From 8e228be5a0039440a0191dfc477e40632cb59177 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 7 Jan 2020 21:32:41 +0100 Subject: [PATCH] :sparkles: Enable shape d&d ordering persistence. --- common/uxbox/common/data.cljc | 15 +++++++++- common/uxbox/common/pages.cljc | 29 +++++++++++++++++-- frontend/src/uxbox/main/data/workspace.cljs | 22 +++++++++++--- .../main/ui/workspace/sidebar/layers.cljs | 5 ++-- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/common/uxbox/common/data.cljc b/common/uxbox/common/data.cljc index 9fd9d2b20..158537232 100644 --- a/common/uxbox/common/data.cljc +++ b/common/uxbox/common/data.cljc @@ -6,7 +6,7 @@ (ns uxbox.common.data "Data manipulation and query helper functions." - (:refer-clojure :exclude [concat]) + (:refer-clojure :exclude [concat read-string]) (:require [clojure.set :as set] #?(:cljs [cljs.reader :as r] :clj [clojure.edn :as r]))) @@ -74,6 +74,19 @@ (persistent! (reduce #(assoc! %1 (getter %2) %2) (transient {}) coll))) +(defn index-of + [coll v] + (loop [c (first coll) + coll (rest coll) + index 0] + (if (nil? c) + nil + (if (= c v) + index + (recur (first coll) + (rest coll) + (inc index)))))) + (defn remove-nil-vals "Given a map, return a map removing key-value pairs when value is `nil`." diff --git a/common/uxbox/common/pages.cljc b/common/uxbox/common/pages.cljc index 16aa9ca7b..3f6208640 100644 --- a/common/uxbox/common/pages.cljc +++ b/common/uxbox/common/pages.cljc @@ -1,7 +1,8 @@ (ns uxbox.common.pages "A common (clj/cljs) functions and specs for pages." (:require - [clojure.spec.alpha :as s])) + [clojure.spec.alpha :as s] + [uxbox.common.data :as d])) ;; --- Specs @@ -49,6 +50,10 @@ :data any?) :del-shape (s/cat :name #(= % :del-shape) :id uuid?) + :mov-shape (s/cat :name #(= % :mov-shape) + :id1 uuid? + :pos #(= :after %) + :id2 (s/nilable uuid?)) :add-canvas (s/cat :name #(= % :add-canvas) :id uuid? :data any?) @@ -62,9 +67,10 @@ (declare process-operation) (declare process-mod-shape) +(declare process-mov-shape) (declare process-add-shape) -(declare process-del-shape) (declare process-add-canvas) +(declare process-del-shape) (declare process-del-canvas) (defn process-ops @@ -76,9 +82,10 @@ [data [op & rest]] (case op :mod-shape (process-mod-shape data rest) + :mov-shape (process-mov-shape data rest) :add-shape (process-add-shape data rest) - :del-shape (process-del-shape data rest) :add-canvas (process-add-canvas data rest) + :del-shape (process-del-shape data rest) :del-canvas (process-del-canvas data rest))) (defn- process-mod-shape @@ -101,6 +108,22 @@ (conj shapes id)))) (update :shapes-by-id assoc id sdata))) +(defn- process-mov-shape + [data [id _ id2]] + (let [shapes (:shapes data) + shapes' (into [] (remove #(= % id) shapes)) + index (d/index-of shapes' id2)] + (cond + (= id id2) + (assoc data :shapes shapes) + + (nil? index) + (assoc data :shapes (d/concat [id] shapes')) + + :else + (let [[before after] (split-at (inc index) shapes')] + (assoc data :shapes (d/concat [] before [id] after)))))) + (defn- process-del-shape [data [id]] (-> data diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 558fc4f39..a908a5f43 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -880,8 +880,10 @@ ;; --- Change Shape Order (D&D Ordering) -(defn change-shape-order - [{:keys [id index] :as params}] +(defn temporal-shape-order-change + [id index] + (s/assert ::us/uuid id) + (s/assert number? index) {:pre [(uuid? id) (number? index)]} (ptk/reify ::change-shape-order ptk/UpdateEvent @@ -889,8 +891,20 @@ (let [shapes (get-in state [:workspace-data :shapes]) shapes (into [] (remove #(= % id)) shapes) [before after] (split-at index shapes) - shapes (vec (concat before [id] after))] - (assoc-in state [:workspace-data :shapes] shapes))))) + shapes (d/concat [] before [id] after) + operation [:mov-shape id :after (last before)]] + (-> state + (assoc-in [:workspace-data :shapes] shapes) + (assoc ::tmp-changes [operation])))))) + +(def commit-shape-order-change + (ptk/reify ::commit-shape-order-change + ptk/WatchEvent + (watch [_ state stream] + (let [changes (::tmp-changes state)] + (rx/of (commit-shapes-changes changes) + #(dissoc state ::tmp-changes)))))) + ;; --- Change Canvas Order (D&D Ordering) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs index 28c92b326..7be57bfb3 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs @@ -107,11 +107,10 @@ (dw/select-shape id))))) (on-drop [item monitor] - (st/emit! ::dw/page-data-update)) + (st/emit! dw/commit-shape-order-change)) (on-hover [item monitor] - (st/emit! (dw/change-shape-order {:id (:shape-id item) - :index index})))] + (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"