♻️ Refactor workspace initialization.

Enable selection indexation.
This commit is contained in:
Andrey Antukh 2020-04-17 15:09:47 +02:00 committed by Alonso Torres
parent 7f7f28f871
commit 77d555dbf2
5 changed files with 241 additions and 304 deletions

View file

@ -5,7 +5,7 @@
;; This Source Code Form is "Incompatible With Secondary Licenses", as ;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0. ;; defined by the Mozilla Public License, v. 2.0.
;; ;;
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz> ;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.data.workspace (ns uxbox.main.data.workspace
(:require (:require
@ -31,6 +31,7 @@
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.streams :as ms] [uxbox.main.streams :as ms]
[uxbox.main.websockets :as ws] [uxbox.main.websockets :as ws]
[uxbox.main.worker :as uw]
[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]
@ -63,8 +64,6 @@
;; --- Declarations ;; --- Declarations
(declare fetch-users)
(declare fetch-images)
(declare fetch-project) (declare fetch-project)
(declare handle-who) (declare handle-who)
(declare handle-pointer-update) (declare handle-pointer-update)
@ -72,6 +71,119 @@
(declare handle-page-change) (declare handle-page-change)
(declare shapes-changes-commited) (declare shapes-changes-commited)
(declare commit-changes) (declare commit-changes)
(declare fetch-bundle)
(declare initialize-ws)
(declare finalize-ws)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Workspace Initialization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Initialize Workspace
(def default-layout
#{:sitemap
:sitemap-pages
:layers
:element-options
:rules})
(def workspace-default
{:zoom 1
:flags #{}
:selected #{}
:drawing nil
:drawing-tool nil
:tooltip nil})
(def initialize-layout
(ptk/reify ::initialize-layout
ptk/UpdateEvent
(update [_ state]
(assoc state :workspace-layout default-layout))))
(defn initialized
[project-id file-id]
(ptk/reify ::initialized
ptk/UpdateEvent
(update [_ state]
(update state :workspace-file
(fn [file]
(if (= (:id file) file-id)
(assoc file :initialized true)
file))))))
(defn initialize
[project-id file-id]
(us/verify ::us/uuid project-id)
(us/verify ::us/uuid file-id)
(letfn [(setup-index [{:keys [file pages] :as params}]
(let [msg {:cmd :selection/create-index
:file-id (:id file)
:pages pages}]
(->> (uw/ask! msg)
(rx/map (constantly ::index-initialized)))))]
(ptk/reify ::initialize
ptk/WatchEvent
(watch [_ state stream]
(rx/merge
(rx/of (fetch-bundle project-id file-id)
(initialize-ws file-id))
(->> stream
(rx/filter (ptk/type? ::bundle-fetched))
(rx/map deref)
(rx/mapcat setup-index)
(rx/first))
(->> stream
(rx/filter #(= ::index-initialized %))
(rx/map (constantly
(initialized project-id file-id)))))))))
(defn finalize
[project-id file-id]
(ptk/reify ::finalize
ptk/UpdateEvent
(update [_ state]
(dissoc state :workspace-file :workspace-project))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (finalize-ws file-id)))))
(declare initialize-page-persistence)
(defn initialize-page
[page-id]
(ptk/reify ::initialize-page
ptk/UpdateEvent
(update [_ state]
(let [page (get-in state [:workspace-pages page-id])
local (get-in state [:workspace-cache page-id] workspace-default)]
(-> state
(assoc ::page-id page-id ; mainly used by events
:workspace-local local
:workspace-page (dissoc page :data))
(assoc-in [:workspace-data page-id] (:data page)))))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (initialize-page-persistence page-id)))))
(defn finalize-page
[page-id]
(us/verify ::us/uuid page-id)
(ptk/reify ::finalize-page
ptk/UpdateEvent
(update [_ state]
(let [local (:workspace-local state)]
(-> state
(assoc-in [:workspace-cache page-id] local)
(update :workspace-data dissoc page-id))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Workspace WebSocket ;; Workspace WebSocket
@ -260,117 +372,6 @@
(update [_ state] (update [_ state]
(update state :workspace-local dissoc :undo-index :undo)))) (update state :workspace-local dissoc :undo-index :undo))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Workspace Initialization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Initialize Workspace
(declare initialize-alignment)
(def default-layout #{:sitemap :sitemap-pages :layers :element-options :rules})
(def workspace-default
{:zoom 1
:flags #{}
:selected #{}
:drawing nil
:drawing-tool nil
:tooltip nil})
(declare initialize-layout)
(declare initialize-page)
(declare initialize-file)
(declare fetch-file-with-users)
(declare fetch-pages)
(declare fetch-page)
(def initialize-layout
(ptk/reify ::initialize-layout
ptk/UpdateEvent
(update [_ state]
(assoc state :workspace-layout default-layout))))
(defn initialize
"Initialize the workspace state."
[project-id file-id page-id]
(us/verify ::us/uuid project-id)
(us/verify ::us/uuid file-id)
(us/verify ::us/uuid page-id)
(ptk/reify ::initialize
ptk/WatchEvent
(watch [_ state stream]
(let [file (:workspace-file state)]
(if (not= (:id file) file-id)
(rx/merge
(rx/of (fetch-file-with-users file-id)
(fetch-pages file-id)
(fetch-images file-id)
(fetch-project project-id))
(->> (rx/zip (rx/filter (ptk/type? ::pages-fetched) stream)
(rx/filter (ptk/type? ::file-fetched) stream)
(rx/filter (ptk/type? ::project-fetched) stream))
(rx/take 1)
(rx/do (fn [_]
(uxbox.util.timers/schedule 500 #(reset! st/loader false))))
(rx/mapcat (fn [_]
(rx/of (initialize-file file-id)
(initialize-page page-id))))))
(rx/merge
(rx/of (fetch-page page-id))
(->> stream
(rx/filter (ptk/type? ::pages-fetched))
(rx/take 1)
(rx/merge-map (fn [_]
(rx/of (initialize-file file-id)
(initialize-page page-id)))))))))))
(defn- initialize-file
[file-id]
(us/verify ::us/uuid file-id)
(ptk/reify ::initialize-file
ptk/UpdateEvent
(update [_ state]
(let [file (get-in state [:files file-id])]
(assoc state :workspace-file file)))))
(declare diff-and-commit-changes)
(declare initialize-page-persistence)
(defn initialize-page
[page-id]
(ptk/reify ::initialize-page
ptk/UpdateEvent
(update [_ state]
(let [page (get-in state [:pages page-id])
data (get-in state [:pages-data page-id])
local (get-in state [:workspace-cache page-id] workspace-default)]
(-> state
(assoc ::page-id page-id) ; mainly used by events
(assoc :workspace-local local)
(assoc :workspace-page page)
(assoc-in [:workspace-data page-id] data))))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (initialize-page-persistence page-id)))))
(defn finalize
[project-id file-id page-id]
(us/verify ::us/uuid project-id)
(us/verify ::us/uuid file-id)
(us/verify ::us/uuid page-id)
(ptk/reify ::finalize
ptk/UpdateEvent
(update [_ state]
(let [local (:workspace-local state)]
(-> state
(assoc-in [:workspace-cache page-id] local)
(update :workspace-data dissoc page-id))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Persistence ;; Data Persistence
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -415,7 +416,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [session-id (:session-id state) (let [session-id (:session-id state)
page (get-in state [:pages page-id]) page (get-in state [:workspace-pages page-id])
changes (->> changes changes (->> changes
(mapcat identity) (mapcat identity)
(map #(assoc % :session-id session-id)) (map #(assoc % :session-id session-id))
@ -472,7 +473,7 @@
(watch [_ state stream] (watch [_ state stream]
(let [page-id (::page-id state) (let [page-id (::page-id state)
curr (get-in state [:workspace-data page-id]) curr (get-in state [:workspace-data page-id])
prev (get-in state [:pages-data page-id]) prev (get-in state [:workspace-pages page-id :data])
changes (generate-changes prev curr) changes (generate-changes prev curr)
undo-changes (generate-changes curr prev)] undo-changes (generate-changes curr prev)]
@ -511,84 +512,47 @@
::ordering ::ordering
::data])) ::data]))
;; --- Fetch Workspace Users ;; --- Fetch Workspace Bundle
(declare users-fetched) (declare bundle-fetched)
(declare file-fetched)
(defn fetch-file-with-users (defn- fetch-bundle
[id] [project-id file-id]
(us/verify ::us/uuid id) (ptk/reify ::fetch-bundle
(ptk/reify ::fetch-file-with-users
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(->> (rp/query :file-with-users {:id id}) (->> (rx/zip (rp/query :file-with-users {:id file-id})
(rx/merge-map (fn [result] (rp/query :project-by-id {:project-id project-id})
(rx/of (file-fetched (dissoc result :users)) (rp/query :pages {:file-id file-id}))
(users-fetched (:users result))))) (rx/first)
(rx/map (fn [[file project pages]]
(bundle-fetched file project pages)))
(rx/catch (fn [{:keys [type] :as error}] (rx/catch (fn [{:keys [type] :as error}]
(when (= :not-found type) (when (= :not-found type)
(rx/of (rt/nav :not-found))))))))) (rx/of (rt/nav :not-found)))))))))
(defn fetch-file
[id]
(us/verify ::us/uuid id)
(ptk/reify ::fetch-file
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query :file {:id id})
(rx/map file-fetched)))))
(defn file-fetched (defn- bundle-fetched
[{:keys [id] :as file}] [file project pages]
(us/verify ::file file) (ptk/reify ::bundle-fetched
(ptk/reify ::file-fetched IDeref
(-deref [_]
{:file file
:project project
:pages pages})
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(update state :files assoc id file)))) (let [assoc-page #(assoc-in %1 [:workspace-pages (:id %2)] %2)]
(as-> state $$
(defn users-fetched (assoc $$
[users] :workspace-file file
(ptk/reify ::users-fetched :workspace-pages {}
ptk/UpdateEvent :workspace-project project)
(update [_ state] (reduce assoc-page $$ pages))))))
(reduce (fn [state user]
(update-in state [:workspace-users :by-id (:id user)] merge user))
state
users))))
;; --- Fetch Project data
(declare project-fetched)
(defn fetch-project
[id]
(us/verify ::us/uuid id)
(ptk/reify ::fetch-project
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query :project-by-id {:project-id id})
(rx/map project-fetched)))))
(defn project-fetched
[project]
(us/verify ::project project)
(ptk/reify ::project-fetched
ptk/UpdateEvent
(update [_ state]
(assoc state :workspace-project project))))
;; --- Fetch Pages ;; --- Fetch Pages
(declare pages-fetched) (declare page-fetched)
(declare unpack-page)
(defn fetch-pages
[file-id]
(us/verify ::us/uuid file-id)
(ptk/reify ::fetch-pages
ptk/WatchEvent
(watch [_ state s]
(->> (rp/query :pages {:file-id file-id})
(rx/map pages-fetched)))))
(defn fetch-page (defn fetch-page
[page-id] [page-id]
@ -597,18 +561,18 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state s] (watch [_ state s]
(->> (rp/query :page {:id page-id}) (->> (rp/query :page {:id page-id})
(rx/map #(pages-fetched [%])))))) (rx/map page-fetched)))))
(defn pages-fetched (defn page-fetched
[pages] [{:keys [id] :as page}]
(us/verify (s/every ::page) pages) (us/verify ::page page)
(ptk/reify ::pages-fetched (ptk/reify ::page-fetched
IDeref IDeref
(-deref [_] pages) (-deref [_] page)
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(reduce unpack-page state pages)))) (assoc-in state [:workspace-pages id] page))))
;; --- Page Crud ;; --- Page Crud
@ -618,9 +582,9 @@
(ptk/reify ::create-empty-page (ptk/reify ::create-empty-page
ptk/WatchEvent ptk/WatchEvent
(watch [this state stream] (watch [this state stream]
(let [file-id (get-in state [:workspace-page :file-id]) (let [file-id (get-in state [:workspace-file :id])
name (str "Page " (gensym "p")) name (str "Page " (gensym "p"))
ordering (count (get-in state [:files file-id :pages])) ordering (count (get-in state [:workspace-file :pages]))
params {:name name params {:name name
:file-id file-id :file-id file-id
:ordering ordering :ordering ordering
@ -639,11 +603,7 @@
(update [_ state] (update [_ state]
(-> state (-> state
(update-in [:workspace-file :pages] (fnil conj []) id) (update-in [:workspace-file :pages] (fnil conj []) id)
(unpack-page page))) (assoc-in [:workspace-pages id] page)))))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (fetch-file file-id)))))
(s/def ::rename-page (s/def ::rename-page
(s/keys :req-un [::id ::name])) (s/keys :req-un [::id ::name]))
@ -656,7 +616,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [pid (get-in state [:workspac-page :id]) (let [pid (get-in state [:workspac-page :id])
state (assoc-in state [:pages id :name] name)] state (assoc-in state [:workspac-pages id :name] name)]
(cond-> state (cond-> state
(= pid id) (assoc-in [:workspace-page :name] name)))) (= pid id) (assoc-in [:workspace-page :name] name))))
@ -684,10 +644,9 @@
(->> (rp/mutation :delete-page {:id id}) (->> (rp/mutation :delete-page {:id id})
(rx/flat-map (fn [_] (rx/flat-map (fn [_]
(if (= id (:id page)) (if (= id (:id page))
(rx/of (go-to-file (:file-id page))) (rx/of go-to-file)
(rx/empty)))))))))) (rx/empty))))))))))
;; --- Fetch Workspace Images ;; --- Fetch Workspace Images
(declare images-fetched) (declare images-fetched)
@ -772,25 +731,14 @@
(update [_ state] (update [_ state]
(update state :workspace-images assoc (:id item) item)))) (update state :workspace-images assoc (:id item) item))))
;; --- Helpers ;; --- Helpers
(defn unpack-page
[state {:keys [id data] :as page}]
(-> state
(update :pages assoc id (dissoc page :data))
(update :pages-data assoc id data)))
(defn purge-page (defn purge-page
"Remove page and all related stuff from the state." "Remove page and all related stuff from the state."
[state id] [state id]
(if-let [file-id (get-in state [:pages id :file-id])] (-> state
(-> state (update-in [:workspace-file :pages] #(filterv (partial not= id) %))
(update-in [:files file-id :pages] #(filterv (partial not= id) %)) (update :workspace-pages dissoc id)))
(update-in [:workspace-file :pages] #(filterv (partial not= id) %))
(update :pages dissoc id)
(update :pages-data dissoc id))
state))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Workspace State Manipulation ;; Workspace State Manipulation
@ -800,8 +748,6 @@
(defn toggle-layout-flag (defn toggle-layout-flag
[& flags] [& flags]
;; Verify all?
#_(us/verify keyword? flag)
(ptk/reify ::toggle-layout-flag (ptk/reify ::toggle-layout-flag
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -903,10 +849,11 @@
{:start pos :stop pos})) {:start pos :stop pos}))
nil) nil)
(rx/map data->selrect) (rx/map data->selrect)
(rx/filter #(or (> (:width %) 10)
(> (:height %) 10)))
(rx/map update-selrect) (rx/map update-selrect)
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of select-shapes-by-current-selrect (rx/of select-shapes-by-current-selrect)))))))
(update-selrect nil))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -1148,55 +1095,19 @@
;; --- Select Shapes (By selrect) ;; --- Select Shapes (By selrect)
(defn- impl-try-match-shape
[selrect acc {:keys [type id] :as shape}]
(cond
(geom/contained-in? shape selrect)
(conj acc id)
(geom/overlaps? shape selrect)
(conj acc id)
:else
acc))
(defn impl-match-by-selrect
[state selrect]
(let [zoom (gpt/point (get-in state [:workspace-local :zoom]))
selrect' (geom/apply-zoom selrect zoom)
page-id (::page-id state)
data (get-in state [:workspace-data page-id])
match (fn [acc {:keys [type id] :as shape}]
(cond
(helpers/is-shape-grouped (:id shape) (:objects data))
acc
(geom/contained-in? shape selrect')
(conj acc id)
(geom/overlaps? shape selrect')
(conj acc id)
:else
acc))
xf (comp (remove :hidden)
(remove :blocked)
(remove #(= :frame (:type %)))
(remove #(= uuid/zero (:id %)))
(map geom/shape->rect-shape)
(map geom/resolve-rotation)
(map geom/shape->rect-shape))]
(transduce xf match #{} (vals (:objects data)))))
(def select-shapes-by-current-selrect (def select-shapes-by-current-selrect
(ptk/reify ::select-shapes-by-current-selrect (ptk/reify ::select-shapes-by-current-selrect
ptk/UpdateEvent ptk/WatchEvent
(update [_ state] (watch [_ state stream]
(let [{:keys [selrect id]} (:workspace-local state)] (let [page-id (get-in state [:workspace-page :id])
(->> (impl-match-by-selrect state selrect) selrect (get-in state [:workspace-local :selrect])]
(assoc-in state [:workspace-local :selected])))))) (rx/merge
(rx/of (update-selrect nil))
(when selrect
(->> (uw/ask! {:cmd :selection/query
:page-id page-id
:rect selrect})
(rx/map select-shapes))))))))
(defn select-inside-group (defn select-inside-group
[group-id position] [group-id position]
@ -1753,6 +1664,17 @@
(reduce materialize-shape state shapes))))) (reduce materialize-shape state shapes)))))
(defn- update-selection-index
[page-id]
(ptk/reify ::update-selection-index
ptk/EffectEvent
(effect [_ state stream]
(let [objects (get-in state [:workspace-pages page-id :data :objects])
lookup #(get objects %)]
(uw/ask! {:cmd :selection/update-index
:page-id page-id
:objects objects})))))
(defn commit-changes (defn commit-changes
([changes undo-changes] (commit-changes changes undo-changes {})) ([changes undo-changes] (commit-changes changes undo-changes {}))
([changes undo-changes {:keys [save-undo? ([changes undo-changes {:keys [save-undo?
@ -1770,7 +1692,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [page-id (::page-id state) (let [page-id (::page-id state)
state (update-in state [:pages-data page-id] cp/process-changes changes)] state (update-in state [:workspace-pages page-id :data] cp/process-changes changes)]
(cond-> state (cond-> state
commit-local? (update-in [:workspace-data page-id] cp/process-changes changes)))) commit-local? (update-in [:workspace-data page-id] cp/process-changes changes))))
@ -1779,6 +1701,8 @@
(let [page (:workspace-page state) (let [page (:workspace-page state)
uidx (get-in state [:workspace-local :undo-index] ::not-found)] uidx (get-in state [:workspace-local :undo-index] ::not-found)]
(rx/concat (rx/concat
(rx/of (update-selection-index (:id page)))
(when (and save-undo? (not= uidx ::not-found)) (when (and save-undo? (not= uidx ::not-found))
(rx/of (reset-undo uidx))) (rx/of (reset-undo uidx)))
@ -1787,7 +1711,6 @@
:redo-changes changes}] :redo-changes changes}]
(rx/of (append-undo entry)))))))))) (rx/of (append-undo entry))))))))))
(s/def ::shapes-changes-commited (s/def ::shapes-changes-commited
(s/keys :req-un [::page-id ::revn ::cp/changes])) (s/keys :req-un [::page-id ::revn ::cp/changes]))
@ -1799,11 +1722,11 @@
(update [_ state] (update [_ state]
(let [session-id (:session-id state) (let [session-id (:session-id state)
state (-> state state (-> state
(assoc-in [:pages page-id :revn] revn)) (assoc-in [:workspace-pages page-id :revn] revn))
changes (filter #(not= session-id (:session-id %)) changes)] changes (filter #(not= session-id (:session-id %)) changes)]
(-> state (-> state
(update-in [:workspace-data page-id] cp/process-changes changes) (update-in [:workspace-data page-id] cp/process-changes changes)
(update-in [:pages-data page-id] cp/process-changes changes)))))) (update-in [:workspace-pages page-id :data] cp/process-changes changes))))))
;; --- Start shape "edition mode" ;; --- Start shape "edition mode"
@ -2042,14 +1965,16 @@
query-params {:page-id page-id}] query-params {:page-id page-id}]
(rx/of (rt/nav :workspace path-params query-params)))))) (rx/of (rt/nav :workspace path-params query-params))))))
(defn go-to-file (def go-to-file
[file-id]
(us/verify ::us/uuid file-id)
(ptk/reify ::go-to-file (ptk/reify ::go-to-file
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [project-id (get-in state [:workspace-project :id]) (let [file (:workspace-file state)
page-ids (get-in state [:files file-id :pages])
file-id (:id file)
project-id (:project-id file)
page-ids (:pages file)
path-params {:project-id project-id :file-id file-id} path-params {:project-id project-id :file-id file-id}
query-params {:page-id (first page-ids)}] query-params {:page-id (first page-ids)}]
(rx/of (rt/nav :workspace path-params query-params)))))) (rx/of (rt/nav :workspace path-params query-params))))))

