mirror of
https://github.com/penpot/penpot.git
synced 2025-05-23 10:06:12 +02:00
✨ Add support for plugin data into penpot objects
This commit is contained in:
parent
4d4a3a512d
commit
5233654da2
22 changed files with 764 additions and 138 deletions
|
@ -133,6 +133,18 @@
|
|||
[:id ::sm/uuid]
|
||||
[:name :string]]]
|
||||
|
||||
[:mod-plugin-data
|
||||
[:map {:title "ModPagePluginData"}
|
||||
[:type [:= :mod-plugin-data]]
|
||||
[:object-type [::sm/one-of #{:file :page :shape :color :typography :component}]]
|
||||
;; It's optional because files don't need the id for type :file
|
||||
[:object-id {:optional true} [:maybe ::sm/uuid]]
|
||||
;; Only needed in type shape
|
||||
[:page-id {:optional true} [:maybe ::sm/uuid]]
|
||||
[:namespace :keyword]
|
||||
[:key :string]
|
||||
[:value [:maybe :string]]]]
|
||||
|
||||
[:del-page
|
||||
[:map {:title "DelPageChange"}
|
||||
[:type [:= :del-page]]
|
||||
|
@ -586,6 +598,36 @@
|
|||
[data {:keys [id name]}]
|
||||
(d/update-in-when data [:pages-index id] assoc :name name))
|
||||
|
||||
(defmethod process-change :mod-plugin-data
|
||||
[data {:keys [object-type object-id page-id namespace key value]}]
|
||||
|
||||
(when (and (= object-type :shape) (nil? page-id))
|
||||
(ex/raise :type :internal :hint "update for shapes needs a page-id"))
|
||||
|
||||
(letfn [(update-fn
|
||||
[data]
|
||||
(if (some? value)
|
||||
(assoc-in data [:plugin-data namespace key] value)
|
||||
(update-in data [:plugin-data namespace] (fnil dissoc {}) key)))]
|
||||
(case object-type
|
||||
:file
|
||||
(update-fn data)
|
||||
|
||||
:page
|
||||
(d/update-in-when data [:pages-index object-id :options] update-fn)
|
||||
|
||||
:shape
|
||||
(d/update-in-when data [:pages-index page-id :objects object-id] update-fn)
|
||||
|
||||
:color
|
||||
(d/update-in-when data [:colors object-id] update-fn)
|
||||
|
||||
:typography
|
||||
(d/update-in-when data [:typographies object-id] update-fn)
|
||||
|
||||
:component
|
||||
(d/update-in-when data [:components object-id] update-fn))))
|
||||
|
||||
(defmethod process-change :del-page
|
||||
[data {:keys [id]}]
|
||||
(ctpl/delete-page data id))
|
||||
|
|
|
@ -201,6 +201,37 @@
|
|||
(update :undo-changes conj {:type :mod-page :id (:id page) :name (:name page)})
|
||||
(apply-changes-local)))
|
||||
|
||||
(defn mod-plugin-data
|
||||
([changes namespace key value]
|
||||
(mod-plugin-data changes :file nil nil namespace key value))
|
||||
([changes type id namespace key value]
|
||||
(mod-plugin-data changes type id nil namespace key value))
|
||||
([changes type id page-id namespace key value]
|
||||
(let [data (::file-data (meta changes))
|
||||
old-val
|
||||
(case type
|
||||
:file
|
||||
(get-in data [:plugin-data namespace key])
|
||||
|
||||
:page
|
||||
(get-in data [:pages-index id :options :plugin-data namespace key])
|
||||
|
||||
:shape
|
||||
(get-in data [:pages-index page-id :objects id :plugin-data namespace key])
|
||||
|
||||
:color
|
||||
(get-in data [:colors id :plugin-data namespace key])
|
||||
|
||||
:typography
|
||||
(get-in data [:typographies id :plugin-data namespace key])
|
||||
|
||||
:component
|
||||
(get-in data [:components id :plugin-data namespace key]))]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value value})
|
||||
(update :undo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value old-val})
|
||||
(apply-changes-local)))))
|
||||
|
||||
(defn del-page
|
||||
[changes page]
|
||||
(-> changes
|
||||
|
|
|
@ -658,6 +658,9 @@
|
|||
::oapi/format "uri"
|
||||
::oapi/decode (comp u/uri str/trim)}})
|
||||
|
||||
(def! ::plugin-data
|
||||
[:map-of {:gen/max 5} :string :string])
|
||||
|
||||
;; ---- PREDICATES
|
||||
|
||||
(def valid-safe-number?
|
||||
|
|
|
@ -84,7 +84,9 @@
|
|||
[:ref-id {:optional true} ::sm/uuid]
|
||||
[:ref-file {:optional true} ::sm/uuid]
|
||||
[:gradient {:optional true} [:maybe ::gradient]]
|
||||
[:image {:optional true} [:maybe ::image-color]]]
|
||||
[:image {:optional true} [:maybe ::image-color]]
|
||||
[:plugin-data {:optional true}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]
|
||||
[::sm/contains-any {:strict true} [:color :gradient :image]]])
|
||||
|
||||
(sm/define! ::recent-color
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
[:path {:optional true} [:maybe :string]]
|
||||
[:modified-at {:optional true} ::sm/inst]
|
||||
[:objects {:optional true}
|
||||
[:map-of {:gen/max 10} ::sm/uuid :map]]])
|
||||
[:map-of {:gen/max 10} ::sm/uuid :map]]
|
||||
[:plugin-data {:optional true}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||
|
||||
(def check-container!
|
||||
(sm/check-fn ::container))
|
||||
|
|
|
@ -57,7 +57,9 @@
|
|||
[:typographies {:optional true}
|
||||
[:map-of {:gen/max 2} ::sm/uuid ::cty/typography]]
|
||||
[: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}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||
|
||||
(def check-file-data!
|
||||
(sm/check-fn ::data))
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
[:flows {:optional true}
|
||||
[:vector {:gen/max 2} ::flow]]
|
||||
[:guides {:optional true}
|
||||
[:map-of {:gen/max 2} ::sm/uuid ::guide]]]]])
|
||||
[:map-of {:gen/max 2} ::sm/uuid ::guide]]
|
||||
[:plugin-data {:optional true}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]]])
|
||||
|
||||
(def check-page-guide!
|
||||
(sm/check-fn ::guide))
|
||||
|
|
|
@ -186,7 +186,9 @@
|
|||
[:vector {:gen/max 1} ::ctss/shadow]]
|
||||
[:blur {:optional true} ::ctsb/blur]
|
||||
[:grow-type {:optional true}
|
||||
[::sm/one-of #{:auto-width :auto-height :fixed}]]])
|
||||
[::sm/one-of #{:auto-width :auto-height :fixed}]]
|
||||
[:plugin-data {:optional true}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||
|
||||
(sm/define! ::group-attrs
|
||||
[:map {:title "GroupAttrs"}
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
[:letter-spacing :string]
|
||||
[:text-transform :string]
|
||||
[:modified-at {:optional true} ::sm/inst]
|
||||
[:path {:optional true} [:maybe :string]]])
|
||||
[:path {:optional true} [:maybe :string]]
|
||||
[:plugin-data {:optional true}
|
||||
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||
|
||||
(def check-typography!
|
||||
(sm/check-fn ::typography))
|
||||
|
|
|
@ -568,6 +568,35 @@
|
|||
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
(defn set-plugin-data
|
||||
([file-id type namespace key value]
|
||||
(set-plugin-data file-id type nil nil namespace key value))
|
||||
([file-id type id namespace key value]
|
||||
(set-plugin-data file-id type id nil namespace key value))
|
||||
([file-id type id page-id namespace key value]
|
||||
(dm/assert! (contains? #{:file :page :shape :color :typography :component} type))
|
||||
(dm/assert! (or (nil? id) (uuid? id)))
|
||||
(dm/assert! (or (nil? page-id) (uuid? page-id)))
|
||||
(dm/assert! (uuid? file-id))
|
||||
(dm/assert! (keyword? namespace))
|
||||
(dm/assert! (string? key))
|
||||
(dm/assert! (or (nil? value) (string? value)))
|
||||
|
||||
(ptk/reify ::set-file-plugin-data
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [file-data
|
||||
(if (= file-id (:current-file-id state))
|
||||
(:workspace-data state)
|
||||
(get-in state [:workspace-libraries file-id :data]))
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it)
|
||||
(pcb/with-file-data file-data)
|
||||
(assoc :file-id file-id)
|
||||
(pcb/mod-plugin-data type id page-id namespace key value))]
|
||||
(rx/of (dch/commit-changes changes)))))))
|
||||
|
||||
(declare purge-page)
|
||||
(declare go-to-file)
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@
|
|||
(defn open-plugin!
|
||||
[{:keys [plugin-id name description host code icon permissions]}]
|
||||
(.ɵloadPlugin
|
||||
js/window #js
|
||||
{:pluginId plugin-id
|
||||
js/window
|
||||
#js {:pluginId plugin-id
|
||||
:name name
|
||||
:description description
|
||||
:host host
|
||||
|
|
|
@ -26,5 +26,4 @@
|
|||
(fn []
|
||||
(when (features/active-feature? @st/state "plugins/runtime")
|
||||
(when-let [init-runtime (obj/get global "initPluginsRuntime")]
|
||||
(let [context (api/create-context)]
|
||||
(init-runtime context))))))))
|
||||
(init-runtime (fn [plugin-id] (api/create-context plugin-id)))))))))
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
||||
;;
|
||||
(defn create-shape
|
||||
[type]
|
||||
[plugin-id type]
|
||||
(let [page-id (:current-page-id @st/state)
|
||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
||||
shape (cts/setup-shape {:type type
|
||||
|
@ -46,13 +46,13 @@
|
|||
(cb/with-objects (:objects page))
|
||||
(cb/add-object shape))]
|
||||
(st/emit! (ch/commit-changes changes))
|
||||
(shape/shape-proxy (:id shape))))
|
||||
(shape/shape-proxy plugin-id (:id shape))))
|
||||
|
||||
(deftype PenpotContext []
|
||||
(deftype PenpotContext [$plugin]
|
||||
Object
|
||||
(addListener
|
||||
[_ type callback]
|
||||
(events/add-listener type callback))
|
||||
(events/add-listener type $plugin callback))
|
||||
|
||||
(removeListener
|
||||
[_ listener-id]
|
||||
|
@ -60,17 +60,17 @@
|
|||
|
||||
(getViewport
|
||||
[_]
|
||||
(viewport/create-proxy))
|
||||
(viewport/create-proxy $plugin))
|
||||
|
||||
(getFile
|
||||
[_]
|
||||
(file/file-proxy (:current-file-id @st/state)))
|
||||
(file/file-proxy $plugin (:current-file-id @st/state)))
|
||||
|
||||
(getPage
|
||||
[_]
|
||||
(let [file-id (:current-file-id @st/state)
|
||||
page-id (:current-page-id @st/state)]
|
||||
(page/page-proxy file-id page-id)))
|
||||
(page/page-proxy $plugin file-id page-id)))
|
||||
|
||||
(getSelected
|
||||
[_]
|
||||
|
@ -80,11 +80,11 @@
|
|||
(getSelectedShapes
|
||||
[_]
|
||||
(let [selection (get-in @st/state [:workspace-local :selected])]
|
||||
(apply array (sequence (map shape/shape-proxy) selection))))
|
||||
(apply array (sequence (map (partial shape/shape-proxy $plugin)) selection))))
|
||||
|
||||
(getRoot
|
||||
[_]
|
||||
(shape/shape-proxy uuid/zero))
|
||||
(shape/shape-proxy $plugin uuid/zero))
|
||||
|
||||
(getTheme
|
||||
[_]
|
||||
|
@ -95,7 +95,7 @@
|
|||
|
||||
(getCurrentUser
|
||||
[_]
|
||||
(user/current-user-proxy (:session-id @st/state)))
|
||||
(user/current-user-proxy $plugin (:session-id @st/state)))
|
||||
|
||||
(getActiveUsers
|
||||
[_]
|
||||
|
@ -103,7 +103,7 @@
|
|||
(->> (:workspace-presence @st/state)
|
||||
(vals)
|
||||
(remove #(= (:id %) (:session-id @st/state)))
|
||||
(map #(user/active-user-proxy (:id %))))))
|
||||
(map #(user/active-user-proxy $plugin (:id %))))))
|
||||
|
||||
(uploadMediaUrl
|
||||
[_ name url]
|
||||
|
@ -122,7 +122,7 @@
|
|||
id (uuid/next)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwg/group-shapes id ids))
|
||||
(shape/shape-proxy file-id page-id id)))
|
||||
(shape/shape-proxy $plugin file-id page-id id)))
|
||||
|
||||
(ungroup
|
||||
[_ group & rest]
|
||||
|
@ -132,15 +132,15 @@
|
|||
|
||||
(createFrame
|
||||
[_]
|
||||
(create-shape :frame))
|
||||
(create-shape $plugin :frame))
|
||||
|
||||
(createRectangle
|
||||
[_]
|
||||
(create-shape :rect))
|
||||
(create-shape $plugin :rect))
|
||||
|
||||
(createEllipse
|
||||
[_]
|
||||
(create-shape :circle))
|
||||
(create-shape $plugin :circle))
|
||||
|
||||
(createPath
|
||||
[_]
|
||||
|
@ -156,7 +156,7 @@
|
|||
(cb/with-objects (:objects page))
|
||||
(cb/add-object shape))]
|
||||
(st/emit! (ch/commit-changes changes))
|
||||
(shape/shape-proxy (:id shape))))
|
||||
(shape/shape-proxy $plugin (:id shape))))
|
||||
|
||||
(createText
|
||||
[_ text]
|
||||
|
@ -172,7 +172,7 @@
|
|||
(cb/with-objects (:objects page))
|
||||
(cb/add-object shape))]
|
||||
(st/emit! (ch/commit-changes changes))
|
||||
(shape/shape-proxy file-id page-id (:id shape))))
|
||||
(shape/shape-proxy $plugin file-id page-id (:id shape))))
|
||||
|
||||
(createShapeFromSvg
|
||||
[_ svg-string]
|
||||
|
@ -181,7 +181,7 @@
|
|||
file-id (:current-file-id @st/state)
|
||||
page-id (:current-page-id @st/state)]
|
||||
(st/emit! (dwm/create-svg-shape id "svg" svg-string (gpt/point 0 0)))
|
||||
(shape/shape-proxy file-id page-id id))))
|
||||
(shape/shape-proxy $plugin file-id page-id id))))
|
||||
|
||||
(createBoolean [_ bool-type shapes]
|
||||
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
|
||||
|
@ -190,14 +190,15 @@
|
|||
(if (contains? cts/bool-types bool-type)
|
||||
(let [id-ret (atom nil)]
|
||||
(st/emit! (dwb/create-bool bool-type ids {:id-ret id-ret}))
|
||||
(shape/shape-proxy @id-ret))
|
||||
(shape/shape-proxy $plugin @id-ret))
|
||||
|
||||
(utils/display-not-valid :bool-shape bool-type)))))
|
||||
|
||||
(defn create-context
|
||||
[]
|
||||
[plugin-id]
|
||||
(cr/add-properties!
|
||||
(PenpotContext.)
|
||||
(PenpotContext. plugin-id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "root" :get #(.getRoot ^js %)}
|
||||
{:name "currentFile" :get #(.getFile ^js %)}
|
||||
{:name "currentPage" :get #(.getPage ^js %)}
|
||||
|
@ -205,4 +206,4 @@
|
|||
{:name "viewport" :get #(.getViewport ^js %)}
|
||||
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
||||
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
||||
{:name "library" :get (fn [_] (library/library-subcontext))}))
|
||||
{:name "library" :get (fn [_] (library/library-subcontext plugin-id))}))
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
(defmulti handle-state-change (fn [type _] type))
|
||||
|
||||
(defmethod handle-state-change "finish"
|
||||
[_ old-val new-val]
|
||||
[_ _ old-val new-val]
|
||||
(let [old-file-id (:current-file-id old-val)
|
||||
new-file-id (:current-file-id new-val)]
|
||||
(if (and (some? old-file-id) (nil? new-file-id))
|
||||
|
@ -23,7 +23,7 @@
|
|||
::not-changed)))
|
||||
|
||||
(defmethod handle-state-change "filechange"
|
||||
[_ old-val new-val]
|
||||
[_ plugin-id old-val new-val]
|
||||
(let [old-file (:workspace-file old-val)
|
||||
new-file (:workspace-file new-val)
|
||||
old-data (:workspace-data old-val)
|
||||
|
@ -31,10 +31,10 @@
|
|||
(if (and (identical? old-file new-file)
|
||||
(identical? old-data new-data))
|
||||
::not-changed
|
||||
(file/file-proxy (:id new-file)))))
|
||||
(file/file-proxy plugin-id (:id new-file)))))
|
||||
|
||||
(defmethod handle-state-change "pagechange"
|
||||
[_ old-val new-val]
|
||||
[_ plugin-id old-val new-val]
|
||||
(let [file-id (:current-file-id new-val)
|
||||
old-page-id (:current-page-id old-val)
|
||||
new-page-id (:current-page-id new-val)
|
||||
|
@ -42,10 +42,10 @@
|
|||
new-page (dm/get-in new-val [:workspace-data :pages-index new-page-id])]
|
||||
(if (identical? old-page new-page)
|
||||
::not-changed
|
||||
(page/page-proxy file-id new-page-id))))
|
||||
(page/page-proxy plugin-id file-id new-page-id))))
|
||||
|
||||
(defmethod handle-state-change "selectionchange"
|
||||
[_ old-val new-val]
|
||||
[_ _ old-val new-val]
|
||||
(let [old-selection (get-in old-val [:workspace-local :selected])
|
||||
new-selection (get-in new-val [:workspace-local :selected])]
|
||||
(if (identical? old-selection new-selection)
|
||||
|
@ -53,7 +53,7 @@
|
|||
(apply array (map str new-selection)))))
|
||||
|
||||
(defmethod handle-state-change "themechange"
|
||||
[_ old-val new-val]
|
||||
[_ _ old-val new-val]
|
||||
(let [old-theme (get-in old-val [:profile :theme])
|
||||
new-theme (get-in new-val [:profile :theme])]
|
||||
(if (identical? old-theme new-theme)
|
||||
|
@ -63,17 +63,17 @@
|
|||
new-theme))))
|
||||
|
||||
(defmethod handle-state-change :default
|
||||
[_ _ _]
|
||||
[_ _ _ _]
|
||||
::not-changed)
|
||||
|
||||
(defn add-listener
|
||||
[type callback]
|
||||
[type plugin-id callback]
|
||||
(let [key (js/Symbol)
|
||||
callback (gf/debounce callback 10)]
|
||||
(add-watch
|
||||
st/state key
|
||||
(fn [_ _ old-val new-val]
|
||||
(let [result (handle-state-change type old-val new-val)]
|
||||
(let [result (handle-state-change type plugin-id old-val new-val)]
|
||||
(when (not= ::not-changed result)
|
||||
(callback result)))))
|
||||
|
||||
|
|
|
@ -9,15 +9,84 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.record :as crc]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.page :as page]
|
||||
[app.plugins.utils :refer [locate-file proxy->file]]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(deftype FileProxy [$id]
|
||||
(deftype FileProxy [$plugin $id]
|
||||
Object
|
||||
(getPages [_]
|
||||
(let [file (locate-file $id)]
|
||||
(apply array (sequence (map #(page/page-proxy $id %)) (dm/get-in file [:data :pages]))))))
|
||||
(let [file (u/locate-file $id)]
|
||||
(apply array (sequence (map #(page/page-proxy $plugin $id %)) (dm/get-in file [:data :pages])))))
|
||||
|
||||
;; Plugin data
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :file-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $id :file (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [file (u/proxy->file self)]
|
||||
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(dm/get-in file [:data :plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :file-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $id :file (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(crc/define-properties!
|
||||
FileProxy
|
||||
|
@ -25,16 +94,17 @@
|
|||
:get (fn [] (str "FileProxy"))})
|
||||
|
||||
(defn file-proxy
|
||||
[id]
|
||||
[plugin-id id]
|
||||
(crc/add-properties!
|
||||
(FileProxy. id)
|
||||
(FileProxy. plugin-id id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
|
||||
{:name "id"
|
||||
:get #(dm/str (obj/get % "$id"))}
|
||||
|
||||
{:name "name"
|
||||
:get #(-> % proxy->file :name)}
|
||||
:get #(-> % u/proxy->file :name)}
|
||||
|
||||
{:name "pages"
|
||||
:get #(.getPages ^js %)}))
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
[app.util.object :as obj]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(deftype FlexLayout [$file $page $id]
|
||||
(deftype FlexLayout [$plugin $file $page $id]
|
||||
Object
|
||||
(remove
|
||||
[_]
|
||||
|
@ -30,9 +30,10 @@
|
|||
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||
|
||||
(defn flex-layout-proxy
|
||||
[file-id page-id id]
|
||||
(-> (FlexLayout. file-id page-id id)
|
||||
[plugin-id file-id page-id id]
|
||||
(-> (FlexLayout. plugin-id file-id page-id id)
|
||||
(crc/add-properties!
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
@ -148,12 +149,13 @@
|
|||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||
|
||||
|
||||
(deftype LayoutChildProxy [$file $page $id])
|
||||
(deftype LayoutChildProxy [$plugin $file $page $id])
|
||||
|
||||
(defn layout-child-proxy
|
||||
[file-id page-id id]
|
||||
(-> (LayoutChildProxy. file-id page-id id)
|
||||
[plugin-id file-id page-id id]
|
||||
(-> (LayoutChildProxy. plugin-id file-id page-id id)
|
||||
(crc/add-properties!
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
js/Object
|
||||
(apply array (->> tracks (map utils/to-js)))))
|
||||
|
||||
(deftype GridLayout [$file $page $id]
|
||||
(deftype GridLayout [$plugin $file $page $id]
|
||||
Object
|
||||
|
||||
(addRow
|
||||
|
@ -75,9 +75,10 @@
|
|||
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||
|
||||
(defn grid-layout-proxy
|
||||
[file-id page-id id]
|
||||
(-> (GridLayout. file-id page-id id)
|
||||
[plugin-id file-id page-id id]
|
||||
(-> (GridLayout. plugin-id file-id page-id id)
|
||||
(crc/add-properties!
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
@ -164,7 +165,6 @@
|
|||
(when (us/safe-int? value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
||||
|
||||
|
||||
{:name "topPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p1)
|
||||
:set
|
||||
|
@ -197,17 +197,18 @@
|
|||
(when (us/safe-int? value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||
|
||||
(deftype GridCellProxy [$file $page $id])
|
||||
(deftype GridCellProxy [$plugin $file $page $id])
|
||||
|
||||
(defn layout-cell-proxy
|
||||
[file-id page-id id]
|
||||
[plugin-id file-id page-id id]
|
||||
(letfn [(locate-cell [_]
|
||||
(let [shape (locate-shape file-id page-id id)
|
||||
parent (locate-shape file-id page-id (:parent-id shape))]
|
||||
(ctl/get-cell-by-shape-id parent id)))]
|
||||
|
||||
(-> (GridCellProxy. file-id page-id id)
|
||||
(-> (GridCellProxy. plugin-id file-id page-id id)
|
||||
(crc/add-properties!
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.types.color :as ctc]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.store :as st]
|
||||
|
@ -26,7 +27,7 @@
|
|||
(declare lib-color-proxy)
|
||||
(declare lib-typography-proxy)
|
||||
|
||||
(deftype LibraryColorProxy [$file $id]
|
||||
(deftype LibraryColorProxy [$plugin $file $id]
|
||||
Object
|
||||
|
||||
(remove
|
||||
|
@ -39,7 +40,7 @@
|
|||
color (-> (u/locate-library-color $file $id)
|
||||
(assoc :id color-id))]
|
||||
(st/emit! (dwl/add-color color {:rename? false}))
|
||||
(lib-color-proxy $id color-id)))
|
||||
(lib-color-proxy $plugin $id color-id)))
|
||||
|
||||
(asFill [_]
|
||||
(let [color (u/locate-library-color $file $id)]
|
||||
|
@ -63,15 +64,87 @@
|
|||
:stroke-color-ref-id $id
|
||||
:stroke-image (:image color)
|
||||
:stroke-style :solid
|
||||
:stroke-alignment :inner})))))
|
||||
:stroke-alignment :inner}))))
|
||||
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :color-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [color (u/proxy->library-color self)]
|
||||
(dm/get-in color [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :color-edit-non-local-library $file)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :color-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :color-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :color $id (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [color (u/proxy->library-color self)]
|
||||
(apply array (keys (dm/get-in color [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :color-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [color (u/proxy->library-color self)]
|
||||
(dm/get-in color [:plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :color-edit-non-local-library $file)
|
||||
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :color-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :color-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :color $id (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [color (u/proxy->library-color self)]
|
||||
(apply array (keys (dm/get-in color [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-color-proxy
|
||||
[file-id id]
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
(assert (uuid? id))
|
||||
|
||||
(cr/add-properties!
|
||||
(LibraryColorProxy. file-id id)
|
||||
(LibraryColorProxy. plugin-id file-id id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
|
||||
|
@ -139,7 +212,7 @@
|
|||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-image value))))}))
|
||||
|
||||
(deftype LibraryTypographyProxy [$file $id]
|
||||
(deftype LibraryTypographyProxy [$plugin $file $id]
|
||||
Object
|
||||
(remove
|
||||
[_]
|
||||
|
@ -151,7 +224,7 @@
|
|||
typo (-> (u/locate-library-typography $file $id)
|
||||
(assoc :id typo-id))]
|
||||
(st/emit! (dwl/add-typography typo false))
|
||||
(lib-typography-proxy $id typo-id)))
|
||||
(lib-typography-proxy $plugin $id typo-id)))
|
||||
|
||||
(applyToText
|
||||
[_ shape]
|
||||
|
@ -162,15 +235,88 @@
|
|||
(applyToTextRange
|
||||
[_ _shape _from _to]
|
||||
;; TODO
|
||||
))
|
||||
)
|
||||
|
||||
;; PLUGIN DATA
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :typography-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [typography (u/proxy->library-typography self)]
|
||||
(dm/get-in typography [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :typography-edit-non-local-library $file)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :typography-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :typography-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :typography $id (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [typography (u/proxy->library-typography self)]
|
||||
(apply array (keys (dm/get-in typography [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :typography-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [typography (u/proxy->library-typography self)]
|
||||
(dm/get-in typography [:plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :typography-edit-non-local-library $file)
|
||||
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :typography-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :typography-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :typography $id (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [typography (u/proxy->library-typography self)]
|
||||
(apply array (keys (dm/get-in typography [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-typography-proxy
|
||||
[file-id id]
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
(assert (uuid? id))
|
||||
|
||||
(cr/add-properties!
|
||||
(LibraryTypographyProxy. file-id id)
|
||||
(LibraryTypographyProxy. plugin-id file-id id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "id" :get (fn [_] (dm/str id))}
|
||||
|
@ -285,7 +431,7 @@
|
|||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-text-transform value)))}))
|
||||
|
||||
(deftype LibraryComponentProxy [$file $id]
|
||||
(deftype LibraryComponentProxy [$plugin $file $id]
|
||||
Object
|
||||
|
||||
(remove
|
||||
|
@ -296,15 +442,87 @@
|
|||
[_]
|
||||
(let [id-ref (atom nil)]
|
||||
(st/emit! (dwl/instantiate-component $file $id (gpt/point 0 0) {:id-ref id-ref}))
|
||||
(shapes/shape-proxy @id-ref))))
|
||||
(shapes/shape-proxy $plugin @id-ref)))
|
||||
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :component-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [component (u/proxy->library-component self)]
|
||||
(dm/get-in component [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :component-edit-non-local-library $file)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :component-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :component-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :component $id (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [component (u/proxy->library-component self)]
|
||||
(apply array (keys (dm/get-in component [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :component-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [component (u/proxy->library-component self)]
|
||||
(dm/get-in component [:plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
(cond
|
||||
(not= $file (:current-file-id @st/state))
|
||||
(u/display-not-valid :component-edit-non-local-library $file)
|
||||
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :component-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :component-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :component $id (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [component (u/proxy->library-component self)]
|
||||
(apply array (keys (dm/get-in component [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-component-proxy
|
||||
[file-id id]
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
(assert (uuid? id))
|
||||
|
||||
(cr/add-properties!
|
||||
(LibraryComponentProxy. file-id id)
|
||||
(LibraryComponentProxy. plugin-id file-id id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "id" :get (fn [_] (dm/str id))}
|
||||
|
@ -329,34 +547,102 @@
|
|||
(st/emit! (dwl/rename-component id value)))
|
||||
(u/display-not-valid :library-component-path value)))}))
|
||||
|
||||
(deftype Library [$id]
|
||||
(deftype Library [$plugin $id]
|
||||
Object
|
||||
|
||||
(createColor
|
||||
[_]
|
||||
(let [color-id (uuid/next)]
|
||||
(st/emit! (dwl/add-color {:id color-id :name "Color" :color "#000000" :opacity 1} {:rename? false}))
|
||||
(lib-color-proxy $id color-id)))
|
||||
(lib-color-proxy $plugin $id color-id)))
|
||||
|
||||
(createTypography
|
||||
[_]
|
||||
(let [typography-id (uuid/next)]
|
||||
(st/emit! (dwl/add-typography (ctt/make-typography {:id typography-id :name "Typography"}) false))
|
||||
(lib-typography-proxy $id typography-id)))
|
||||
(lib-typography-proxy $plugin $id typography-id)))
|
||||
|
||||
(createComponent
|
||||
[_ shapes]
|
||||
(let [id-ref (atom nil)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwl/add-component id-ref ids))
|
||||
(lib-component-proxy $id @id-ref))))
|
||||
(lib-component-proxy $plugin $id @id-ref)))
|
||||
|
||||
;; Plugin data
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :file-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $id :file (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [file (u/proxy->file self)]
|
||||
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(dm/get-in file [:data :plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :file-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $id :file (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [file (u/proxy->file self)]
|
||||
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn library-proxy
|
||||
[file-id]
|
||||
[plugin-id file-id]
|
||||
(assert (uuid? file-id) "File id not valid")
|
||||
|
||||
(cr/add-properties!
|
||||
(Library. file-id)
|
||||
(Library. plugin-id file-id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
|
||||
{:name "id"
|
||||
|
@ -369,14 +655,14 @@
|
|||
:get
|
||||
(fn [_]
|
||||
(let [file (u/locate-file file-id)
|
||||
colors (->> file :data :colors keys (map #(lib-color-proxy file-id %)))]
|
||||
colors (->> file :data :colors keys (map #(lib-color-proxy plugin-id file-id %)))]
|
||||
(apply array colors)))}
|
||||
|
||||
{:name "typographies"
|
||||
:get
|
||||
(fn [_]
|
||||
(let [file (u/locate-file file-id)
|
||||
typographies (->> file :data :typographies keys (map #(lib-typography-proxy file-id %)))]
|
||||
typographies (->> file :data :typographies keys (map #(lib-typography-proxy plugin-id file-id %)))]
|
||||
(apply array typographies)))}
|
||||
|
||||
{:name "components"
|
||||
|
@ -388,10 +674,10 @@
|
|||
:components
|
||||
(remove (comp :deleted second))
|
||||
(map first)
|
||||
(map #(lib-component-proxy file-id %)))]
|
||||
(map #(lib-component-proxy plugin-id file-id %)))]
|
||||
(apply array components)))}))
|
||||
|
||||
(deftype PenpotLibrarySubcontext []
|
||||
(deftype PenpotLibrarySubcontext [$plugin]
|
||||
Object
|
||||
(find
|
||||
[_ _name])
|
||||
|
@ -399,14 +685,15 @@
|
|||
(find [_]))
|
||||
|
||||
(defn library-subcontext
|
||||
[]
|
||||
[plugin-id]
|
||||
(cr/add-properties!
|
||||
(PenpotLibrarySubcontext.)
|
||||
(PenpotLibrarySubcontext. plugin-id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "local" :get
|
||||
(fn [_]
|
||||
(library-proxy (:current-file-id @st/state)))}
|
||||
(library-proxy plugin-id (:current-file-id @st/state)))}
|
||||
|
||||
{:name "connected" :get
|
||||
(fn [_]
|
||||
(let [libraries (get @st/state :workspace-libraries)]
|
||||
(apply array (->> libraries vals (map library-proxy)))))}))
|
||||
(apply array (->> libraries keys (map (partial library-proxy plugin-id))))))}))
|
||||
|
|
|
@ -17,23 +17,90 @@
|
|||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(deftype PageProxy [$file $id]
|
||||
(deftype PageProxy [$plugin $file $id]
|
||||
Object
|
||||
(getShapeById
|
||||
[_ shape-id]
|
||||
(let [shape-id (uuid/uuid shape-id)]
|
||||
(shape/shape-proxy $file $id shape-id)))
|
||||
(shape/shape-proxy $plugin $file $id shape-id)))
|
||||
|
||||
(getRoot
|
||||
[_]
|
||||
(shape/shape-proxy $file $id uuid/zero))
|
||||
(shape/shape-proxy $plugin $file $id uuid/zero))
|
||||
|
||||
(findShapes
|
||||
[_]
|
||||
;; Returns a lazy (iterable) of all available shapes
|
||||
(when (and (some? $file) (some? $id))
|
||||
(let [page (u/locate-page $file $id)]
|
||||
(apply array (sequence (map shape/shape-proxy) (keys (:objects page))))))))
|
||||
(apply array (sequence (map (partial shape/shape-proxy $plugin)) (keys (:objects page)))))))
|
||||
|
||||
;; Plugin data
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :page-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [page (u/proxy->page self)]
|
||||
(dm/get-in page [:options :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :page-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :page-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :page $id (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [page (u/proxy->page self)]
|
||||
(apply array (keys (dm/get-in page [:options :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :page-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [page (u/proxy->page self)]
|
||||
(dm/get-in page [:options :plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :page-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :page-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :page $id (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [page (u/proxy->page self)]
|
||||
(apply array (keys (dm/get-in page [:options :plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(crc/define-properties!
|
||||
PageProxy
|
||||
|
@ -41,9 +108,10 @@
|
|||
:get (fn [] (str "PageProxy"))})
|
||||
|
||||
(defn page-proxy
|
||||
[file-id id]
|
||||
[plugin-id file-id id]
|
||||
(crc/add-properties!
|
||||
(PageProxy. file-id id)
|
||||
(PageProxy. plugin-id file-id id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
|
@ -20,7 +21,7 @@
|
|||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
|
@ -61,23 +62,90 @@
|
|||
(dwt/current-paragraph-values {:shape shape :attrs txt/paragraph-attrs})
|
||||
(dwt/current-text-values {:shape shape :attrs txt/text-node-attrs})))
|
||||
|
||||
(deftype ShapeProxy [$file $page $id]
|
||||
(deftype ShapeProxy [$plugin $file $page $id]
|
||||
Object
|
||||
(resize
|
||||
[_ width height]
|
||||
(st/emit! (udw/update-dimensions [$id] :width width)
|
||||
(udw/update-dimensions [$id] :height height)))
|
||||
(st/emit! (dw/update-dimensions [$id] :width width)
|
||||
(dw/update-dimensions [$id] :height height)))
|
||||
|
||||
(clone
|
||||
[_]
|
||||
(let [ret-v (atom nil)]
|
||||
(st/emit! (dws/duplicate-shapes #{$id} :change-selection? false :return-ref ret-v))
|
||||
(shape-proxy (deref ret-v))))
|
||||
(shape-proxy $plugin (deref ret-v))))
|
||||
|
||||
(remove
|
||||
[_]
|
||||
(st/emit! (dwsh/delete-shapes #{$id})))
|
||||
|
||||
;; Plugin data
|
||||
(getPluginData
|
||||
[self key]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :shape-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [shape (u/proxy->shape self)]
|
||||
(dm/get-in shape [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||
|
||||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(u/display-not-valid :shape-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :shape-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :shape $id $page (keyword "plugin" (str $plugin)) key value))))
|
||||
|
||||
(getPluginDataKeys
|
||||
[self]
|
||||
(let [shape (u/proxy->shape self)]
|
||||
(apply array (keys (dm/get-in shape [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||
|
||||
(getSharedPluginData
|
||||
[self namespace key]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :shape-plugin-data-key key)
|
||||
|
||||
:else
|
||||
(let [shape (u/proxy->shape self)]
|
||||
(dm/get-in shape [:plugin-data (keyword "shared" namespace) key]))))
|
||||
|
||||
(setSharedPluginData
|
||||
[_ namespace key value]
|
||||
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(u/display-not-valid :shape-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
(u/display-not-valid :shape-plugin-data value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/set-plugin-data $file :shape $id $page (keyword "shared" namespace) key value))))
|
||||
|
||||
(getSharedPluginDataKeys
|
||||
[self namespace]
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||
|
||||
:else
|
||||
(let [shape (u/proxy->shape self)]
|
||||
(apply array (keys (dm/get-in shape [:plugin-data (keyword "shared" namespace)]))))))
|
||||
|
||||
;; Only for frames + groups + booleans
|
||||
(getChildren
|
||||
[_]
|
||||
|
@ -85,7 +153,7 @@
|
|||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||
(apply array (->> (u/locate-shape $file $page $id)
|
||||
:shapes
|
||||
(map #(shape-proxy $file $page %))))
|
||||
(map #(shape-proxy $plugin $file $page %))))
|
||||
(u/display-not-valid :getChildren (:type shape)))))
|
||||
|
||||
(appendChild
|
||||
|
@ -93,7 +161,7 @@
|
|||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (udw/relocate-shapes #{child-id} $id 0)))
|
||||
(st/emit! (dw/relocate-shapes #{child-id} $id 0)))
|
||||
(u/display-not-valid :appendChild (:type shape)))))
|
||||
|
||||
(insertChild
|
||||
|
@ -101,7 +169,7 @@
|
|||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (udw/relocate-shapes #{child-id} $id index)))
|
||||
(st/emit! (dw/relocate-shapes #{child-id} $id index)))
|
||||
(u/display-not-valid :insertChild (:type shape)))))
|
||||
|
||||
;; Only for frames
|
||||
|
@ -110,7 +178,7 @@
|
|||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (cfh/frame-shape? shape)
|
||||
(do (st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false))
|
||||
(grid/grid-layout-proxy $file $page $id))
|
||||
(grid/grid-layout-proxy $plugin $file $page $id))
|
||||
(u/display-not-valid :addFlexLayout (:type shape)))))
|
||||
|
||||
(addGridLayout
|
||||
|
@ -118,7 +186,7 @@
|
|||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (cfh/frame-shape? shape)
|
||||
(do (st/emit! (dwsl/create-layout-from-id $id :grid :from-frame? true :calculate-params? false))
|
||||
(grid/grid-layout-proxy $file $page $id))
|
||||
(grid/grid-layout-proxy $plugin $file $page $id))
|
||||
(u/display-not-valid :addGridLayout (:type shape)))))
|
||||
|
||||
;; Make masks for groups
|
||||
|
@ -142,6 +210,14 @@
|
|||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (cfh/path-shape? shape)
|
||||
(upf/format-path (:content shape))
|
||||
(u/display-not-valid :makeMask (:type shape)))))
|
||||
|
||||
;; Text shapes
|
||||
(getRange
|
||||
[_ _from _to]
|
||||
(let [shape (u/locate-shape $file $page $id)]
|
||||
(if (cfh/text-shape? shape)
|
||||
nil ;; TODO
|
||||
(u/display-not-valid :makeMask (:type shape))))))
|
||||
|
||||
(crc/define-properties!
|
||||
|
@ -150,20 +226,21 @@
|
|||
:get (fn [] (str "ShapeProxy"))})
|
||||
|
||||
(defn shape-proxy
|
||||
([id]
|
||||
(shape-proxy (:current-file-id @st/state) (:current-page-id @st/state) id))
|
||||
([plugin-id id]
|
||||
(shape-proxy plugin-id (:current-file-id @st/state) (:current-page-id @st/state) id))
|
||||
|
||||
([page-id id]
|
||||
(shape-proxy (:current-file-id @st/state) page-id id))
|
||||
([plugin-id page-id id]
|
||||
(shape-proxy plugin-id (:current-file-id @st/state) page-id id))
|
||||
|
||||
([file-id page-id id]
|
||||
([plugin-id file-id page-id id]
|
||||
(assert (uuid? file-id))
|
||||
(assert (uuid? page-id))
|
||||
(assert (uuid? id))
|
||||
|
||||
(let [data (u/locate-shape file-id page-id id)]
|
||||
(-> (ShapeProxy. file-id page-id id)
|
||||
(-> (ShapeProxy. plugin-id file-id page-id id)
|
||||
(crc/add-properties!
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
@ -332,14 +409,14 @@
|
|||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (udw/update-position id {:x value}))))}
|
||||
(st/emit! (dw/update-position id {:x value}))))}
|
||||
|
||||
{:name "y"
|
||||
:get #(-> % u/proxy->shape :y)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (udw/update-position id {:y value}))))}
|
||||
(st/emit! (dw/update-position id {:y value}))))}
|
||||
|
||||
{:name "parentX"
|
||||
:get (fn [self]
|
||||
|
@ -353,7 +430,7 @@
|
|||
parent-id (-> self u/proxy->shape :parent-id)
|
||||
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||
parent-x (:x parent)]
|
||||
(st/emit! (udw/update-position id {:x (+ parent-x value)}))))}
|
||||
(st/emit! (dw/update-position id {:x (+ parent-x value)}))))}
|
||||
|
||||
{:name "parentY"
|
||||
:get (fn [self]
|
||||
|
@ -368,7 +445,7 @@
|
|||
parent-id (-> self u/proxy->shape :parent-id)
|
||||
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||
parent-y (:y parent)]
|
||||
(st/emit! (udw/update-position id {:y (+ parent-y value)}))))}
|
||||
(st/emit! (dw/update-position id {:y (+ parent-y value)}))))}
|
||||
|
||||
{:name "frameX"
|
||||
:get (fn [self]
|
||||
|
@ -383,7 +460,7 @@
|
|||
frame-id (-> self u/proxy->shape :frame-id)
|
||||
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||
frame-x (:x frame)]
|
||||
(st/emit! (udw/update-position id {:x (+ frame-x value)}))))}
|
||||
(st/emit! (dw/update-position id {:x (+ frame-x value)}))))}
|
||||
|
||||
{:name "frameY"
|
||||
:get (fn [self]
|
||||
|
@ -398,7 +475,7 @@
|
|||
frame-id (-> self u/proxy->shape :frame-id)
|
||||
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||
frame-y (:y frame)]
|
||||
(st/emit! (udw/update-position id {:y (+ frame-y value)}))))}
|
||||
(st/emit! (dw/update-position id {:y (+ frame-y value)}))))}
|
||||
|
||||
{:name "width"
|
||||
:get #(-> % u/proxy->shape :width)}
|
||||
|
@ -437,7 +514,7 @@
|
|||
id (obj/get self "$id")
|
||||
objects (u/locate-objects file-id page-id)]
|
||||
(when (ctl/any-layout-immediate-child-id? objects id)
|
||||
(flex/layout-child-proxy file-id page-id id))))}
|
||||
(flex/layout-child-proxy plugin-id file-id page-id id))))}
|
||||
|
||||
{:name "layoutCell"
|
||||
:get
|
||||
|
@ -447,7 +524,7 @@
|
|||
id (obj/get self "$id")
|
||||
objects (u/locate-objects file-id page-id)]
|
||||
(when (ctl/grid-layout-immediate-child-id? objects id)
|
||||
(grid/layout-cell-proxy file-id page-id id))))})
|
||||
(grid/layout-cell-proxy plugin-id file-id page-id id))))})
|
||||
|
||||
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
||||
(crc/add-properties!
|
||||
|
@ -465,7 +542,7 @@
|
|||
page-id (obj/get self "$page")
|
||||
id (obj/get self "$id")]
|
||||
(when (= :grid layout)
|
||||
(grid/grid-layout-proxy file-id page-id id))))}
|
||||
(grid/grid-layout-proxy plugin-id file-id page-id id))))}
|
||||
|
||||
{:name "flex"
|
||||
:get
|
||||
|
@ -475,7 +552,7 @@
|
|||
page-id (obj/get self "$page")
|
||||
id (obj/get self "$id")]
|
||||
(when (= :flex layout)
|
||||
(flex/flex-layout-proxy file-id page-id id))))}
|
||||
(flex/flex-layout-proxy plugin-id file-id page-id id))))}
|
||||
|
||||
{:name "guides"
|
||||
:get #(-> % u/proxy->shape :grids u/array-to-js)
|
||||
|
|
|
@ -11,14 +11,18 @@
|
|||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(deftype CurrentUserProxy [$session])
|
||||
(deftype ActiveUserProxy [$session])
|
||||
(deftype CurrentUserProxy [$plugin $session])
|
||||
(deftype ActiveUserProxy [$plugin $session])
|
||||
|
||||
(defn add-user-properties
|
||||
[user-proxy]
|
||||
(let [session-id (obj/get user-proxy "$session")]
|
||||
(let [plugin-id (obj/get user-proxy "$plugin")
|
||||
session-id (obj/get user-proxy "$session")]
|
||||
(crc/add-properties!
|
||||
user-proxy
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "$session" :enumerable false :get (constantly session-id)}
|
||||
|
||||
{:name "id"
|
||||
:get (fn [_] (-> (u/locate-profile session-id) :id str))}
|
||||
|
||||
|
@ -35,13 +39,13 @@
|
|||
:get (fn [_] (str session-id))})))
|
||||
|
||||
(defn current-user-proxy
|
||||
[session-id]
|
||||
(-> (CurrentUserProxy. session-id)
|
||||
[plugin-id session-id]
|
||||
(-> (CurrentUserProxy. plugin-id session-id)
|
||||
(add-user-properties)))
|
||||
|
||||
(defn active-user-proxy
|
||||
[session-id]
|
||||
(-> (ActiveUserProxy. session-id)
|
||||
[plugin-id session-id]
|
||||
(-> (ActiveUserProxy. plugin-id session-id)
|
||||
(add-user-properties)
|
||||
(crc/add-properties!
|
||||
{:name "position" :get (fn [_] (-> (u/locate-presence session-id) :point u/to-js))}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
[app.main.store :as st]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(deftype ViewportProxy []
|
||||
(deftype ViewportProxy [$plugin]
|
||||
Object
|
||||
(zoomIntoView [_ shapes]
|
||||
(let [ids
|
||||
|
@ -33,9 +33,9 @@
|
|||
:get (fn [] (str "ViewportProxy"))})
|
||||
|
||||
(defn create-proxy
|
||||
[]
|
||||
[plugin-id]
|
||||
(crc/add-properties!
|
||||
(ViewportProxy.)
|
||||
(ViewportProxy. plugin-id)
|
||||
{:name "center"
|
||||
:get
|
||||
(fn [_]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue