mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 18:06:12 +02:00
Merge remote-tracking branch 'origin/plugins-beta-test' into develop
This commit is contained in:
commit
35f4a07d27
24 changed files with 189 additions and 57 deletions
|
@ -908,10 +908,6 @@
|
||||||
::oapi/format "password"}})
|
::oapi/format "password"}})
|
||||||
|
|
||||||
|
|
||||||
;; FIXME: this should not be here
|
|
||||||
(register! ::plugin-data
|
|
||||||
[:map-of {:gen/max 5} :string :string])
|
|
||||||
|
|
||||||
;; ---- PREDICATES
|
;; ---- PREDICATES
|
||||||
|
|
||||||
(def valid-safe-number?
|
(def valid-safe-number?
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
[app.common.types.color.generic :as-alias color-generic]
|
[app.common.types.color.generic :as-alias color-generic]
|
||||||
[app.common.types.color.gradient :as-alias color-gradient]
|
[app.common.types.color.gradient :as-alias color-gradient]
|
||||||
[app.common.types.color.gradient.stop :as-alias color-gradient-stop]
|
[app.common.types.color.gradient.stop :as-alias color-gradient-stop]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.test.check.generators :as tgen]
|
[clojure.test.check.generators :as tgen]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
@ -88,7 +89,7 @@
|
||||||
[:gradient {:optional true} [:maybe ::gradient]]
|
[:gradient {:optional true} [:maybe ::gradient]]
|
||||||
[:image {:optional true} [:maybe ::image-color]]
|
[:image {:optional true} [:maybe ::image-color]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]]
|
||||||
[::sm/contains-any {:strict true} [:color :gradient :image]]])
|
[::sm/contains-any {:strict true} [:color :gradient :image]]])
|
||||||
|
|
||||||
(sm/register! ::recent-color
|
(sm/register! ::recent-color
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[app.common.types.component :as ctk]
|
[app.common.types.component :as ctk]
|
||||||
[app.common.types.components-list :as ctkl]
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
@ -37,7 +38,7 @@
|
||||||
[:objects {:optional true}
|
[:objects {:optional true}
|
||||||
[:map-of {:gen/max 10} ::sm/uuid :map]]
|
[:map-of {:gen/max 10} ::sm/uuid :map]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]])
|
||||||
|
|
||||||
(def check-container!
|
(def check-container!
|
||||||
(sm/check-fn ::container))
|
(sm/check-fn ::container))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.page :as ctp]
|
[app.common.types.page :as ctp]
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.typographies-list :as ctyl]
|
[app.common.types.typographies-list :as ctyl]
|
||||||
[app.common.types.typography :as cty]
|
[app.common.types.typography :as cty]
|
||||||
|
@ -59,7 +60,7 @@
|
||||||
[:media {:optional true}
|
[:media {:optional true}
|
||||||
[:map-of {:gen/max 5} ::sm/uuid ::media-object]]
|
[:map-of {:gen/max 5} ::sm/uuid ::media-object]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]])
|
||||||
|
|
||||||
(def check-file-data!
|
(def check-file-data!
|
||||||
(sm/check-fn ::data))
|
(sm/check-fn ::data))
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.types.color :as-alias ctc]
|
[app.common.types.color :as-alias ctc]
|
||||||
[app.common.types.grid :as ctg]
|
[app.common.types.grid :as ctg]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@
|
||||||
[:guides {:optional true}
|
[:guides {:optional true}
|
||||||
[:map-of {:gen/max 2} ::sm/uuid ::guide]]
|
[:map-of {:gen/max 2} ::sm/uuid ::guide]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]]])
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]]]])
|
||||||
|
|
||||||
(def check-page-guide!
|
(def check-page-guide!
|
||||||
(sm/check-fn ::guide))
|
(sm/check-fn ::guide))
|
||||||
|
|
16
common/src/app/common/types/plugins.cljc
Normal file
16
common/src/app/common/types/plugins.cljc
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.types.plugins
|
||||||
|
(:require
|
||||||
|
[app.common.schema :as sm]))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; SCHEMAS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(sm/register! ::plugin-data
|
||||||
|
[:map-of {:gen/max 5} :string :string])
|
|
@ -20,6 +20,7 @@
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.types.color :as ctc]
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.grid :as ctg]
|
[app.common.types.grid :as ctg]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.types.shape.attrs :refer [default-color]]
|
[app.common.types.shape.attrs :refer [default-color]]
|
||||||
[app.common.types.shape.blur :as ctsb]
|
[app.common.types.shape.blur :as ctsb]
|
||||||
[app.common.types.shape.export :as ctse]
|
[app.common.types.shape.export :as ctse]
|
||||||
|
@ -188,7 +189,7 @@
|
||||||
[:grow-type {:optional true}
|
[:grow-type {:optional true}
|
||||||
[::sm/one-of #{:auto-width :auto-height :fixed}]]
|
[::sm/one-of #{:auto-width :auto-height :fixed}]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]])
|
||||||
|
|
||||||
(sm/register! ::group-attrs
|
(sm/register! ::group-attrs
|
||||||
[:map {:title "GroupAttrs"}
|
[:map {:title "GroupAttrs"}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
[:modified-at {:optional true} ::sm/inst]
|
[:modified-at {:optional true} ::sm/inst]
|
||||||
[:path {:optional true} [:maybe :string]]
|
[:path {:optional true} [:maybe :string]]
|
||||||
[:plugin-data {:optional true}
|
[:plugin-data {:optional true}
|
||||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
[:map-of {:gen/max 5} :keyword ::ctpg/plugin-data]]])
|
||||||
|
|
||||||
(def check-typography!
|
(def check-typography!
|
||||||
(sm/check-fn ::typography))
|
(sm/check-fn ::typography))
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5"><path d="M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||||
|
|
Before Width: | Height: | Size: 1,021 B After Width: | Height: | Size: 1,023 B |
|
@ -7776,6 +7776,9 @@ function Ml(t, e) {
|
||||||
get selection() {
|
get selection() {
|
||||||
return o("content:read"), t.selection;
|
return o("content:read"), t.selection;
|
||||||
},
|
},
|
||||||
|
set selection(i) {
|
||||||
|
o("content:read"), t.selection = i;
|
||||||
|
},
|
||||||
get viewport() {
|
get viewport() {
|
||||||
return t.viewport;
|
return t.viewport;
|
||||||
},
|
},
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
(def privacy-policy-uri (obj/get global "penpotPrivacyPolicyURI" "https://penpot.app/privacy"))
|
(def privacy-policy-uri (obj/get global "penpotPrivacyPolicyURI" "https://penpot.app/privacy"))
|
||||||
(def flex-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/"))
|
(def flex-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/"))
|
||||||
(def grid-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/"))
|
(def grid-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/"))
|
||||||
(def plugins-list-uri (obj/get global "penpotPluginsListUri" "https://penpot-docs-plugins.netlify.app/technical-guide/plugins/getting-started/#examples"))
|
(def plugins-list-uri (obj/get global "penpotPluginsListUri" "https://penpot-docs-plugins.pages.dev/technical-guide/plugins/getting-started/#examples"))
|
||||||
|
|
||||||
(defn- normalize-uri
|
(defn- normalize-uri
|
||||||
[uri-str]
|
[uri-str]
|
||||||
|
|
|
@ -467,4 +467,5 @@
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(->> (svg->clj [name svg-string])
|
(->> (svg->clj [name svg-string])
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/map #(svg/add-svg-shapes id % position {:change-selection? false}))))))
|
(rx/map #(svg/add-svg-shapes id % position {:ignore-selection? true
|
||||||
|
:change-selection? false}))))))
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.hooks.resize :as r]
|
[app.main.ui.hooks.resize :as r]
|
||||||
[app.util.dom :as dom]))
|
[app.util.dom :as dom]
|
||||||
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Shortcuts
|
;; Shortcuts
|
||||||
|
@ -563,7 +564,9 @@
|
||||||
:command (ds/c-mod "alt+p")
|
:command (ds/c-mod "alt+p")
|
||||||
:subsections [:basics]
|
:subsections [:basics]
|
||||||
:fn #(when (features/active-feature? @st/state "plugins/runtime")
|
:fn #(when (features/active-feature? @st/state "plugins/runtime")
|
||||||
(st/emit! (modal/show :plugin-management {})))}})
|
(st/emit!
|
||||||
|
(ptk/event ::ev/event {::ev/name "open-plugins-manager" ::ev/origin "workspace:shortcuts"})
|
||||||
|
(modal/show :plugin-management {})))}})
|
||||||
|
|
||||||
(def debug-shortcuts
|
(def debug-shortcuts
|
||||||
;; PREVIEW
|
;; PREVIEW
|
||||||
|
|
|
@ -64,7 +64,8 @@
|
||||||
([svg-data position]
|
([svg-data position]
|
||||||
(add-svg-shapes nil svg-data position nil))
|
(add-svg-shapes nil svg-data position nil))
|
||||||
|
|
||||||
([id svg-data position {:keys [change-selection?] :or {change-selection? false}}]
|
([id svg-data position {:keys [change-selection? ignore-selection?]
|
||||||
|
:or {ignore-selection? false change-selection? true}}]
|
||||||
(ptk/reify ::add-svg-shapes
|
(ptk/reify ::add-svg-shapes
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
|
@ -73,7 +74,7 @@
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (wsh/lookup-page-objects state page-id)
|
||||||
frame-id (ctst/top-nested-frame objects position)
|
frame-id (ctst/top-nested-frame objects position)
|
||||||
selected (wsh/lookup-selected state)
|
selected (if ignore-selection? #{} (wsh/lookup-selected state))
|
||||||
base (cfh/get-base-shape objects selected)
|
base (cfh/get-base-shape objects selected)
|
||||||
|
|
||||||
selected-id (first selected)
|
selected-id (first selected)
|
||||||
|
|
|
@ -630,13 +630,23 @@
|
||||||
(when (d/not-empty? plugins)
|
(when (d/not-empty? plugins)
|
||||||
[:div {:class (stl/css :separator)}])
|
[:div {:class (stl/css :separator)}])
|
||||||
|
|
||||||
(for [[idx {:keys [name] :as manifest}] (d/enumerate plugins)]
|
(for [[idx {:keys [name host] :as manifest}] (d/enumerate plugins)]
|
||||||
[:> dropdown-menu-item* {:key (dm/str "plugins-menu-" idx)
|
[:> dropdown-menu-item* {:key (dm/str "plugins-menu-" idx)
|
||||||
:on-click #(uwp/open-plugin! manifest)
|
:on-click #(do
|
||||||
|
(st/emit! (ptk/event ::ev/event {::ev/name "start-plugin"
|
||||||
|
::ev/origin "workspace:menu"
|
||||||
|
:name name
|
||||||
|
:host host}))
|
||||||
|
(uwp/open-plugin! manifest))
|
||||||
:class (stl/css :submenu-item)
|
:class (stl/css :submenu-item)
|
||||||
:on-key-down (fn [event]
|
:on-key-down (fn [event]
|
||||||
(when (kbd/enter? event)
|
(when (kbd/enter? event)
|
||||||
#(uwp/open-plugin! manifest)))}
|
#(do
|
||||||
|
(st/emit! (ptk/event ::ev/event {::ev/name "start-plugin"
|
||||||
|
::ev/origin "workspace:menu"
|
||||||
|
:name name
|
||||||
|
:host host}))
|
||||||
|
(uwp/open-plugin! manifest))))}
|
||||||
[:span {:class (stl/css :item-name)} name]])])))
|
[:span {:class (stl/css :item-name)} name]])])))
|
||||||
|
|
||||||
(mf/defc menu
|
(mf/defc menu
|
||||||
|
@ -699,7 +709,9 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(reset! show-menu* false)
|
(reset! show-menu* false)
|
||||||
(reset! sub-menu* nil)
|
(reset! sub-menu* nil)
|
||||||
(st/emit! (modal/show :plugin-management {}))))]
|
(st/emit!
|
||||||
|
(ptk/event ::ev/event {::ev/name "open-plugins-manager" ::ev/origin "workspace:menu"})
|
||||||
|
(modal/show :plugin-management {}))))]
|
||||||
|
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
|
[app.main.data.events :as ev]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.search-bar :refer [search-bar]]
|
[app.main.ui.components.search-bar :refer [search-bar]]
|
||||||
|
@ -21,6 +22,8 @@
|
||||||
[app.util.http :as http]
|
[app.util.http :as http]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def ^:private close-icon
|
(def ^:private close-icon
|
||||||
|
@ -111,6 +114,7 @@
|
||||||
(rx/subs!
|
(rx/subs!
|
||||||
(fn [body]
|
(fn [body]
|
||||||
(let [plugin (plugins/parser-manifest plugin-url body)]
|
(let [plugin (plugins/parser-manifest plugin-url body)]
|
||||||
|
(st/emit! (ptk/event ::ev/event {::ev/name "install-plugin" :name (:name plugin) :url plugin-url}))
|
||||||
(modal/show!
|
(modal/show!
|
||||||
:plugin-permissions
|
:plugin-permissions
|
||||||
{:plugin plugin
|
{:plugin plugin
|
||||||
|
@ -126,6 +130,10 @@
|
||||||
handle-open-plugin
|
handle-open-plugin
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [manifest]
|
(fn [manifest]
|
||||||
|
(st/emit! (ptk/event ::ev/event {::ev/name "start-plugin"
|
||||||
|
::ev/origin "workspace:plugins"
|
||||||
|
:name (:name manifest)
|
||||||
|
:host (:host manifest)}))
|
||||||
(open-plugin! manifest)
|
(open-plugin! manifest)
|
||||||
(modal/hide!)))
|
(modal/hide!)))
|
||||||
|
|
||||||
|
@ -134,6 +142,9 @@
|
||||||
(mf/deps plugins-state)
|
(mf/deps plugins-state)
|
||||||
(fn [plugin-index]
|
(fn [plugin-index]
|
||||||
(let [plugin (nth @plugins/pluginsdb plugin-index)]
|
(let [plugin (nth @plugins/pluginsdb plugin-index)]
|
||||||
|
(st/emit! (ptk/event ::ev/event {::ev/name "remove-plugin"
|
||||||
|
:name (:name plugin)
|
||||||
|
:host (:host plugin)}))
|
||||||
(plugins/remove-plugin! plugin)
|
(plugins/remove-plugin! plugin)
|
||||||
(reset! plugins-state* @plugins/pluginsdb))))]
|
(reset! plugins-state* @plugins/pluginsdb))))]
|
||||||
|
|
||||||
|
@ -162,7 +173,10 @@
|
||||||
[:div {:class (stl/css :plugins-empty)}
|
[:div {:class (stl/css :plugins-empty)}
|
||||||
[:div {:class (stl/css :plugins-empty-logo)} i/puzzle]
|
[:div {:class (stl/css :plugins-empty-logo)} i/puzzle]
|
||||||
[:div {:class (stl/css :plugins-empty-text)} (tr "workspace.plugins.empty-plugins")]
|
[:div {:class (stl/css :plugins-empty-text)} (tr "workspace.plugins.empty-plugins")]
|
||||||
[:a {:class (stl/css :plugins-link) :href cf/plugins-list-uri :target "_blank"}
|
[:a {:class (stl/css :plugins-link)
|
||||||
|
:href cf/plugins-list-uri
|
||||||
|
:target "_blank"
|
||||||
|
:on-click #(st/emit! (ptk/event ::ev/event {::ev/name "open-plugins-list"}))}
|
||||||
(tr "workspace.plugins.plugin-list-link") i/external-link]]
|
(tr "workspace.plugins.plugin-list-link") i/external-link]]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
|
@ -182,7 +196,7 @@
|
||||||
::mf/register-as :plugin-permissions}
|
::mf/register-as :plugin-permissions}
|
||||||
[{:keys [plugin on-accept]}]
|
[{:keys [plugin on-accept]}]
|
||||||
|
|
||||||
(let [{:keys [permissions]} plugin
|
(let [{:keys [host permissions]} plugin
|
||||||
permissions (set permissions)
|
permissions (set permissions)
|
||||||
|
|
||||||
handle-accept-dialog
|
handle-accept-dialog
|
||||||
|
@ -190,12 +204,18 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(st/emit! (modal/hide))
|
(st/emit! (modal/hide))
|
||||||
|
(ptk/event ::ev/event {::ev/name "allow-plugin-permissions"
|
||||||
|
:host host
|
||||||
|
:permissions (->> permissions (str/join ", "))})
|
||||||
(on-accept)))
|
(on-accept)))
|
||||||
|
|
||||||
handle-close-dialog
|
handle-close-dialog
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
|
(ptk/event ::ev/event {::ev/name "reject-plugin-permissions"
|
||||||
|
:host host
|
||||||
|
:permissions (->> permissions (str/join ", "))})
|
||||||
(st/emit! (modal/hide))))]
|
(st/emit! (modal/hide))))]
|
||||||
|
|
||||||
[:div {:class (stl/css :modal-overlay)}
|
[:div {:class (stl/css :modal-overlay)}
|
||||||
|
@ -205,35 +225,38 @@
|
||||||
|
|
||||||
[:div {:class (stl/css :modal-content)}
|
[:div {:class (stl/css :modal-content)}
|
||||||
[:div {:class (stl/css :permissions-list)}
|
[:div {:class (stl/css :permissions-list)}
|
||||||
(when (contains? permissions "content:read")
|
(cond
|
||||||
|
(contains? permissions "content:write")
|
||||||
|
[:div {:class (stl/css :permissions-list-entry)}
|
||||||
|
i/oauth-1
|
||||||
|
[:p {:class (stl/css :permissions-list-text)}
|
||||||
|
(tr "workspace.plugins.permissions.content-write")]]
|
||||||
|
|
||||||
|
(contains? permissions "content:read")
|
||||||
[:div {:class (stl/css :permissions-list-entry)}
|
[:div {:class (stl/css :permissions-list-entry)}
|
||||||
i/oauth-1
|
i/oauth-1
|
||||||
[:p {:class (stl/css :permissions-list-text)}
|
[:p {:class (stl/css :permissions-list-text)}
|
||||||
(tr "workspace.plugins.permissions.content-read")]])
|
(tr "workspace.plugins.permissions.content-read")]])
|
||||||
|
|
||||||
(when (contains? permissions "content:write")
|
(cond
|
||||||
[:div {:class (stl/css :permissions-list-entry)}
|
(contains? permissions "user:read")
|
||||||
i/oauth-1
|
|
||||||
[:p {:class (stl/css :permissions-list-text)}
|
|
||||||
(tr "workspace.plugins.permissions.content-write")]])
|
|
||||||
|
|
||||||
(when (contains? permissions "user:read")
|
|
||||||
[:div {:class (stl/css :permissions-list-entry)}
|
[:div {:class (stl/css :permissions-list-entry)}
|
||||||
i/oauth-2
|
i/oauth-2
|
||||||
[:p {:class (stl/css :permissions-list-text)}
|
[:p {:class (stl/css :permissions-list-text)}
|
||||||
(tr "workspace.plugins.permissions.user-read")]])
|
(tr "workspace.plugins.permissions.user-read")]])
|
||||||
|
|
||||||
(when (contains? permissions "library:read")
|
(cond
|
||||||
|
(contains? permissions "library:write")
|
||||||
[:div {:class (stl/css :permissions-list-entry)}
|
[:div {:class (stl/css :permissions-list-entry)}
|
||||||
i/oauth-3
|
i/oauth-3
|
||||||
[:p {:class (stl/css :permissions-list-text)}
|
[:p {:class (stl/css :permissions-list-text)}
|
||||||
(tr "workspace.plugins.permissions.library-read")]])
|
(tr "workspace.plugins.permissions.library-write")]]
|
||||||
|
|
||||||
(when (contains? permissions "library:write")
|
(contains? permissions "library:read")
|
||||||
[:div {:class (stl/css :permissions-list-entry)}
|
[:div {:class (stl/css :permissions-list-entry)}
|
||||||
i/oauth-3
|
i/oauth-3
|
||||||
[:p {:class (stl/css :permissions-list-text)}
|
[:p {:class (stl/css :permissions-list-text)}
|
||||||
(tr "workspace.plugins.permissions.library-write")]])]
|
(tr "workspace.plugins.permissions.library-read")]])]
|
||||||
|
|
||||||
[:div {:class (stl/css :permissions-disclaimer)}
|
[:div {:class (stl/css :permissions-disclaimer)}
|
||||||
(tr "workspace.plugins.permissions.disclaimer")]]
|
(tr "workspace.plugins.permissions.disclaimer")]]
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc image-upload
|
(mf/defc image-upload
|
||||||
|
@ -200,7 +201,9 @@
|
||||||
{:title (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
|
{:title (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
|
||||||
:aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
|
:aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins))
|
||||||
:class (stl/css :main-toolbar-options-button)
|
:class (stl/css :main-toolbar-options-button)
|
||||||
:on-click #(modal/show! :plugin-management {})
|
:on-click #(st/emit!
|
||||||
|
(ptk/event ::ev/event {::ev/name "open-plugins-manager" ::ev/origin "workspace:toolbar"})
|
||||||
|
(modal/show :plugin-management {}))
|
||||||
:data-tool "plugins"
|
:data-tool "plugins"
|
||||||
:data-testid "plugins-btn"}
|
:data-testid "plugins-btn"}
|
||||||
i/puzzle]])
|
i/puzzle]])
|
||||||
|
|
|
@ -47,7 +47,16 @@
|
||||||
desc (obj/get manifest "description")
|
desc (obj/get manifest "description")
|
||||||
code (obj/get manifest "code")
|
code (obj/get manifest "code")
|
||||||
icon (obj/get manifest "icon")
|
icon (obj/get manifest "icon")
|
||||||
permissions (obj/get manifest "permissions")
|
|
||||||
|
permissions (into #{} (obj/get manifest "permissions" []))
|
||||||
|
permissions
|
||||||
|
(cond-> permissions
|
||||||
|
(contains? permissions "content:write")
|
||||||
|
(conj "content:read")
|
||||||
|
|
||||||
|
(contains? permissions "library:write")
|
||||||
|
(conj "content:write"))
|
||||||
|
|
||||||
origin (obj/get (js/URL. plugin-url) "origin")
|
origin (obj/get (js/URL. plugin-url) "origin")
|
||||||
plugin-id (str (uuid/next))]
|
plugin-id (str (uuid/next))]
|
||||||
{:plugin-id plugin-id
|
{:plugin-id plugin-id
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
[app.main.data.workspace.colors :as dwc]
|
[app.main.data.workspace.colors :as dwc]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.main.data.workspace.media :as dwm]
|
[app.main.data.workspace.media :as dwm]
|
||||||
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.events :as events]
|
[app.plugins.events :as events]
|
||||||
[app.plugins.file :as file]
|
[app.plugins.file :as file]
|
||||||
|
@ -356,7 +357,19 @@
|
||||||
{:name "root" :get #(.getRoot ^js %)}
|
{:name "root" :get #(.getRoot ^js %)}
|
||||||
{:name "currentFile" :get #(.getFile ^js %)}
|
{:name "currentFile" :get #(.getFile ^js %)}
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
|
||||||
|
{:name "selection"
|
||||||
|
:get #(.getSelectedShapes ^js %)
|
||||||
|
:set
|
||||||
|
(fn [_ shapes]
|
||||||
|
(cond
|
||||||
|
(or (not (array? shapes)) (not (every? shape/shape-proxy? shapes)))
|
||||||
|
(u/display-not-valid :selection shapes)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [ids (into (d/ordered-set) (map #(obj/get % "$id")) shapes)]
|
||||||
|
(st/emit! (dws/select-shapes ids)))))}
|
||||||
|
|
||||||
{:name "viewport" :get #(.getViewport ^js %)}
|
{:name "viewport" :get #(.getViewport ^js %)}
|
||||||
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
||||||
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
||||||
|
|
|
@ -229,8 +229,8 @@
|
||||||
(when (some? export)
|
(when (some? export)
|
||||||
(d/without-nils
|
(d/without-nils
|
||||||
{:type (-> (obj/get export "type") parse-keyword)
|
{:type (-> (obj/get export "type") parse-keyword)
|
||||||
:scale (obj/get export "scale")
|
:scale (obj/get export "scale" 1)
|
||||||
:suffix (obj/get export "suffix")})))
|
:suffix (obj/get export "suffix" "")})))
|
||||||
|
|
||||||
(defn parse-exports
|
(defn parse-exports
|
||||||
[^js exports]
|
[^js exports]
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.flex :as flex]
|
[app.plugins.flex :as flex]
|
||||||
[app.plugins.format :as format]
|
[app.plugins.format :as format]
|
||||||
|
@ -46,7 +47,9 @@
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.path.format :as upf]
|
[app.util.path.format :as upf]
|
||||||
[cuerdas.core :as str]))
|
[beicon.v2.core :as rx]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(def lib-typography-proxy? nil)
|
(def lib-typography-proxy? nil)
|
||||||
(def lib-component-proxy nil)
|
(def lib-component-proxy nil)
|
||||||
|
@ -436,7 +439,34 @@
|
||||||
shape (u/proxy->shape self)]
|
shape (u/proxy->shape self)]
|
||||||
(when (ctn/in-any-component? objects shape)
|
(when (ctn/in-any-component? objects shape)
|
||||||
(let [[root component] (u/locate-component objects shape)]
|
(let [[root component] (u/locate-component objects shape)]
|
||||||
(lib-component-proxy $plugin (:component-file root) (:id component)))))))
|
(lib-component-proxy $plugin (:component-file root) (:id component))))))
|
||||||
|
|
||||||
|
(export
|
||||||
|
[self value]
|
||||||
|
(let [value (parser/parse-export value)]
|
||||||
|
(cond
|
||||||
|
(not (sm/validate ::ctse/export value))
|
||||||
|
(u/display-not-valid :export value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [payload
|
||||||
|
{:cmd :export-shapes
|
||||||
|
:profile-id (:profile-id @st/state)
|
||||||
|
:wait true
|
||||||
|
:exports [{:file-id $file
|
||||||
|
:page-id $page
|
||||||
|
:object-id $id
|
||||||
|
:name (obj/get self "name")
|
||||||
|
:type (:type value :png)
|
||||||
|
:suffix (:suffix value "")
|
||||||
|
:scale (:scale value 1)}]}]
|
||||||
|
(p/create
|
||||||
|
(fn [resolve reject]
|
||||||
|
(->> (rp/cmd! :export payload)
|
||||||
|
(rx/mapcat #(rp/cmd! :export {:cmd :get-resource :wait true :id (:id %) :blob? true}))
|
||||||
|
(rx/mapcat #(.arrayBuffer %))
|
||||||
|
(rx/map #(js/Uint8Array. %))
|
||||||
|
(rx/subs! resolve reject)))))))))
|
||||||
|
|
||||||
(defn shape-proxy? [p]
|
(defn shape-proxy? [p]
|
||||||
(instance? ShapeProxy p))
|
(instance? ShapeProxy p))
|
||||||
|
@ -886,6 +916,12 @@
|
||||||
{:name "height"
|
{:name "height"
|
||||||
:get #(-> % u/proxy->shape :height)}
|
:get #(-> % u/proxy->shape :height)}
|
||||||
|
|
||||||
|
{:name "bounds"
|
||||||
|
:get #(-> % u/proxy->shape :points grc/points->rect format/format-bounds)}
|
||||||
|
|
||||||
|
{:name "center"
|
||||||
|
:get #(-> % u/proxy->shape gsh/shape->center format/format-point)}
|
||||||
|
|
||||||
{:name "rotation"
|
{:name "rotation"
|
||||||
:get #(-> % u/proxy->shape :rotation)
|
:get #(-> % u/proxy->shape :rotation)
|
||||||
:set
|
:set
|
||||||
|
|
|
@ -39,10 +39,14 @@
|
||||||
store))
|
store))
|
||||||
|
|
||||||
(defn run-store
|
(defn run-store
|
||||||
[store done events completed-cb]
|
([store done events completed-cb]
|
||||||
|
(run-store store done events completed-cb nil))
|
||||||
|
([store done events completed-cb stopper]
|
||||||
(let [stream (ptk/input-stream store)]
|
(let [stream (ptk/input-stream store)]
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/take-until (rx/filter #(= :the/end %) stream))
|
(rx/take-until (if stopper
|
||||||
|
(stopper stream)
|
||||||
|
(rx/filter #(= :the/end %) stream)))
|
||||||
(rx/last)
|
(rx/last)
|
||||||
(rx/tap (fn []
|
(rx/tap (fn []
|
||||||
(completed-cb @store)))
|
(completed-cb @store)))
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
(js/console.log "[complete]"))))
|
(js/console.log "[complete]"))))
|
||||||
(doall (for [event events]
|
(doall (for [event events]
|
||||||
(ptk/emit! store event)))
|
(ptk/emit! store event)))
|
||||||
(ptk/emit! store :the/end)))
|
(ptk/emit! store :the/end))))
|
||||||
|
|
||||||
(defn get-file-from-store
|
(defn get-file-from-store
|
||||||
[store]
|
[store]
|
||||||
|
|
|
@ -5281,6 +5281,9 @@ msgstr "Plugin correctly loaded."
|
||||||
msgid "workspace.plugins.menu.title"
|
msgid "workspace.plugins.menu.title"
|
||||||
msgstr "Plugins"
|
msgstr "Plugins"
|
||||||
|
|
||||||
|
msgid "workspace.toolbar.plugins"
|
||||||
|
msgstr "Plugins"
|
||||||
|
|
||||||
msgid "workspace.plugins.menu.plugins-manager"
|
msgid "workspace.plugins.menu.plugins-manager"
|
||||||
msgstr "Plugins manager"
|
msgstr "Plugins manager"
|
||||||
|
|
||||||
|
|
|
@ -5361,6 +5361,9 @@ msgstr "Pulsar para cerrar la ruta"
|
||||||
msgid "workspace.plugins.title"
|
msgid "workspace.plugins.title"
|
||||||
msgstr "Extensiones"
|
msgstr "Extensiones"
|
||||||
|
|
||||||
|
msgid "workspace.toolbar.plugins"
|
||||||
|
msgstr "Extensiones"
|
||||||
|
|
||||||
msgid "workspace.plugins.search-placeholder"
|
msgid "workspace.plugins.search-placeholder"
|
||||||
msgstr "Intruduzca URL de la extensión"
|
msgstr "Intruduzca URL de la extensión"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue