From a4fe43235b2d1ddd58a8af05b99090d979976434 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 29 Dec 2015 15:51:47 +0200 Subject: [PATCH] Denormalize shapes storage. --- frontend/uxbox/core.cljs | 1 + frontend/uxbox/data/load.cljs | 13 +++++++++++-- frontend/uxbox/data/projects.cljs | 15 ++++++++------- frontend/uxbox/data/workspace.cljs | 19 ++++++++----------- frontend/uxbox/state.cljs | 1 + frontend/uxbox/ui/workspace/base.cljs | 8 ++++++++ frontend/uxbox/ui/workspace/canvas.cljs | 6 +++--- 7 files changed, 40 insertions(+), 23 deletions(-) diff --git a/frontend/uxbox/core.cljs b/frontend/uxbox/core.cljs index 7e19ab56f..6bee84586 100644 --- a/frontend/uxbox/core.cljs +++ b/frontend/uxbox/core.cljs @@ -13,6 +13,7 @@ "Initialize the storage subsystem." [] (let [lens (l/select-keys [:pages-by-id + :shapes-by-id :colors-by-id :projects-by-id]) stream (->> (l/focus-atom lens st/state) diff --git a/frontend/uxbox/data/load.cljs b/frontend/uxbox/data/load.cljs index c1ef1ec9e..40fcbc2b2 100644 --- a/frontend/uxbox/data/load.cljs +++ b/frontend/uxbox/data/load.cljs @@ -16,14 +16,22 @@ to the state map." [state color-coll] (let [uuid (:id color-coll)] - (update-in state [:colors-by-id] assoc uuid color-coll))) + (update state :colors-by-id assoc uuid color-coll))) + +(defn assoc-shape + [state shape] + (let [id (:id shape)] + (update state :shapes-by-id assoc id shape))) (defn persist-state [state] (let [pages (into #{} (vals (:pages-by-id state))) projects (into #{} (vals (:projects-by-id state))) + shapes (into #{} (vals (:shapes-by-id state))) color-colls (into #{} (vals (:colors-by-id state)))] + (assoc! local-storage :data {:pages pages + :shapes shapes :projects projects :color-collections color-colls}))) @@ -41,6 +49,7 @@ (as-> state $ (reduce dp/assoc-project $ (:projects data)) (reduce dp/assoc-page $ (:pages data)) - (reduce assoc-color $ (:color-collections data))) + (reduce assoc-color $ (:color-collections data)) + (reduce assoc-shape $ (:shapes data))) state)))) diff --git a/frontend/uxbox/data/projects.cljs b/frontend/uxbox/data/projects.cljs index e87877252..49666b16a 100644 --- a/frontend/uxbox/data/projects.cljs +++ b/frontend/uxbox/data/projects.cljs @@ -1,10 +1,11 @@ (ns uxbox.data.projects - (:require [uxbox.rstore :as rs] + (:require [bouncer.validators :as v] + [uxbox.rstore :as rs] [uxbox.router :as r] [uxbox.state :as st] [uxbox.schema :as sc] [uxbox.time :as time] - [bouncer.validators :as v])) + [uxbox.util.data :refer (without-keys)])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Schemas @@ -63,7 +64,6 @@ :project project :created (time/now :unix) :shapes [] - :shapes-by-id {} :name name :width width :height height}] @@ -89,7 +89,10 @@ (reify rs/UpdateEvent (-apply-update [_ state] - (update-in state [:pages-by-id] dissoc pageid)) + (let [shapeids (get-in state [:pages-by-id pageid :shapes])] + (as-> state $ + (update $ :shapes-by-id without-keys shapeids) + (update $ :pages-by-id dissoc pageid)))) IPrintWithWriter (-pr-writer [mv writer _] @@ -106,8 +109,7 @@ :name name :width width :created (time/now :unix) - :height height - :layout layout}] + :height height}] (assoc-project state proj))) rs/EffectEvent @@ -116,7 +118,6 @@ :width width :height height :project uuid}))) - IPrintWithWriter (-pr-writer [mv writer _] (-write writer "#"))))) diff --git a/frontend/uxbox/data/workspace.cljs b/frontend/uxbox/data/workspace.cljs index f42a08149..cdfac964c 100644 --- a/frontend/uxbox/data/workspace.cljs +++ b/frontend/uxbox/data/workspace.cljs @@ -93,13 +93,12 @@ (reify rs/UpdateEvent (-apply-update [_ state] - (let [id (random-uuid) - pageid (get-in state [:workspace :page]) - _ (assert pageid) - shape (merge shape props {:id id})] + (let [sid (random-uuid) + pid (get-in state [:workspace :page]) + shape (merge shape props {:id sid :page pid})] (as-> state $ - (update-in $ [:pages-by-id pageid :shapes] conj id) - (update-in $ [:pages-by-id pageid :shapes-by-id] assoc id shape)))) + (update-in $ [:pages-by-id pid :shapes] conj sid) + (assoc-in $ [:shapes-by-id sid] shape)))) IPrintWithWriter (-pr-writer [mv writer _] @@ -124,14 +123,12 @@ (defn apply-delta "Mark a shape selected for drawing in the canvas." - [shapeid [dx dy :as delta]] + [sid [dx dy :as delta]] (reify rs/UpdateEvent (-apply-update [_ state] - ;; (println "apply-delta" shapeid delta) - (let [pageid (get-in state [:workspace :page]) - shape (get-in state [:pages-by-id pageid :shapes-by-id shapeid])] - (update-in state [:pages-by-id pageid :shapes-by-id shapeid] merge + (let [shape (get-in state [:shapes-by-id sid])] + (update-in state [:shapes-by-id sid] merge {:x (+ (:x shape) dx) :y (+ (:y shape) dy)}))))) diff --git a/frontend/uxbox/state.cljs b/frontend/uxbox/state.cljs index b59637d2e..fcc916dca 100644 --- a/frontend/uxbox/state.cljs +++ b/frontend/uxbox/state.cljs @@ -9,6 +9,7 @@ :avatar "http://lorempixel.com/50/50/"} :dashboard {} :workspace {} + :shapes-by-id {} :elements-by-id {} :colors-by-id {} :icons-by-id {} diff --git a/frontend/uxbox/ui/workspace/base.cljs b/frontend/uxbox/ui/workspace/base.cljs index 61e8b7162..6c1646bdf 100644 --- a/frontend/uxbox/ui/workspace/base.cljs +++ b/frontend/uxbox/ui/workspace/base.cljs @@ -27,6 +27,14 @@ (dp/project-pages % pid))) $ (l/focus-atom $ s/state))) +(def ^:static shapes-state + (as-> (ul/getter (fn [state] + (let [pid (get-in state [:workspace :page]) + shapes (->> (vals (:shapes-by-id state)) + (filter #(= (:page %) pid)))] + (into [] shapes)))) $ + (l/focus-atom $ s/state))) + (def ^:static workspace-state (as-> (l/in [:workspace]) $ (l/focus-atom $ s/state))) diff --git a/frontend/uxbox/ui/workspace/canvas.cljs b/frontend/uxbox/ui/workspace/canvas.cljs index 37fd8be2e..cafa5b20b 100644 --- a/frontend/uxbox/ui/workspace/canvas.cljs +++ b/frontend/uxbox/ui/workspace/canvas.cljs @@ -126,6 +126,7 @@ (defn canvas-render [] (let [page (rum/react wb/page-state) + shapes (rum/react wb/shapes-state) page-width (:width page) page-height (:height page)] (html @@ -150,9 +151,8 @@ (grid 1) [:svg.page-layout {} - (for [shapeid (:shapes page) - :let [item (get-in page [:shapes-by-id shapeid])]] - (rum/with-key (shape item) (str shapeid)))]]))) + (for [item shapes] + (rum/with-key (shape item) (str (:id item))))]]))) (def canvas (util/component