View file

@ -2,8 +2,10 @@
;; 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-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com> ;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz> ;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.ui.workspace (ns uxbox.main.ui.workspace
(:require (:require
@ -48,10 +50,8 @@
(when (:colorpalette layout) (when (:colorpalette layout)
[:& colorpalette {:left-sidebar? left-sidebar?}]) [:& colorpalette {:left-sidebar? left-sidebar?}])
[:& messages]
[:& context-menu]
[:section.workspace-content {:class classes} [:section.workspace-content {:class classes}
[:& history-dialog] [:& history-dialog]
;; Rules ;; Rules
@ -71,36 +71,47 @@
(when right-sidebar? (when right-sidebar?
[:& right-sidebar {:page page :layout layout}])])) [:& right-sidebar {:page page :layout layout}])]))
(mf/defc workspace-page
[{:keys [project file layout page-id] :as props}]
(mf/use-effect
(mf/deps page-id)
(fn []
(st/emit! (dw/initialize-page page-id))
#(st/emit! (dw/finalize-page page-id))))
(when-let [page (mf/deref refs/workspace-page)]
[:& workspace-content {:page page
:project project
:file file
:layout layout}]))
(mf/defc workspace (mf/defc workspace
[{:keys [project-id file-id page-id] :as props}] [{:keys [project-id file-id page-id] :as props}]
(mf/use-effect #(st/emit! dw/initialize-layout))
(mf/use-effect (mf/use-effect
(mf/deps file-id page-id) (mf/deps project-id file-id)
(fn [] (fn []
(st/emit! (dw/initialize project-id file-id page-id)) (st/emit! (dw/initialize project-id file-id))
#(st/emit! (dw/finalize project-id file-id page-id)))) #(st/emit! (dw/finalize project-id file-id))))
(mf/use-effect
(mf/deps file-id)
(fn []
(st/emit! (dw/initialize-ws file-id))
#(st/emit! (dw/finalize-ws file-id))))
(hooks/use-shortcuts dw/shortcuts) (hooks/use-shortcuts dw/shortcuts)
(mf/use-effect #(st/emit! dw/initialize-layout))
(let [file (mf/deref refs/workspace-file) (let [file (mf/deref refs/workspace-file)
page (mf/deref refs/workspace-page)
project (mf/deref refs/workspace-project) project (mf/deref refs/workspace-project)
layout (mf/deref refs/workspace-layout)] layout (mf/deref refs/workspace-layout)]
[:* [:*
[:& header {:page page [:& header {:file file
:file file
:project project :project project
:layout layout}] :layout layout}]
(when page [:& messages]
[:& workspace-content {:file file [:& context-menu]
:page page
:layout layout}])])) (when (and (and file project)
(:initialized file))
[:& workspace-page {:file file
:project project
:layout layout
:page-id page-id}])]))

View file

@ -144,10 +144,11 @@
;; --- Header Component ;; --- Header Component
(mf/defc header (mf/defc header
[{:keys [page file layout project] :as props}] [{:keys [file layout project] :as props}]
(let [locale (i18n/use-locale) (let [locale (i18n/use-locale)
go-to-dashboard #(st/emit! (rt/nav :dashboard-team {:team-id "self"})) go-to-dashboard #(st/emit! (rt/nav :dashboard-team {:team-id "self"}))
zoom (mf/deref refs/selected-zoom) zoom (mf/deref refs/selected-zoom)
page (mf/deref refs/workspace-page)
locale (i18n/use-locale) locale (i18n/use-locale)
router (mf/deref refs/router) router (mf/deref refs/router)
view-url (rt/resolve router :viewer {:page-id (:id page)} {:index 0})] view-url (rt/resolve router :viewer {:page-id (:id page)} {:index 0})]

View file

@ -91,14 +91,16 @@
;; --- Page Item Wrapper ;; --- Page Item Wrapper
(defn- make-page-ref (defn- make-page-ref
[page-id] [id]
(l/derived #(get-in % [:pages page-id]) st/state)) #(-> (l/in [:workspace-pages id])
(l/derived st/state)))
(mf/defc page-item-wrapper (mf/defc page-item-wrapper
[{:keys [page-id index deletable? selected?] :as props}] [{:keys [page-id index deletable? selected?] :as props}]
(let [page-ref (-> (mf/deps page-id) (let [page-iref (mf/use-memo
(mf/use-memo #(make-page-ref page-id))) (mf/deps page-id)
page (mf/deref page-ref)] (make-page-ref page-id))
page (mf/deref page-iref)]
[:& page-item {:page page [:& page-item {:page page
:index index :index index
:deletable? deletable? :deletable? deletable?

View file

@ -7,8 +7,6 @@
(ns uxbox.util.storage (ns uxbox.util.storage
(:require [uxbox.util.transit :as t])) (:require [uxbox.util.transit :as t]))
(enable-console-print!)
(defn- persist (defn- persist
[alias value] [alias value]
(let [key (name alias) (let [key (name alias)