mirror of
https://github.com/penpot/penpot.git
synced 2025-04-16 08:51:32 -05:00
🎉 Link with components of other files
This commit is contained in:
parent
f837bad894
commit
1ad9a7f82f
11 changed files with 329 additions and 96 deletions
|
@ -44,6 +44,9 @@
|
|||
(integer? %)
|
||||
(>= % min-safe-int)
|
||||
(<= % max-safe-int)))
|
||||
(s/def ::component-id uuid?)
|
||||
(s/def ::component-file uuid?)
|
||||
(s/def ::shape-ref uuid?)
|
||||
|
||||
(s/def ::safe-number
|
||||
#(and
|
||||
|
@ -216,7 +219,10 @@
|
|||
|
||||
(s/def ::shape
|
||||
(s/and ::minimal-shape ::shape-attrs
|
||||
(s/keys :opt-un [::id])))
|
||||
(s/keys :opt-un [::id
|
||||
::component-id
|
||||
::component-file
|
||||
::shape-ref])))
|
||||
|
||||
(s/def :internal.page/objects (s/map-of uuid? ::shape))
|
||||
|
||||
|
@ -363,7 +369,7 @@
|
|||
(s/keys :req-un [::id]))
|
||||
|
||||
(defmethod change-spec :update-component [_]
|
||||
(s/keys :req-un [::id ::shapes]))
|
||||
(s/keys :req-un [::id ::name ::shapes]))
|
||||
|
||||
(s/def ::change (s/multi-spec change-spec :type))
|
||||
(s/def ::changes (s/coll-of ::change))
|
||||
|
@ -777,50 +783,12 @@
|
|||
[data {:keys [id]}]
|
||||
(d/dissoc-in data [:components id]))
|
||||
|
||||
(declare sync-component-shape)
|
||||
|
||||
(defmethod process-change :update-component
|
||||
[data {:keys [id shapes]}]
|
||||
(let [sync-component
|
||||
(fn [component]
|
||||
(update component :objects
|
||||
#(d/mapm (partial sync-component-shape shapes) %)))]
|
||||
|
||||
(update-in data [:components id] sync-component)))
|
||||
|
||||
(defn- sync-component-shape
|
||||
[new-shapes _ component-shape]
|
||||
(let [shape (d/seek #(= (:shape-ref %) (:id component-shape)) new-shapes)]
|
||||
(if (nil? shape)
|
||||
component-shape
|
||||
(-> component-shape
|
||||
(d/assoc-when :content (:content shape))
|
||||
(d/assoc-when :fill-color (:fill-color shape))
|
||||
(d/assoc-when :fill-color-ref-file (:fill-color-ref-file shape))
|
||||
(d/assoc-when :fill-color-ref-id (:fill-color-ref-id shape))
|
||||
(d/assoc-when :fill-opacity (:fill-opacity shape))
|
||||
(d/assoc-when :font-family (:font-family shape))
|
||||
(d/assoc-when :font-size (:font-size shape))
|
||||
(d/assoc-when :font-style (:font-style shape))
|
||||
(d/assoc-when :font-weight (:font-weight shape))
|
||||
(d/assoc-when :letter-spacing (:letter-spacing shape))
|
||||
(d/assoc-when :line-height (:line-height shape))
|
||||
(d/assoc-when :proportion (:proportion shape))
|
||||
(d/assoc-when :rx (:rx shape))
|
||||
(d/assoc-when :ry (:ry shape))
|
||||
(d/assoc-when :stroke-color (:stroke-color shape))
|
||||
(d/assoc-when :stroke-color-ref-file (:stroke-color-ref-file shape))
|
||||
(d/assoc-when :stroke-color-ref-id (:stroke-color-ref-id shape))
|
||||
(d/assoc-when :stroke-opacity (:stroke-opacity shape))
|
||||
(d/assoc-when :stroke-style (:stroke-style shape))
|
||||
(d/assoc-when :stroke-width (:stroke-width shape))
|
||||
(d/assoc-when :stroke-alignment (:stroke-alignment shape))
|
||||
(d/assoc-when :text-align (:text-align shape))
|
||||
(d/assoc-when :width (:width shape))
|
||||
(d/assoc-when :height (:height shape))
|
||||
(d/assoc-when :interactions (:interactions shape))
|
||||
(d/assoc-when :selrect (:selrect shape))
|
||||
(d/assoc-when :points (:points shape))))))
|
||||
[data {:keys [id name shapes]}]
|
||||
(update-in data [:components id]
|
||||
#(assoc %
|
||||
:name name
|
||||
:objects (d/index-by :id shapes))))
|
||||
|
||||
(defmethod process-operation :set
|
||||
[shape op]
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
|
||||
Returns the cloned object, the list of all new objects (including
|
||||
the cloned one), and possibly a list of original objects modified."
|
||||
|
||||
([object parent-id objects xf-new-object]
|
||||
(clone-object object parent-id objects xf-new-object identity))
|
||||
|
||||
|
|
|
@ -176,9 +176,7 @@
|
|||
grid-auto-rows: 10vh;
|
||||
|
||||
.grid-cell {
|
||||
background-color: transparent;
|
||||
border: 1px solid $color-gray-40;
|
||||
border-radius: 4px;
|
||||
padding: $x-small;
|
||||
|
||||
& svg {
|
||||
height: 10vh;
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
.element-list li.component {
|
||||
|
||||
.element-list-body {
|
||||
.element-name {
|
||||
span.element-name {
|
||||
color: $color-component;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@
|
|||
}
|
||||
|
||||
&.selected {
|
||||
.element-name {
|
||||
span.element-name {
|
||||
color: $color-component-highlight;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@
|
|||
&:hover {
|
||||
background-color: $color-component-highlight;
|
||||
|
||||
.element-name {
|
||||
span.element-name {
|
||||
color: $color-gray-60;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.texts :as dwtxt]
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.data.colors :as dwl]
|
||||
[app.main.data.colors :as mdc]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
|
@ -1130,8 +1130,14 @@
|
|||
(ptk/reify ::show-context-menu
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [mdata {:position position
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
root-id (cph/get-root-component (:id shape) objects)
|
||||
root-shape (get objects root-id)
|
||||
|
||||
mdata {:position position
|
||||
:shape shape
|
||||
:root-shape root-shape
|
||||
:selected (get-in state [:workspace-local :selected])}]
|
||||
(-> state
|
||||
(assoc-in [:workspace-local :context-menu] mdata))))
|
||||
|
@ -1467,5 +1473,5 @@
|
|||
"right" #(st/emit! (dwt/move-selected :right false))
|
||||
"left" #(st/emit! (dwt/move-selected :left false))
|
||||
|
||||
"i" #(st/emit! (dwl/picker-for-selected-shape ))})
|
||||
"i" #(st/emit! (mdc/picker-for-selected-shape ))})
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.util.color :as color]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[beicon.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[potok.core :as ptk]))
|
||||
|
@ -147,6 +148,9 @@
|
|||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val (:component-id updated-shape)}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val (:shape-ref updated-shape)}]})
|
||||
|
@ -164,6 +168,9 @@
|
|||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val nil}]})
|
||||
|
@ -192,15 +199,14 @@
|
|||
|
||||
(defn delete-component
|
||||
[{:keys [id] :as params}]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::delete-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [component (get-in state [:workspace-data :components id])
|
||||
|
||||
rchanges [{:type :del-component
|
||||
:id id}
|
||||
{:type :sync-library
|
||||
:id (get-in state [:workspace-file :id])}]
|
||||
:id id}]
|
||||
|
||||
uchanges [{:type :add-component
|
||||
:id id
|
||||
|
@ -210,12 +216,15 @@
|
|||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn instantiate-component
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
[file-id component-id]
|
||||
(us/assert (s/nilable ::us/uuid) file-id)
|
||||
(us/assert ::us/uuid component-id)
|
||||
(ptk/reify ::instantiate-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [component (get-in state [:workspace-data :components id])
|
||||
(let [component (if (nil? file-id)
|
||||
(get-in state [:workspace-data :components component-id])
|
||||
(get-in state [:workspace-libraries file-id :data :components component-id]))
|
||||
component-shape (get-in component [:objects (:id component)])
|
||||
|
||||
orig-pos (gpt/point (:x component-shape) (:y component-shape))
|
||||
|
@ -228,14 +237,16 @@
|
|||
|
||||
page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
unames (dwc/retrieve-used-names objects)
|
||||
unames (atom (dwc/retrieve-used-names objects))
|
||||
|
||||
all-frames (cph/select-frames objects)
|
||||
|
||||
xf-new-shape
|
||||
(fn [new-shape original-shape]
|
||||
(let [new-name ;; TODO: ojoooooooooo
|
||||
(dwc/generate-unique-name unames (:name new-shape))]
|
||||
(let [new-name
|
||||
(dwc/generate-unique-name @unames (:name new-shape))]
|
||||
|
||||
(swap! unames conj new-name)
|
||||
|
||||
(cond-> new-shape
|
||||
true
|
||||
|
@ -249,7 +260,10 @@
|
|||
(assoc $ :shape-ref (:id original-shape)))
|
||||
|
||||
(nil? (:parent-id original-shape))
|
||||
(assoc :component-id (:id original-shape)))))
|
||||
(assoc :component-id (:id original-shape))
|
||||
|
||||
(and (nil? (:parent-id original-shape)) (some? file-id))
|
||||
(assoc :component-file file-id))))
|
||||
|
||||
[new-shape new-shapes _]
|
||||
(cph/clone-object component-shape
|
||||
|
@ -294,6 +308,9 @@
|
|||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val nil}]})
|
||||
|
@ -306,6 +323,9 @@
|
|||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val (:component-id obj)}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val (:component-file obj)}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val (:shape-ref obj)}]})
|
||||
|
@ -313,17 +333,51 @@
|
|||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn nav-to-component-file
|
||||
[file-id]
|
||||
(us/assert ::us/uuid file-id)
|
||||
(ptk/reify ::nav-to-component-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [file (get-in state [:workspace-libraries file-id])
|
||||
pparams {:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
qparams {:page-id (first (get-in file [:data :pages]))}]
|
||||
(st/emit! (rt/nav-new-window :workspace pparams qparams))))))
|
||||
|
||||
(declare generate-sync-file)
|
||||
(declare generate-sync-page)
|
||||
(declare generate-sync-shape-and-children)
|
||||
(declare generate-sync-shape)
|
||||
(declare remove-component-and-ref)
|
||||
(declare remove-ref)
|
||||
(declare update-attrs)
|
||||
(declare sync-attrs)
|
||||
|
||||
(defn reset-component
|
||||
[id]
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::reset-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
)))
|
||||
(let [page-id (:current-page-id state)
|
||||
page (get-in state [:workspace-data :pages-index page-id])
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
root-id (cph/get-root-component id objects)
|
||||
root-shape (get objects id)
|
||||
file-id (get root-shape :component-file)
|
||||
|
||||
components
|
||||
(if (nil? file-id)
|
||||
(get-in state [:workspace-data :components])
|
||||
(get-in state [:workspace-libraries file-id :data :components]))
|
||||
|
||||
[rchanges uchanges]
|
||||
(generate-sync-shape-and-children root-shape page components)]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn update-component
|
||||
[id]
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::update-component
|
||||
|
@ -333,21 +387,202 @@
|
|||
objects (dwc/lookup-page-objects state page-id)
|
||||
root-id (cph/get-root-component id objects)
|
||||
root-shape (get objects id)
|
||||
|
||||
component-id (get root-shape :component-id)
|
||||
component-objs (dwc/lookup-component-objects state component-id)
|
||||
component-obj (get component-objs component-id)
|
||||
|
||||
shapes (cph/get-object-with-children root-id objects)
|
||||
;; Clone again the original shape and its children, maintaing
|
||||
;; the ids of the cloned shapes. If the original shape has some
|
||||
;; new child shapes, the cloned ones will have new generated ids.
|
||||
xf-new-shape (fn [new-shape original-shape]
|
||||
(cond-> new-shape
|
||||
true
|
||||
(assoc :frame-id nil)
|
||||
|
||||
(some? (:shape-ref original-shape))
|
||||
(assoc :id (:shape-ref original-shape))))
|
||||
|
||||
[new-shape new-shapes _]
|
||||
(cph/clone-object root-shape nil objects xf-new-shape)
|
||||
|
||||
rchanges [{:type :update-component
|
||||
:id component-id
|
||||
:shapes shapes}
|
||||
{:type :sync-library
|
||||
:id (get-in state [:workspace-file :id])}]
|
||||
|
||||
:name (:name new-shape)
|
||||
:shapes new-shapes}]
|
||||
|
||||
uchanges [{:type :update-component
|
||||
:id component-id
|
||||
:name (:name component-obj)
|
||||
:shapes (vals component-objs)}]]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
|
||||
(defn sync-file
|
||||
[{:keys [file-id] :as params}]
|
||||
(us/assert (s/nilable ::us/uuid) file-id)
|
||||
(ptk/reify ::sync-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [[rchanges uchanges] (generate-sync-file state file-id)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn- generate-sync-file
|
||||
[state file-id]
|
||||
(let [components
|
||||
(if (nil? file-id)
|
||||
(get-in state [:workspace-data :components])
|
||||
(get-in state [:workspace-libraries file-id :data :components]))]
|
||||
(loop [pages (seq (vals (get-in state [:workspace-data :pages-index])))
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(let [page (first pages)]
|
||||
(if (nil? page)
|
||||
[rchanges uchanges]
|
||||
(let [[page-rchanges page-uchanges]
|
||||
(generate-sync-page page components)]
|
||||
(recur (next pages)
|
||||
(concat rchanges page-rchanges)
|
||||
(concat uchanges page-uchanges))))))))
|
||||
|
||||
(defn- generate-sync-page
|
||||
[page components]
|
||||
(let [linked-shapes
|
||||
(cph/select-objects #(some? (:component-id %)) page)]
|
||||
(loop [shapes (seq linked-shapes)
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(let [shape (first shapes)]
|
||||
(if (nil? shape)
|
||||
[rchanges uchanges]
|
||||
(let [[shape-rchanges shape-uchanges]
|
||||
(generate-sync-shape-and-children shape page components)]
|
||||
(recur (next shapes)
|
||||
(concat rchanges shape-rchanges)
|
||||
(concat uchanges shape-uchanges))))))))
|
||||
|
||||
(defn- generate-sync-shape-and-children
|
||||
[root-shape page components]
|
||||
(let [objects (get page :objects)
|
||||
all-shapes (cph/get-object-with-children (:id root-shape) objects)
|
||||
component (get components (:component-id root-shape))]
|
||||
(loop [shapes (seq all-shapes)
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(let [shape (first shapes)]
|
||||
(if (nil? shape)
|
||||
[rchanges uchanges]
|
||||
(let [[shape-rchanges shape-uchanges]
|
||||
(generate-sync-shape shape page component)]
|
||||
(recur (next shapes)
|
||||
(concat rchanges shape-rchanges)
|
||||
(concat uchanges shape-uchanges))))))))
|
||||
|
||||
(defn- generate-sync-shape
|
||||
[shape page component]
|
||||
(if (nil? component)
|
||||
(remove-component-and-ref shape page)
|
||||
(let [component-shape (get (:objects component) (:shape-ref shape))]
|
||||
(if (nil? component-shape)
|
||||
(remove-ref shape page)
|
||||
(update-attrs shape component-shape page)))))
|
||||
|
||||
(defn- remove-component-and-ref
|
||||
[shape page]
|
||||
[[{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val nil}]}]
|
||||
[{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val (:component-id shape)}
|
||||
{:type :set
|
||||
:attr :component-file
|
||||
:val (:component-file shape)}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val (:shape-ref shape)}]}]])
|
||||
|
||||
(defn- remove-ref
|
||||
[shape page]
|
||||
[[{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations [{:type :set
|
||||
:attr :shape-ref
|
||||
:val nil}]}]
|
||||
[{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations [{:type :set
|
||||
:attr :shape-ref
|
||||
:val (:shape-ref shape)}]}]])
|
||||
|
||||
(defn- update-attrs
|
||||
[shape component-shape page]
|
||||
(loop [attrs (seq sync-attrs)
|
||||
roperations []
|
||||
uoperations []]
|
||||
(let [attr (first attrs)]
|
||||
(if (nil? attr)
|
||||
(let [rchanges [{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations roperations}]
|
||||
uchanges [{:type :mod-obj
|
||||
:page-id (:id page)
|
||||
:id (:id shape)
|
||||
:operations uoperations}]]
|
||||
[rchanges uchanges])
|
||||
(if-not (contains? shape attr)
|
||||
(recur (next attrs)
|
||||
roperations
|
||||
uoperations)
|
||||
(let [roperation {:type :set
|
||||
:attr attr
|
||||
:val (get component-shape attr)}
|
||||
uoperation {:type :set
|
||||
:attr attr
|
||||
:val (get shape attr)}]
|
||||
(recur (next attrs)
|
||||
(conj roperations roperation)
|
||||
(conj uoperations uoperation))))))))
|
||||
|
||||
(def sync-attrs [:content
|
||||
:fill-color
|
||||
:fill-color-ref-file
|
||||
:fill-color-ref-id
|
||||
:fill-opacity
|
||||
:font-family
|
||||
:font-size
|
||||
:font-style
|
||||
:font-weight
|
||||
:letter-spacing
|
||||
:line-height
|
||||
:proportion
|
||||
:rx
|
||||
:ry
|
||||
:stroke-color
|
||||
:stroke-color-ref-file
|
||||
:stroke-color-ref-id
|
||||
:stroke-opacity
|
||||
:stroke-style
|
||||
:stroke-width
|
||||
:stroke-alignment
|
||||
:text-align
|
||||
:width
|
||||
:height
|
||||
:interactions
|
||||
:points])
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
[{:keys [mdata] :as props}]
|
||||
(let [{:keys [id] :as shape} (:shape mdata)
|
||||
selected (:selected mdata)
|
||||
root-shape (:root-shape mdata)
|
||||
|
||||
do-duplicate #(st/emit! dw/duplicate-selected)
|
||||
do-delete #(st/emit! dw/delete-selected)
|
||||
|
@ -64,7 +65,11 @@
|
|||
do-add-component #(st/emit! dwl/add-component)
|
||||
do-detach-component #(st/emit! (dwl/detach-component id))
|
||||
do-reset-component #(st/emit! (dwl/reset-component id))
|
||||
do-update-component #(st/emit! (dwl/update-component id))]
|
||||
do-update-component #(do
|
||||
(st/emit! (dwl/update-component id))
|
||||
(st/emit! (dwl/sync-file {:file-id nil})))
|
||||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file
|
||||
(:component-file root-shape)))]
|
||||
[:*
|
||||
[:& menu-entry {:title "Copy"
|
||||
:shortcut "Ctrl + c"
|
||||
|
@ -123,8 +128,11 @@
|
|||
:on-click do-detach-component}]
|
||||
[:& menu-entry {:title "Reset overrides"
|
||||
:on-click do-reset-component}]
|
||||
[:& menu-entry {:title "Update master component"
|
||||
:on-click do-update-component}]])
|
||||
(if (nil? (:component-file root-shape))
|
||||
[:& menu-entry {:title "Update master component"
|
||||
:on-click do-update-component}]
|
||||
[:& menu-entry {:title "Go to master component file"
|
||||
:on-click do-navigate-component-file}])])
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title "Delete"
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
(mf/use-callback
|
||||
(mf/deps state)
|
||||
(fn []
|
||||
(let [params {:id (:component-id @state)}]
|
||||
(st/emit! (dwl/delete-component params)))))
|
||||
(st/emit! (dwl/delete-component {:id (:component-id @state)}))
|
||||
(st/emit! (dwl/sync-file {:file-id nil}))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
|
@ -70,7 +70,8 @@
|
|||
on-drag-start
|
||||
(mf/use-callback
|
||||
(fn [component-id event]
|
||||
(dnd/set-data! event "app/component" component-id)
|
||||
(dnd/set-data! event "app/component" {:file-id (if local? nil file-id)
|
||||
:component-id component-id})
|
||||
(dnd/set-allowed-effect! event "move")))]
|
||||
|
||||
[:div.asset-group
|
||||
|
@ -363,26 +364,26 @@
|
|||
|
||||
(mf/defc file-library
|
||||
[{:keys [file local? open? filters locale] :as props}]
|
||||
(let [open? (mf/use-state open?)
|
||||
shared? (:is-shared file)
|
||||
router (mf/deref refs/router)
|
||||
toggle-open #(swap! open? not)
|
||||
(let [open? (mf/use-state open?)
|
||||
shared? (:is-shared file)
|
||||
router (mf/deref refs/router)
|
||||
toggle-open #(swap! open? not)
|
||||
|
||||
toggles (mf/use-state #{:graphics :colors})
|
||||
toggles (mf/use-state #{:graphics :colors})
|
||||
|
||||
url (rt/resolve router :workspace
|
||||
{:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
{:page-id (get-in file [:data :pages 0])})
|
||||
url (rt/resolve router :workspace
|
||||
{:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
{:page-id (get-in file [:data :pages 0])})
|
||||
|
||||
colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file)))
|
||||
colors (apply-filters (mf/deref colors-ref) filters)
|
||||
colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file)))
|
||||
colors (apply-filters (mf/deref colors-ref) filters)
|
||||
|
||||
media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file)))
|
||||
media (apply-filters (mf/deref media-ref) filters)
|
||||
media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file)))
|
||||
media (apply-filters (mf/deref media-ref) filters)
|
||||
|
||||
components-ref (mf/use-memo (mf/deps (:id file)) #(file-components-ref (:id file)))
|
||||
components (apply-filters (mf/deref components-ref) filters)]
|
||||
components-ref (mf/use-memo (mf/deps (:id file)) #(file-components-ref (:id file)))
|
||||
components (apply-filters (mf/deref components-ref) filters)]
|
||||
|
||||
[:div.tool-window
|
||||
[:div.tool-window-bar
|
||||
|
|
|
@ -297,6 +297,8 @@
|
|||
:content
|
||||
:parent-id
|
||||
:component-id
|
||||
:component-file
|
||||
:shape-ref
|
||||
:metadata])]
|
||||
(persistent!
|
||||
(reduce-kv (fn [res id obj]
|
||||
|
|
|
@ -495,8 +495,8 @@
|
|||
(assoc :y final-y)))))
|
||||
|
||||
(dnd/has-type? event "app/component")
|
||||
(let [component-id (dnd/get-data event "app/component")]
|
||||
(st/emit! (dwl/instantiate-component component-id)))
|
||||
(let [{:keys [component-id file-id]} (dnd/get-data event "app/component")]
|
||||
(st/emit! (dwl/instantiate-component file-id component-id)))
|
||||
|
||||
(dnd/has-type? event "text/uri-list")
|
||||
(let [data (dnd/get-data event "text/uri-list")
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[potok.core :as ptk]
|
||||
[reitit.core :as r]
|
||||
[app.common.data :as d]
|
||||
[app.config :as cfg]
|
||||
[app.util.browser-history :as bhistory]
|
||||
[app.util.timers :as ts])
|
||||
(:import
|
||||
|
@ -112,6 +113,19 @@
|
|||
|
||||
(def navigate nav)
|
||||
|
||||
(deftype NavigateNewWindow [id params qparams]
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [router (:router state)
|
||||
path (resolve router id params qparams)
|
||||
uri (str cfg/public-uri "/#" path)]
|
||||
(js/window.open uri "_blank"))))
|
||||
|
||||
(defn nav-new-window
|
||||
([id] (nav-new-window id nil nil))
|
||||
([id params] (nav-new-window id params nil))
|
||||
([id params qparams] (NavigateNewWindow. id params qparams)))
|
||||
|
||||
;; --- History API
|
||||
|
||||
(defn initialize-history
|
||||
|
|
Loading…
Add table
Reference in a new issue