diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index ad7514235..cd5727571 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -23,7 +23,6 @@ [uxbox.main.streams :as ms] [uxbox.main.websockets :as ws] [uxbox.main.workers :as uwrk] - [uxbox.util.data :refer [dissoc-in index-of]] [uxbox.util.geom.matrix :as gmt] [uxbox.util.geom.point :as gpt] [uxbox.util.math :as mth] @@ -234,6 +233,8 @@ (let [file (get-in state [:files file-id])] (assoc state :workspace-file file))))) +(declare diff-and-commit-changes) + (defn initialize-page [page-id] (ptk/reify ::initialize-page @@ -244,6 +245,7 @@ (assoc state :workspace-local workspace-default :workspace-data data + :workspace-data-prev data :workspace-page page))) ptk/WatchEvent @@ -254,7 +256,7 @@ (->> stream (rx/filter #(satisfies? IBatchedChange %)) (rx/debounce 500) - (rx/map (constantly commit-batched-changes)) + (rx/map (constantly diff-and-commit-changes)) (rx/take-until stoper)))))) (defn finalize @@ -268,6 +270,29 @@ :workspace-page :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 (declare users-fetched) @@ -465,7 +490,7 @@ ptk/UpdateEvent (update [_ state] (let [increase #(nth c/zoom-levels - (+ (index-of c/zoom-levels %) 1) + (+ (d/index-of c/zoom-levels %) 1) (last c/zoom-levels))] (update-in state [:workspace-local :zoom] (fnil increase 1)))))) @@ -474,7 +499,7 @@ ptk/UpdateEvent (update [_ state] (let [decrease #(nth c/zoom-levels - (- (index-of c/zoom-levels %) 1) + (- (d/index-of c/zoom-levels %) 1) (first c/zoom-levels))] (update-in state [:workspace-local :zoom] (fnil decrease 1)))))) @@ -632,11 +657,7 @@ (fn [selected] (if (contains? selected id) (disj selected id) - (conj selected id))))) - - ptk/WatchEvent - (watch [_ state s] - (rx/of (activate-flag :element-options))))) + (conj selected id))))))) (def deselect-all "Clear all possible state of drawing, edition @@ -694,16 +715,7 @@ IBatchedChange ptk/UpdateEvent (update [_ state] - (let [shape-old (get-in state [:workspace-data :shapes-by-id id]) - 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-in state [:workspace-data :shapes-by-id id] merge attrs)))) ;; --- Update Page Options @@ -714,15 +726,7 @@ IBatchedChange ptk/UpdateEvent (update [_ state] - (let [opts-old (get-in state [:workspace-data :options]) - 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-in state [:workspace-data :options] merge opts)))) ;; --- Update Selected Shapes attrs @@ -787,16 +791,15 @@ ;; --- Delete Selected (defn impl-dissoc-shape - "Given a shape, removes it from the state." - [state id] - (-> state - (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-by-id] dissoc id))) - -(defn impl-lookup-shape - [state id] - (get-in state [:workspace-data :shapes-by-id id])) + "Given a shape id, removes it from the state." + [id] + (ptk/reify ::impl-dissoc-shape + ptk/UpdateEvent + (update [_ state] + (-> state + (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-by-id] dissoc id))))) (def delete-selected "Deselect all and remove all selected shapes." @@ -813,9 +816,9 @@ {:type (if (= type :canvas) :del-canvas :del-shape) :session-id session-id :id id})))] - (rx/merge + (rx/concat (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))))))) ;; --- Rename Shape @@ -846,6 +849,7 @@ [loc] (us/assert ::direction loc) (ptk/reify ::move-selected-layer + IBatchedChange ptk/UpdateEvent (update [_ state] (let [id (first (get-in state [:workspace-local :selected])) @@ -860,8 +864,8 @@ (let [shapes (get-in state [:workspace-data :shapes]) index (case opt :top 0 - :down (min (- (count shapes) 1) (inc (index-of shapes sid))) - :up (max 0 (- (index-of shapes sid) 1)) + :down (min (- (count shapes) 1) (inc (d/index-of shapes sid))) + :up (max 0 (- (d/index-of shapes sid) 1)) :bottom (- (count shapes) 1))] (update-in state [:workspace-data :shapes] (fn [items] @@ -977,16 +981,8 @@ xfmt (or (:modifier-mtx shape) (gmt/matrix)) shape-old (dissoc shape :modifier-mtx) shape-new (geom/transform shape-old xfmt) - shape-new (recalculate-shape-canvas-relation state shape-new) - 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-new (recalculate-shape-canvas-relation state shape-new)] + (assoc-in state [:workspace-data :shapes-by-id id] shape-new)))] (ptk/reify ::materialize-temporal-modifier-in-bulk IBatchedChange ptk/UpdateEvent @@ -1001,7 +997,9 @@ (update [_ state] (let [pid (get-in state [:workspace-page :id]) 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 (watch [_ state stream] @@ -1059,7 +1057,7 @@ (->> stream (rx/filter #(= % :interrupt)) (rx/take 1) - (rx/map (fn [_] #(dissoc-in % [:workspace-local :edition]))))))) + (rx/map (fn [_] #(d/dissoc-in % [:workspace-local :edition]))))))) ;; --- Select for Drawing @@ -1106,16 +1104,7 @@ IBatchedChange ptk/UpdateEvent (update [_ state] - (let [shape-old (get-in state [:workspace-data :shapes-by-id id]) - 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)))))) + (update-in state [:workspace-data :shapes-by-id id] geom/resize-dim dimensions)))) ;; --- Shape Proportions @@ -1143,21 +1132,20 @@ ;; --- 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 "Update a concrete point in the path shape." [id index delta] - {:pre [(uuid? id) (number? index) (gpt/point? delta)]} - (UpdatePath. id index delta)) + (us/assert ::us/uuid id) + (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 -;; TODO: revisit +;; TODO: revisit on alignemt refactor (deftype InitialPathPointAlign [id index] ptk/WatchEvent (watch [_ state s] @@ -1177,88 +1165,71 @@ ;; --- Shape Visibility -;; TODO: revisit -(defn set-hidden-attr - [id value] +(declare impl-update-shape-hidden) + +(defn hide-shape + [id] (us/assert ::us/uuid id) - (us/assert ::us/boolean value) - (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 - (update [_ state] - (impl-set-hidden state id))))) + (ptk/reify ::hide-shape + ptk/UpdateEvent + (update [_ state] + (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 -;; TODO: revisit -(defn set-blocked-attr - [id value] +(declare impl-update-shape-blocked) + +(defn block-shape + [id] (us/assert ::us/uuid id) - (us/assert ::us/boolean value) - (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 - (update [_ state] - (impl-set-blocked state id))))) + (ptk/reify ::hide-shape + ptk/UpdateEvent + (update [_ state] + (impl-update-shape-blocked state id true)))) -;; --- Shape Locking - -;; 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 +(defn unblock-shape [id] - {:pre [(uuid? id)]} - (LockShape. id)) + (us/assert ::us/uuid id) + (ptk/reify ::hide-shape + ptk/UpdateEvent + (update [_ state] + (impl-update-shape-blocked state id false)))) -(deftype UnlockShape [id] - ptk/UpdateEvent - (update [_ state] - (letfn [(mark-unlocked [state id] - (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 unlock-shape - [id] - {:pre [(uuid? id)]} - (UnlockShape. id)) +(defn- impl-update-shape-blocked + [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 :blocked 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 :blocked hidden?))) + shapes + shapes)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Canvas Interactions diff --git a/frontend/src/uxbox/main/ui/workspace/clipboard.cljs b/frontend/src/uxbox/main/ui/workspace/clipboard.cljs index 8074f5ec6..41fe520c4 100644 --- a/frontend/src/uxbox/main/ui/workspace/clipboard.cljs +++ b/frontend/src/uxbox/main/ui/workspace/clipboard.cljs @@ -29,7 +29,7 @@ (fn [own props] [] (letfn [(on-paste [item] - (st/emit! (udw/paste-from-clipboard (:id item))) + #_(st/emit! (udw/paste-from-clipboard (:id item))) (udl/close!)) (on-close [event] (dom/prevent-default event) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs index e98fbbeb9..4ddd7a153 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs @@ -2,13 +2,17 @@ ;; 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/. ;; +;; 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 -;; Copyright (c) 2015-2019 Andrey Antukh +;; Copyright (c) 2015-2020 Andrey Antukh (ns uxbox.main.ui.workspace.sidebar.layers (:require [lentes.core :as l] [rumext.alpha :as mf] + [uxbox.common.data :as d] [uxbox.builtins.icons :as i] [uxbox.main.data.workspace :as dw] [uxbox.main.refs :as refs] @@ -16,7 +20,6 @@ [uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.shapes.icon :as icon] [uxbox.main.ui.workspace.sortable :refer [use-sortable]] - [uxbox.util.data :refer [classnames enumerate]] [uxbox.util.dom :as dom] [uxbox.util.i18n :as i18n :refer [t]])) @@ -77,138 +80,163 @@ (mf/defc layer-item [{:keys [shape selected index] :as props}] - ;; (prn "layer-item" index (:name shape)) - (letfn [(toggle-blocking [event] - (dom/stop-propagation event) - (let [{:keys [id blocked]} shape] - (st/emit! (dw/set-blocked-attr id (not blocked))))) + (let [selected? (contains? selected (:id shape)) - (toggle-visibility [event] - (dom/stop-propagation event) - (let [{:keys [id hidden]} shape] - (st/emit! (dw/set-hidden-attr id (not hidden))))) + toggle-blocking + (fn [event] + (prn "toggle-blocking" (:blocked shape)) + (dom/stop-propagation event) + (if (:blocked shape) + (st/emit! (dw/unblock-shape (:id shape))) + (st/emit! (dw/block-shape (:id shape))))) - (select-shape [event] - (dom/prevent-default event) - (let [id (:id shape)] - (cond - (or (:blocked shape) - (:hidden shape)) - nil + 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))))) - (.-ctrlKey event) - (st/emit! (dw/select-shape id)) + select-shape + (fn [event] + (dom/prevent-default event) + (let [id (:id shape)] + (cond + (or (:blocked shape) + (:hidden shape)) + nil - (> (count selected) 1) - (st/emit! dw/deselect-all - (dw/select-shape id)) - :else - (st/emit! dw/deselect-all - (dw/select-shape id))))) + (.-ctrlKey event) + (st/emit! (dw/select-shape id)) - (on-drop [item monitor] - (st/emit! dw/commit-shape-order-change)) + (> (count selected) 1) + (st/emit! dw/deselect-all + (dw/select-shape id)) + :else + (st/emit! dw/deselect-all + (dw/select-shape id))))) - (on-hover [item monitor] - (st/emit! (dw/temporal-shape-order-change (:shape-id item) index)))] - (let [selected? (contains? selected (:id shape)) - [dprops dnd-ref] (use-sortable - {:type "layer-item" - :data {:shape-id (:id shape) - :page-id (:page shape) - :index index} - :on-hover on-hover - :on-drop on-drop})] - [:li {:ref dnd-ref - :class (classnames - :selected selected? - :dragging-TODO (:dragging? dprops))} - [:div.element-list-body {:class (classnames :selected selected?) - :on-click select-shape - :on-double-click #(dom/stop-propagation %)} - [:div.element-actions - [:div.toggle-element {:class (when-not (:hidden shape) "selected") - :on-click toggle-visibility} - i/eye] - [:div.block-element {:class (when (:blocked shape) "selected") - :on-click toggle-blocking} - i/lock]] - [:div.element-icon (element-icon shape)] - [:& layer-name {:shape shape}]]]))) + on-drop + (fn [item monitor] + (st/emit! dw/commit-shape-order-change)) + + on-hover + (fn [item monitor] + (st/emit! (dw/temporal-shape-order-change (:shape-id item) index))) + + [dprops dnd-ref] (use-sortable + {:type "layer-item" + :data {:shape-id (:id shape) + :page-id (:page shape) + :index index} + :on-hover on-hover + :on-drop on-drop})] + [:li {:ref dnd-ref + :class (dom/classnames + :selected selected? + :dragging-TODO (:dragging? dprops))} + [:div.element-list-body {:class (dom/classnames :selected selected?) + :on-click select-shape + :on-double-click #(dom/stop-propagation %)} + [:div.element-actions + [:div.toggle-element {:class (when-not (:hidden shape) "selected") + :on-click toggle-visibility} + i/eye] + [:div.block-element {:class (when (:blocked shape) "selected") + :on-click toggle-blocking} + i/lock]] + [:div.element-icon (element-icon shape)] + [:& layer-name {:shape shape}]]])) (mf/defc canvas-item [{:keys [canvas shapes selected index] :as props}] - (letfn [(toggle-blocking [event] - (dom/stop-propagation event) - (let [{:keys [id blocked]} canvas] - (st/emit! (dw/set-blocked-attr id (not blocked))))) + (let [selected? (contains? selected (:id canvas)) + local (mf/use-state {:collapsed false}) + collapsed? (:collapsed @local) - (toggle-visibility [event] - (dom/stop-propagation event) - (let [{:keys [id hidden]} canvas] - (st/emit! (dw/set-hidden-attr id (not hidden))))) + shapes (filter #(= (:canvas (second %)) (:id canvas)) shapes) - (select-shape [event] - (dom/prevent-default event) - (let [id (:id canvas)] - (cond - (or (:blocked canvas) - (:hidden canvas)) - nil + toggle-collapse + (fn [event] + (dom/stop-propagation event) + (swap! local update :collapsed not)) - (.-ctrlKey event) - (st/emit! (dw/select-shape id)) + 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))))) - (> (count selected) 1) - (st/emit! dw/deselect-all - (dw/select-shape id)) - :else - (st/emit! dw/deselect-all - (dw/select-shape id))))) + 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))))) - (on-drop [item monitor] - (st/emit! ::dw/page-data-update)) + select-shape + (fn [event] + (dom/prevent-default event) + (let [id (:id canvas)] + (cond + (or (:blocked canvas) + (:hidden canvas)) + nil - (on-hover [item monitor] - (st/emit! (dw/change-canvas-order {:id (:canvas-id item) - :index index})))] - (let [selected? (contains? selected (:id canvas)) - collapsed? (:collapsed canvas false) + (.-ctrlKey event) + (st/emit! (dw/select-shape id)) - shapes (filter #(= (:canvas (second %)) (:id canvas)) shapes) - [dprops dnd-ref] (use-sortable - {:type "canvas-item" - :data {:canvas-id (:id canvas) - :page-id (:page canvas) - :index index} - :on-hover on-hover - :on-drop on-drop})] - [:li.group {:ref dnd-ref - :class (classnames - :selected selected? - :dragging-TODO (:dragging? dprops))} - [:div.element-list-body {:class (classnames :selected selected?) - :on-click select-shape - :on-double-click #(dom/stop-propagation %)} - [:div.element-actions - [:div.toggle-element {:class (when-not (:hidden canvas) "selected") - :on-click toggle-visibility} - i/eye] - [:div.block-element {:class (when (:blocked canvas) "selected") - :on-click toggle-blocking} + (> (count selected) 1) + (st/emit! dw/deselect-all + (dw/select-shape id)) + :else + (st/emit! dw/deselect-all + (dw/select-shape id))))) + + on-drop + (fn [item monitor] + (st/emit! ::dw/page-data-update)) + + on-hover + (fn [item monitor] + (st/emit! (dw/change-canvas-order {:id (:canvas-id item) + :index index}))) + + [dprops dnd-ref] (use-sortable + {:type "canvas-item" + :data {:canvas-id (:id canvas) + :page-id (:page canvas) + :index index} + :on-hover on-hover + :on-drop on-drop})] + [:li.group {:ref dnd-ref + :class (dom/classnames + :selected selected? + :dragging-TODO (:dragging? dprops))} + [:div.element-list-body {:class (dom/classnames :selected selected?) + :on-click select-shape + :on-double-click #(dom/stop-propagation %)} + [:div.element-actions + [:div.toggle-element {:class (when-not (:hidden canvas) "selected") + :on-click toggle-visibility} + i/eye] + #_[:div.block-element {:class (when (:blocked canvas) "selected") + :on-click toggle-blocking} i/lock]] - [:div.element-icon i/folder] - [:& layer-name {:shape canvas}] - [:span.toggle-content - { ;; :on-click toggle-collapse - :class (when-not collapsed? "inverse")} - i/arrow-slide]] + [:div.element-icon i/folder] + [:& layer-name {:shape canvas}] + [:span.toggle-content + {:on-click toggle-collapse + :class (when-not collapsed? "inverse")} + i/arrow-slide]] + (when-not collapsed? [:ul (for [[index shape] (reverse shapes)] [:& layer-item {:shape shape :selected selected :index index - :key (:id shape)}])]]))) + :key (:id shape)}])])])) ;; --- Layers List @@ -245,15 +273,15 @@ canvas (->> (:canvas data) (map #(get shapes-by-id %)) - (enumerate)) + (d/enumerate)) shapes (->> (:shapes data) (map #(get shapes-by-id %))) - all-shapes (enumerate shapes) + all-shapes (d/enumerate shapes) unc-shapes (->> shapes (filter #(nil? (:canvas %))) - (enumerate))] + (d/enumerate))] [:div#layers.tool-window [:div.tool-window-bar diff --git a/frontend/src/uxbox/util/dom.cljs b/frontend/src/uxbox/util/dom.cljs index ebf5f42e9..76737df23 100644 --- a/frontend/src/uxbox/util/dom.cljs +++ b/frontend/src/uxbox/util/dom.cljs @@ -2,11 +2,16 @@ ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; -;; Copyright (c) 2015-2016 Andrey Antukh +;; 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 +;; Copyright (c) 2015-2020 Andrey Antukh (ns uxbox.util.dom - (:require [goog.dom :as dom])) + (:require + [goog.dom :as dom] + [cuerdas.core :as str])) ;; --- Deprecated methods @@ -22,6 +27,16 @@ [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 (defn get-element-by-class