mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 00:06:38 +02:00
♻️ Refactor workspace initialization.
Enable selection indexation.
This commit is contained in:
parent
7f7f28f871
commit
77d555dbf2
5 changed files with 241 additions and 304 deletions
|
@ -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))))))
|
||||||
|
|
|
@ -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}])]))
|
||||||
|
|
|
@ -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})]
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue