0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-18 21:06:11 -05:00

Simplify changes detection and commit.

With minor code cleaning.
This commit is contained in:
Andrey Antukh 2020-01-21 17:38:07 +01:00
parent 8dd6c8457f
commit 1d726564df
4 changed files with 279 additions and 265 deletions

View file

@ -23,7 +23,6 @@
[uxbox.main.streams :as ms] [uxbox.main.streams :as ms]
[uxbox.main.websockets :as ws] [uxbox.main.websockets :as ws]
[uxbox.main.workers :as uwrk] [uxbox.main.workers :as uwrk]
[uxbox.util.data :refer [dissoc-in index-of]]
[uxbox.util.geom.matrix :as gmt] [uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt] [uxbox.util.geom.point :as gpt]
[uxbox.util.math :as mth] [uxbox.util.math :as mth]
@ -234,6 +233,8 @@
(let [file (get-in state [:files file-id])] (let [file (get-in state [:files file-id])]
(assoc state :workspace-file file))))) (assoc state :workspace-file file)))))
(declare diff-and-commit-changes)
(defn initialize-page (defn initialize-page
[page-id] [page-id]
(ptk/reify ::initialize-page (ptk/reify ::initialize-page
@ -244,6 +245,7 @@
(assoc state (assoc state
:workspace-local workspace-default :workspace-local workspace-default
:workspace-data data :workspace-data data
:workspace-data-prev data
:workspace-page page))) :workspace-page page)))
ptk/WatchEvent ptk/WatchEvent
@ -254,7 +256,7 @@
(->> stream (->> stream
(rx/filter #(satisfies? IBatchedChange %)) (rx/filter #(satisfies? IBatchedChange %))
(rx/debounce 500) (rx/debounce 500)
(rx/map (constantly commit-batched-changes)) (rx/map (constantly diff-and-commit-changes))
(rx/take-until stoper)))))) (rx/take-until stoper))))))
(defn finalize (defn finalize
@ -268,6 +270,29 @@
:workspace-page :workspace-page
:workspace-data)))) :workspace-data))))
(def diff-and-commit-changes
(ptk/reify ::diff-and-commit-changes
ptk/WatchEvent
(watch [_ state stream]
(let [curr (get-in state [:workspace-data :shapes-by-id])
prev (get-in state [:workspace-data-prev :shapes-by-id])
diff (d/diff-maps prev curr)
changes (loop [scs (rest diff)
sc (first diff)
res []]
(if (nil? sc)
res
(let [[_ id shape] sc]
(recur (rest scs)
(first scs)
(conj res {:type :mod-shape
:session-id (:session-id state)
:operations (d/diff-maps (get prev id) shape)
:id id})))))]
(when-not (empty? changes)
(rx/of (commit-changes changes)))))))
;; --- Fetch Workspace Users ;; --- Fetch Workspace Users
(declare users-fetched) (declare users-fetched)
@ -465,7 +490,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [increase #(nth c/zoom-levels (let [increase #(nth c/zoom-levels
(+ (index-of c/zoom-levels %) 1) (+ (d/index-of c/zoom-levels %) 1)
(last c/zoom-levels))] (last c/zoom-levels))]
(update-in state [:workspace-local :zoom] (fnil increase 1)))))) (update-in state [:workspace-local :zoom] (fnil increase 1))))))
@ -474,7 +499,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [decrease #(nth c/zoom-levels (let [decrease #(nth c/zoom-levels
(- (index-of c/zoom-levels %) 1) (- (d/index-of c/zoom-levels %) 1)
(first c/zoom-levels))] (first c/zoom-levels))]
(update-in state [:workspace-local :zoom] (fnil decrease 1)))))) (update-in state [:workspace-local :zoom] (fnil decrease 1))))))
@ -632,11 +657,7 @@
(fn [selected] (fn [selected]
(if (contains? selected id) (if (contains? selected id)
(disj selected id) (disj selected id)
(conj selected id))))) (conj selected id)))))))
ptk/WatchEvent
(watch [_ state s]
(rx/of (activate-flag :element-options)))))
(def deselect-all (def deselect-all
"Clear all possible state of drawing, edition "Clear all possible state of drawing, edition
@ -694,16 +715,7 @@
IBatchedChange IBatchedChange
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [shape-old (get-in state [:workspace-data :shapes-by-id id]) (update-in state [:workspace-data :shapes-by-id id] merge attrs))))
shape-new (merge shape-old attrs)
operations (d/diff-maps shape-old shape-new)
change {:type :mod-shape
:session-id (:session-id state)
:operations operations
:id id}]
(-> state
(assoc-in [:workspace-data :shapes-by-id id] shape-new)
(update ::batched-changes (fnil conj []) change))))))
;; --- Update Page Options ;; --- Update Page Options
@ -714,15 +726,7 @@
IBatchedChange IBatchedChange
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [opts-old (get-in state [:workspace-data :options]) (update-in state [:workspace-data :options] merge opts))))
opts-new (merge opts-old opts)
operations (d/diff-maps opts-old opts-new)
change {:type :mod-opts
:session-id (:session-id state)
:operations operations}]
(-> state
(assoc-in [:workspace-data :options] opts-new)
(update ::batched-changes (fnil conj []) change))))))
;; --- Update Selected Shapes attrs ;; --- Update Selected Shapes attrs
@ -787,16 +791,15 @@
;; --- Delete Selected ;; --- Delete Selected
(defn impl-dissoc-shape (defn impl-dissoc-shape
"Given a shape, removes it from the state." "Given a shape id, removes it from the state."
[state id] [id]
(ptk/reify ::impl-dissoc-shape
ptk/UpdateEvent
(update [_ state]
(-> state (-> state
(update-in [:workspace-data :canvas] (fn [items] (filterv #(not= % id) items))) (update-in [:workspace-data :canvas] (fn [items] (filterv #(not= % id) items)))
(update-in [:workspace-data :shapes] (fn [items] (filterv #(not= % id) items))) (update-in [:workspace-data :shapes] (fn [items] (filterv #(not= % id) items)))
(update-in [:workspace-data :shapes-by-id] dissoc id))) (update-in [:workspace-data :shapes-by-id] dissoc id)))))
(defn impl-lookup-shape
[state id]
(get-in state [:workspace-data :shapes-by-id id]))
(def delete-selected (def delete-selected
"Deselect all and remove all selected shapes." "Deselect all and remove all selected shapes."
@ -813,9 +816,9 @@
{:type (if (= type :canvas) :del-canvas :del-shape) {:type (if (= type :canvas) :del-canvas :del-shape)
:session-id session-id :session-id session-id
:id id})))] :id id})))]
(rx/merge (rx/concat
(rx/of deselect-all) (rx/of deselect-all)
(rx/from (map (fn [id] #(impl-dissoc-shape % id)) selected)) (rx/from (map impl-dissoc-shape selected))
(rx/of (commit-changes changes))))))) (rx/of (commit-changes changes)))))))
;; --- Rename Shape ;; --- Rename Shape
@ -846,6 +849,7 @@
[loc] [loc]
(us/assert ::direction loc) (us/assert ::direction loc)
(ptk/reify ::move-selected-layer (ptk/reify ::move-selected-layer
IBatchedChange
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [id (first (get-in state [:workspace-local :selected])) (let [id (first (get-in state [:workspace-local :selected]))
@ -860,8 +864,8 @@
(let [shapes (get-in state [:workspace-data :shapes]) (let [shapes (get-in state [:workspace-data :shapes])
index (case opt index (case opt
:top 0 :top 0
:down (min (- (count shapes) 1) (inc (index-of shapes sid))) :down (min (- (count shapes) 1) (inc (d/index-of shapes sid)))
:up (max 0 (- (index-of shapes sid) 1)) :up (max 0 (- (d/index-of shapes sid) 1))
:bottom (- (count shapes) 1))] :bottom (- (count shapes) 1))]
(update-in state [:workspace-data :shapes] (update-in state [:workspace-data :shapes]
(fn [items] (fn [items]
@ -977,16 +981,8 @@
xfmt (or (:modifier-mtx shape) (gmt/matrix)) xfmt (or (:modifier-mtx shape) (gmt/matrix))
shape-old (dissoc shape :modifier-mtx) shape-old (dissoc shape :modifier-mtx)
shape-new (geom/transform shape-old xfmt) shape-new (geom/transform shape-old xfmt)
shape-new (recalculate-shape-canvas-relation state shape-new) shape-new (recalculate-shape-canvas-relation state shape-new)]
operations (d/diff-maps shape-old shape-new) (assoc-in state [:workspace-data :shapes-by-id id] shape-new)))]
change {:type :mod-shape
:session-id (:session-id state)
:operations operations
:id id}]
(-> state
(assoc-in [:workspace-data :shapes-by-id id] shape-new)
(update ::batched-changes (fnil conj []) change))))]
(ptk/reify ::materialize-temporal-modifier-in-bulk (ptk/reify ::materialize-temporal-modifier-in-bulk
IBatchedChange IBatchedChange
ptk/UpdateEvent ptk/UpdateEvent
@ -1001,7 +997,9 @@
(update [_ state] (update [_ state]
(let [pid (get-in state [:workspace-page :id]) (let [pid (get-in state [:workspace-page :id])
data (get-in state [:pages-data pid])] data (get-in state [:pages-data pid])]
(update-in state [:pages-data pid] cp/process-changes changes))) (-> state
(update-in [:pages-data pid] cp/process-changes changes)
(assoc :workspace-data-prev (:workspace-data state)))))
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
@ -1059,7 +1057,7 @@
(->> stream (->> stream
(rx/filter #(= % :interrupt)) (rx/filter #(= % :interrupt))
(rx/take 1) (rx/take 1)
(rx/map (fn [_] #(dissoc-in % [:workspace-local :edition]))))))) (rx/map (fn [_] #(d/dissoc-in % [:workspace-local :edition])))))))
;; --- Select for Drawing ;; --- Select for Drawing
@ -1106,16 +1104,7 @@
IBatchedChange IBatchedChange
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [shape-old (get-in state [:workspace-data :shapes-by-id id]) (update-in state [:workspace-data :shapes-by-id id] geom/resize-dim dimensions))))
shape-new (geom/resize-dim shape-old dimensions)
operations (d/diff-maps shape-old shape-new)
change {:type :mod-shape
:session-id (:session-id state)
:operations operations
:id id}]
(-> state
(assoc-in [:workspace-data :shapes-by-id id] shape-new)
(update ::batched-changes (fnil conj []) change))))))
;; --- Shape Proportions ;; --- Shape Proportions
@ -1143,21 +1132,20 @@
;; --- Path Modifications ;; --- Path Modifications
;; TODO: revisit
(deftype UpdatePath [id index delta]
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-data :shapes-by-id id :segments index] gpt/add delta)))
(defn update-path (defn update-path
"Update a concrete point in the path shape." "Update a concrete point in the path shape."
[id index delta] [id index delta]
{:pre [(uuid? id) (number? index) (gpt/point? delta)]} (us/assert ::us/uuid id)
(UpdatePath. id index delta)) (us/assert ::us/integer index)
(us/assert gpt/point? delta)
(ptk/reify ::update-path
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-data :shapes-by-id id :segments index] gpt/add delta))))
;; --- Initial Path Point Alignment ;; --- Initial Path Point Alignment
;; TODO: revisit ;; TODO: revisit on alignemt refactor
(deftype InitialPathPointAlign [id index] (deftype InitialPathPointAlign [id index]
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
@ -1177,88 +1165,71 @@
;; --- Shape Visibility ;; --- Shape Visibility
;; TODO: revisit (declare impl-update-shape-hidden)
(defn set-hidden-attr
[id value] (defn hide-shape
[id]
(us/assert ::us/uuid id) (us/assert ::us/uuid id)
(us/assert ::us/boolean value) (ptk/reify ::hide-shape
(letfn [(impl-set-hidden [state id]
(let [{:keys [type] :as shape} (get-in state [:shapes id])]
(as-> state $
(assoc-in $ [:shapes id :hidden] value)
(if (= :canvas type)
(let [shapes (get-in state [:pages (:page shape) :shapes])
xform (comp (map #(get-in state [:shapes %]))
(filter #(= id (:canvas %)))
(map :id))]
(reduce impl-set-hidden $ (sequence xform shapes)))
$))))]
(ptk/reify ::set-hidden-attr
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(impl-set-hidden state id))))) (impl-update-shape-hidden state id true))))
(defn show-shape
[id]
(us/assert ::us/uuid id)
(ptk/reify ::hide-shape
ptk/UpdateEvent
(update [_ state]
(impl-update-shape-hidden state id false))))
(defn- impl-update-shape-hidden
[state id hidden?]
(let [type (get-in state [:workspace-data :shapes-by-id id :type])
state (update-in state [:workspace-data :shapes-by-id id] assoc :hidden hidden?)]
(cond-> state
(= type :canvas)
(update-in [:workspace-data :shapes-by-id]
(fn [shapes]
(reduce-kv (fn [shapes key {:keys [canvas] :as val}]
(cond-> shapes
(= id canvas) (update key assoc :hidden hidden?)))
shapes
shapes))))))
;; --- Shape Blocking ;; --- Shape Blocking
;; TODO: revisit (declare impl-update-shape-blocked)
(defn set-blocked-attr
[id value] (defn block-shape
[id]
(us/assert ::us/uuid id) (us/assert ::us/uuid id)
(us/assert ::us/boolean value) (ptk/reify ::hide-shape
(letfn [(impl-set-blocked [state id]
(let [{:keys [type] :as shape} (get-in state [:shapes id])]
(as-> state $
(assoc-in $ [:shapes id :blocked] value)
(if (= :canvas type)
(let [shapes (get-in state [:pages (:page shape) :shapes])
xform (comp (map #(get-in state [:shapes %]))
(filter #(= id (:canvas %)))
(map :id))]
(reduce impl-set-blocked $ (sequence xform shapes)))
$))))]
(ptk/reify ::set-blocked-attr
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(impl-set-blocked state id))))) (impl-update-shape-blocked state id true))))
;; --- Shape Locking (defn unblock-shape
;; TODO: revisit
(deftype LockShape [id]
ptk/UpdateEvent
(update [_ state]
(letfn [(mark-locked [state id]
(let [shape (get-in state [:shapes id])]
(if (= :group (:type shape))
(as-> state $
(assoc-in $ [:shapes id :locked] true)
(reduce mark-locked $ (:items shape)))
(assoc-in state [:shapes id :locked] true))))]
(mark-locked state id))))
;; TODO: revisit
(defn lock-shape
[id] [id]
{:pre [(uuid? id)]} (us/assert ::us/uuid id)
(LockShape. id)) (ptk/reify ::hide-shape
(deftype UnlockShape [id]
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(letfn [(mark-unlocked [state id] (impl-update-shape-blocked state id false))))
(let [shape (get-in state [:shapes id])]
(if (= :group (:type shape))
(as-> state $
(assoc-in $ [:shapes id :locked] false)
(reduce mark-unlocked $ (:items shape)))
(assoc-in state [:shapes id :locked] false))))]
(mark-unlocked state id))))
;; TODO: revisit (defn- impl-update-shape-blocked
(defn unlock-shape [state id hidden?]
[id] (let [type (get-in state [:workspace-data :shapes-by-id id :type])
{:pre [(uuid? id)]} state (update-in state [:workspace-data :shapes-by-id id] assoc :blocked hidden?)]
(UnlockShape. id)) (cond-> state
(= type :canvas)
(update-in [:workspace-data :shapes-by-id]
(fn [shapes]
(reduce-kv (fn [shapes key {:keys [canvas] :as val}]
(cond-> shapes
(= id canvas) (update key assoc :blocked hidden?)))
shapes
shapes))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Canvas Interactions ;; Canvas Interactions

View file

@ -29,7 +29,7 @@
(fn [own props] (fn [own props]
[] []
(letfn [(on-paste [item] (letfn [(on-paste [item]
(st/emit! (udw/paste-from-clipboard (:id item))) #_(st/emit! (udw/paste-from-clipboard (:id item)))
(udl/close!)) (udl/close!))
(on-close [event] (on-close [event]
(dom/prevent-default event) (dom/prevent-default event)

View file

@ -2,13 +2,17 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; 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/. ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;; ;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com> ;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz> ;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.ui.workspace.sidebar.layers (ns uxbox.main.ui.workspace.sidebar.layers
(:require (:require
[lentes.core :as l] [lentes.core :as l]
[rumext.alpha :as mf] [rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.builtins.icons :as i] [uxbox.builtins.icons :as i]
[uxbox.main.data.workspace :as dw] [uxbox.main.data.workspace :as dw]
[uxbox.main.refs :as refs] [uxbox.main.refs :as refs]
@ -16,7 +20,6 @@
[uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.shapes.icon :as icon] [uxbox.main.ui.shapes.icon :as icon]
[uxbox.main.ui.workspace.sortable :refer [use-sortable]] [uxbox.main.ui.workspace.sortable :refer [use-sortable]]
[uxbox.util.data :refer [classnames enumerate]]
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t]])) [uxbox.util.i18n :as i18n :refer [t]]))
@ -77,18 +80,25 @@
(mf/defc layer-item (mf/defc layer-item
[{:keys [shape selected index] :as props}] [{:keys [shape selected index] :as props}]
;; (prn "layer-item" index (:name shape)) (let [selected? (contains? selected (:id shape))
(letfn [(toggle-blocking [event]
(dom/stop-propagation event)
(let [{:keys [id blocked]} shape]
(st/emit! (dw/set-blocked-attr id (not blocked)))))
(toggle-visibility [event] toggle-blocking
(fn [event]
(prn "toggle-blocking" (:blocked shape))
(dom/stop-propagation event) (dom/stop-propagation event)
(let [{:keys [id hidden]} shape] (if (:blocked shape)
(st/emit! (dw/set-hidden-attr id (not hidden))))) (st/emit! (dw/unblock-shape (:id shape)))
(st/emit! (dw/block-shape (:id shape)))))
(select-shape [event] toggle-visibility
(fn [event]
(dom/stop-propagation event)
(if (:hidden shape)
(st/emit! (dw/show-shape (:id shape)))
(st/emit! (dw/hide-shape (:id shape)))))
select-shape
(fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(let [id (:id shape)] (let [id (:id shape)]
(cond (cond
@ -106,12 +116,14 @@
(st/emit! dw/deselect-all (st/emit! dw/deselect-all
(dw/select-shape id))))) (dw/select-shape id)))))
(on-drop [item monitor] on-drop
(fn [item monitor]
(st/emit! dw/commit-shape-order-change)) (st/emit! dw/commit-shape-order-change))
(on-hover [item monitor] on-hover
(st/emit! (dw/temporal-shape-order-change (:shape-id item) index)))] (fn [item monitor]
(let [selected? (contains? selected (:id shape)) (st/emit! (dw/temporal-shape-order-change (:shape-id item) index)))
[dprops dnd-ref] (use-sortable [dprops dnd-ref] (use-sortable
{:type "layer-item" {:type "layer-item"
:data {:shape-id (:id shape) :data {:shape-id (:id shape)
@ -120,10 +132,10 @@
:on-hover on-hover :on-hover on-hover
:on-drop on-drop})] :on-drop on-drop})]
[:li {:ref dnd-ref [:li {:ref dnd-ref
:class (classnames :class (dom/classnames
:selected selected? :selected selected?
:dragging-TODO (:dragging? dprops))} :dragging-TODO (:dragging? dprops))}
[:div.element-list-body {:class (classnames :selected selected?) [:div.element-list-body {:class (dom/classnames :selected selected?)
:on-click select-shape :on-click select-shape
:on-double-click #(dom/stop-propagation %)} :on-double-click #(dom/stop-propagation %)}
[:div.element-actions [:div.element-actions
@ -134,21 +146,37 @@
:on-click toggle-blocking} :on-click toggle-blocking}
i/lock]] i/lock]]
[:div.element-icon (element-icon shape)] [:div.element-icon (element-icon shape)]
[:& layer-name {:shape shape}]]]))) [:& layer-name {:shape shape}]]]))
(mf/defc canvas-item (mf/defc canvas-item
[{:keys [canvas shapes selected index] :as props}] [{:keys [canvas shapes selected index] :as props}]
(letfn [(toggle-blocking [event] (let [selected? (contains? selected (:id canvas))
(dom/stop-propagation event) local (mf/use-state {:collapsed false})
(let [{:keys [id blocked]} canvas] collapsed? (:collapsed @local)
(st/emit! (dw/set-blocked-attr id (not blocked)))))
(toggle-visibility [event] shapes (filter #(= (:canvas (second %)) (:id canvas)) shapes)
(dom/stop-propagation event)
(let [{:keys [id hidden]} canvas]
(st/emit! (dw/set-hidden-attr id (not hidden)))))
(select-shape [event] toggle-collapse
(fn [event]
(dom/stop-propagation event)
(swap! local update :collapsed not))
toggle-blocking
(fn [event]
(dom/stop-propagation event)
(if (:blocked canvas)
(st/emit! (dw/unblock-shape (:id canvas)))
(st/emit! (dw/block-shape (:id canvas)))))
toggle-visibility
(fn [event]
(dom/stop-propagation event)
(if (:hidden canvas)
(st/emit! (dw/show-shape (:id canvas)))
(st/emit! (dw/hide-shape (:id canvas)))))
select-shape
(fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(let [id (:id canvas)] (let [id (:id canvas)]
(cond (cond
@ -166,16 +194,15 @@
(st/emit! dw/deselect-all (st/emit! dw/deselect-all
(dw/select-shape id))))) (dw/select-shape id)))))
(on-drop [item monitor] on-drop
(fn [item monitor]
(st/emit! ::dw/page-data-update)) (st/emit! ::dw/page-data-update))
(on-hover [item monitor] on-hover
(fn [item monitor]
(st/emit! (dw/change-canvas-order {:id (:canvas-id item) (st/emit! (dw/change-canvas-order {:id (:canvas-id item)
:index index})))] :index index})))
(let [selected? (contains? selected (:id canvas))
collapsed? (:collapsed canvas false)
shapes (filter #(= (:canvas (second %)) (:id canvas)) shapes)
[dprops dnd-ref] (use-sortable [dprops dnd-ref] (use-sortable
{:type "canvas-item" {:type "canvas-item"
:data {:canvas-id (:id canvas) :data {:canvas-id (:id canvas)
@ -184,31 +211,32 @@
:on-hover on-hover :on-hover on-hover
:on-drop on-drop})] :on-drop on-drop})]
[:li.group {:ref dnd-ref [:li.group {:ref dnd-ref
:class (classnames :class (dom/classnames
:selected selected? :selected selected?
:dragging-TODO (:dragging? dprops))} :dragging-TODO (:dragging? dprops))}
[:div.element-list-body {:class (classnames :selected selected?) [:div.element-list-body {:class (dom/classnames :selected selected?)
:on-click select-shape :on-click select-shape
:on-double-click #(dom/stop-propagation %)} :on-double-click #(dom/stop-propagation %)}
[:div.element-actions [:div.element-actions
[:div.toggle-element {:class (when-not (:hidden canvas) "selected") [:div.toggle-element {:class (when-not (:hidden canvas) "selected")
:on-click toggle-visibility} :on-click toggle-visibility}
i/eye] i/eye]
[:div.block-element {:class (when (:blocked canvas) "selected") #_[:div.block-element {:class (when (:blocked canvas) "selected")
:on-click toggle-blocking} :on-click toggle-blocking}
i/lock]] i/lock]]
[:div.element-icon i/folder] [:div.element-icon i/folder]
[:& layer-name {:shape canvas}] [:& layer-name {:shape canvas}]
[:span.toggle-content [:span.toggle-content
{ ;; :on-click toggle-collapse {:on-click toggle-collapse
:class (when-not collapsed? "inverse")} :class (when-not collapsed? "inverse")}
i/arrow-slide]] i/arrow-slide]]
(when-not collapsed?
[:ul [:ul
(for [[index shape] (reverse shapes)] (for [[index shape] (reverse shapes)]
[:& layer-item {:shape shape [:& layer-item {:shape shape
:selected selected :selected selected
:index index :index index
:key (:id shape)}])]]))) :key (:id shape)}])])]))
;; --- Layers List ;; --- Layers List
@ -245,15 +273,15 @@
canvas (->> (:canvas data) canvas (->> (:canvas data)
(map #(get shapes-by-id %)) (map #(get shapes-by-id %))
(enumerate)) (d/enumerate))
shapes (->> (:shapes data) shapes (->> (:shapes data)
(map #(get shapes-by-id %))) (map #(get shapes-by-id %)))
all-shapes (enumerate shapes) all-shapes (d/enumerate shapes)
unc-shapes (->> shapes unc-shapes (->> shapes
(filter #(nil? (:canvas %))) (filter #(nil? (:canvas %)))
(enumerate))] (d/enumerate))]
[:div#layers.tool-window [:div#layers.tool-window
[:div.tool-window-bar [:div.tool-window-bar

View file

@ -2,11 +2,16 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; 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/. ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;; ;;
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz> ;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com> ;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.util.dom (ns uxbox.util.dom
(:require [goog.dom :as dom])) (:require
[goog.dom :as dom]
[cuerdas.core :as str]))
;; --- Deprecated methods ;; --- Deprecated methods
@ -22,6 +27,16 @@
[e] [e]
(.-target e)) (.-target e))
(defn classnames
[& params]
(assert (even? (count params)))
(str/join " " (reduce (fn [acc [k v]]
(if (true? v)
(conj acc (name k))
acc))
[]
(partition 2 params))))
;; --- New methods ;; --- New methods
(defn get-element-by-class (defn get-element-by-class