mirror of
https://github.com/penpot/penpot.git
synced 2025-03-18 10:41:29 -05:00
✨ Improve workspace initialization flow
This commit is contained in:
parent
8ca6055935
commit
ff00043811
4 changed files with 114 additions and 142 deletions
|
@ -142,116 +142,86 @@
|
|||
(let [data (d/removem (comp t/pointer? val) data)]
|
||||
(assoc state :workspace-data data)))))
|
||||
|
||||
(defn- workspace-data-pointers-loaded
|
||||
[pdata]
|
||||
(ptk/reify ::workspace-data-pointers-loaded
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-data merge pdata))))
|
||||
(defn- resolve-file-data
|
||||
[file-id {:keys [pages-index] :as data}]
|
||||
(letfn [(resolve-pointer [[key val :as kv]]
|
||||
(if (t/pointer? val)
|
||||
(->> (rp/cmd! :get-file-fragment {:file-id file-id :fragment-id @val})
|
||||
(rx/map #(get % :content))
|
||||
(rx/map #(vector key %)))
|
||||
(rx/of kv)))
|
||||
|
||||
(resolve-pointers [coll]
|
||||
(->> (rx/from (seq coll))
|
||||
(rx/merge-map resolve-pointer)
|
||||
(rx/reduce conj {})))]
|
||||
|
||||
(->> (rx/zip (resolve-pointers data)
|
||||
(resolve-pointers pages-index))
|
||||
(rx/take 1)
|
||||
(rx/map (fn [[data pages-index]]
|
||||
(assoc data :pages-index pages-index))))))
|
||||
|
||||
(defn- bundle-fetched
|
||||
[features [{:keys [id data] :as file} thumbnails project users comments-users]]
|
||||
(letfn [(resolve-pointer [file-id [key pointer]]
|
||||
(->> (rp/cmd! :get-file-fragment {:file-id file-id :fragment-id @pointer})
|
||||
(rx/map :content)
|
||||
(rx/map #(vector key %))))
|
||||
(ptk/reify ::bundle-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc :workspace-thumbnails thumbnails)
|
||||
(assoc :workspace-file (dissoc file :data))
|
||||
(assoc :workspace-project project)
|
||||
(assoc :current-team-id (:team-id project))
|
||||
(assoc :users (d/index-by :id users))
|
||||
(assoc :current-file-comments-users (d/index-by :id comments-users))))
|
||||
|
||||
(resolve-pointers [file-id coll]
|
||||
(->> (rx/from (seq coll))
|
||||
(rx/merge-map (partial resolve-pointer file-id))
|
||||
(rx/reduce conj {})))]
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [team-id (:team-id project)
|
||||
stoper (rx/filter (ptk/type? ::bundle-fetched) stream)]
|
||||
(->> (rx/concat
|
||||
;; Initialize notifications
|
||||
(rx/of (dwn/initialize team-id id)
|
||||
(dwsl/initialize))
|
||||
|
||||
(ptk/reify ::bundle-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc :workspace-thumbnails thumbnails)
|
||||
(assoc :workspace-file (dissoc file :data))
|
||||
(assoc :workspace-project project)
|
||||
(assoc :current-team-id (:team-id project))
|
||||
(assoc :users (d/index-by :id users))
|
||||
(assoc :current-file-comments-users (d/index-by :id comments-users))))
|
||||
;; Load team fonts. We must ensure custom fonts are
|
||||
;; fully loadad before mark workspace as initialized
|
||||
(rx/merge
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? :app.main.data.fonts/team-fonts-loaded))
|
||||
(rx/take 1)
|
||||
(rx/ignore))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [team-id (:team-id project)
|
||||
stoper (rx/filter (ptk/type? ::bundle-fetched) stream)]
|
||||
(->> (rx/concat
|
||||
;; Initialize notifications
|
||||
(rx/of (dwn/initialize team-id id)
|
||||
(dwsl/initialize))
|
||||
(rx/of (df/load-team-fonts team-id))
|
||||
|
||||
;; Load team fonts. We must ensure custom fonts are fully loadad
|
||||
;; before starting the workspace load.
|
||||
(rx/merge
|
||||
(rx/of (df/load-team-fonts team-id))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? :app.main.data.fonts/team-fonts-loaded))
|
||||
(rx/take 1)
|
||||
(rx/ignore)))
|
||||
;; Load main file
|
||||
(->> (resolve-file-data id data)
|
||||
(rx/mapcat (fn [{:keys [pages-index] :as data}]
|
||||
(->> (rx/from (seq pages-index))
|
||||
(rx/mapcat
|
||||
(fn [[id page]]
|
||||
(let [page (update page :objects ctst/start-page-index)]
|
||||
(->> (uw/ask! {:cmd :initialize-page-index :page page})
|
||||
(rx/map (fn [_] [id page]))))))
|
||||
(rx/reduce conj {})
|
||||
(rx/map (fn [pages-index]
|
||||
(assoc data :pages-index pages-index))))))
|
||||
(rx/map workspace-data-loaded))
|
||||
|
||||
(rx/merge
|
||||
;; Load all pages, independently if they are pointers or already
|
||||
;; resolved values.
|
||||
(->> (rx/from (seq (:pages-index data)))
|
||||
(rx/merge-map
|
||||
(fn [[_ page :as kp]]
|
||||
(if (t/pointer? page)
|
||||
(resolve-pointer id kp)
|
||||
(rx/of kp))))
|
||||
(rx/merge-map
|
||||
(fn [[id page]]
|
||||
(let [page (update page :objects ctst/start-page-index)]
|
||||
(->> (uw/ask! {:cmd :initialize-page-index :page page})
|
||||
(rx/map (constantly [id page]))))))
|
||||
(rx/reduce conj {})
|
||||
(rx/map (fn [pages-index]
|
||||
(-> data
|
||||
(assoc :pages-index pages-index)
|
||||
(workspace-data-loaded)))))
|
||||
|
||||
;; Once workspace data is loaded, proceed asynchronously load
|
||||
;; the local library and all referenced libraries, without
|
||||
;; blocking the main workspace load process.
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::workspace-data-loaded))
|
||||
(rx/take 1)
|
||||
(rx/merge-map
|
||||
(fn [_]
|
||||
(rx/merge
|
||||
(->> data
|
||||
(filter (comp t/pointer? val))
|
||||
(resolve-pointers id)
|
||||
(rx/map workspace-data-pointers-loaded))
|
||||
|
||||
(->> (rp/cmd! :get-file-libraries {:file-id id})
|
||||
(rx/mapcat identity)
|
||||
(rx/merge-map
|
||||
(fn [{:keys [id]}]
|
||||
(rp/cmd! :get-file {:id id :features features})))
|
||||
(rx/merge-map
|
||||
(fn [{:keys [id data] :as file}]
|
||||
(->> (filter (comp t/pointer? val) data)
|
||||
(resolve-pointers id)
|
||||
(rx/map #(update file :data merge %)))))
|
||||
(rx/merge-map
|
||||
(fn [{:keys [id data] :as file}]
|
||||
;; Resolve all pages of each library, if needed
|
||||
(->> (rx/from (seq (:pages-index data)))
|
||||
(rx/merge-map
|
||||
(fn [[_ page :as kp]]
|
||||
(if (t/pointer? page)
|
||||
(resolve-pointer id kp)
|
||||
(rx/of kp))))
|
||||
(rx/reduce conj {})
|
||||
(rx/map
|
||||
(fn [pages-index]
|
||||
(assoc-in file [:data :pages-index] pages-index))))))
|
||||
(rx/reduce conj [])
|
||||
(rx/map libraries-fetched)))))))
|
||||
|
||||
(rx/of (workspace-initialized)))
|
||||
(rx/take-until stoper)))))))
|
||||
;; Load libraries
|
||||
(->> (rp/cmd! :get-file-libraries {:file-id id})
|
||||
(rx/mapcat identity)
|
||||
(rx/merge-map
|
||||
(fn [{:keys [id]}]
|
||||
(rp/cmd! :get-file {:id id :features features})))
|
||||
(rx/merge-map
|
||||
(fn [{:keys [id data] :as file}]
|
||||
(->> (resolve-file-data id data)
|
||||
(rx/map (fn [data] (assoc file :data data))))))
|
||||
(rx/reduce conj [])
|
||||
(rx/map libraries-fetched)))
|
||||
(rx/of (workspace-initialized)))
|
||||
(rx/take-until stoper))))))
|
||||
|
||||
(defn- libraries-fetched
|
||||
[libraries]
|
||||
|
@ -329,6 +299,7 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state
|
||||
:workspace-ready? false
|
||||
:current-file-id file-id
|
||||
:current-project-id project-id
|
||||
:workspace-presence {}))
|
||||
|
|
|
@ -105,7 +105,11 @@
|
|||
(l/derived :workspace-drawing st/state))
|
||||
|
||||
(def workspace-ready?
|
||||
(l/derived :workspace-ready? st/state))
|
||||
(l/derived (fn [state]
|
||||
(and (:workspace-ready? state)
|
||||
(:current-file-id state)
|
||||
(:current-project-id state)))
|
||||
st/state))
|
||||
|
||||
;; TODO: rename to workspace-selected (?)
|
||||
;; Don't use directly from components, this is a proxy to improve performance of selected-shapes
|
||||
|
|
|
@ -131,8 +131,7 @@
|
|||
i/loader-pencil])
|
||||
|
||||
(mf/defc workspace
|
||||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [project-id file-id page-id layout-name]}]
|
||||
(let [file (mf/deref refs/workspace-file)
|
||||
project (mf/deref refs/workspace-project)
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.perf :as perf]
|
||||
[app.util.router :as rt]
|
||||
[app.util.strings :refer [matches-search]]
|
||||
[app.util.timers :as ts]
|
||||
|
@ -2490,44 +2489,43 @@
|
|||
show-libraries-dialog
|
||||
(mf/use-fn #(modal/show! :libraries-dialog {}))]
|
||||
|
||||
[:& perf/profiler {:enabled true :label "sidebar/assets"}
|
||||
[:div.assets-bar
|
||||
[:div.tool-window
|
||||
[:div.tool-window-content
|
||||
[:div.assets-bar-title
|
||||
(tr "workspace.assets.assets")
|
||||
[:div.assets-bar
|
||||
[:div.tool-window
|
||||
[:div.tool-window-content
|
||||
[:div.assets-bar-title
|
||||
(tr "workspace.assets.assets")
|
||||
|
||||
(when-not ^boolean read-only?
|
||||
[:div.libraries-button {:on-click show-libraries-dialog}
|
||||
i/text-align-justify
|
||||
(tr "workspace.assets.libraries")])]
|
||||
(when-not ^boolean read-only?
|
||||
[:div.libraries-button {:on-click show-libraries-dialog}
|
||||
i/text-align-justify
|
||||
(tr "workspace.assets.libraries")])]
|
||||
|
||||
[:div.search-block
|
||||
[:input.search-input
|
||||
{:placeholder (tr "workspace.assets.search")
|
||||
:type "text"
|
||||
:value (:term filters)
|
||||
:on-change on-search-term-change
|
||||
:on-key-down handle-key-down}]
|
||||
[:div.search-block
|
||||
[:input.search-input
|
||||
{:placeholder (tr "workspace.assets.search")
|
||||
:type "text"
|
||||
:value (:term filters)
|
||||
:on-change on-search-term-change
|
||||
:on-key-down handle-key-down}]
|
||||
|
||||
(if ^boolean (str/empty? (:term filters))
|
||||
[:div.search-icon
|
||||
i/search]
|
||||
[:div.search-icon.close
|
||||
{:on-click on-search-clear-click}
|
||||
i/close])]
|
||||
(if ^boolean (str/empty? (:term filters))
|
||||
[:div.search-icon
|
||||
i/search]
|
||||
[:div.search-icon.close
|
||||
{:on-click on-search-clear-click}
|
||||
i/close])]
|
||||
|
||||
[:select.input-select {:value (:section filters)
|
||||
:on-change on-section-filter-change}
|
||||
[:option {:value ":all"} (tr "workspace.assets.box-filter-all")]
|
||||
[:option {:value ":components"} (tr "workspace.assets.components")]
|
||||
[:option {:value ":graphics"} (tr "workspace.assets.graphics")]
|
||||
[:option {:value ":colors"} (tr "workspace.assets.colors")]
|
||||
[:option {:value ":typographies"} (tr "workspace.assets.typography")]]]]
|
||||
[:select.input-select {:value (:section filters)
|
||||
:on-change on-section-filter-change}
|
||||
[:option {:value ":all"} (tr "workspace.assets.box-filter-all")]
|
||||
[:option {:value ":components"} (tr "workspace.assets.components")]
|
||||
[:option {:value ":graphics"} (tr "workspace.assets.graphics")]
|
||||
[:option {:value ":colors"} (tr "workspace.assets.colors")]
|
||||
[:option {:value ":typographies"} (tr "workspace.assets.typography")]]]]
|
||||
|
||||
[:& (mf/provider ctx:filters) {:value filters}
|
||||
[:& (mf/provider ctx:toggle-ordering) {:value toggle-ordering}
|
||||
[:& (mf/provider ctx:toggle-list-style) {:value toggle-list-style}
|
||||
[:div.libraries-wrapper
|
||||
[:& assets-local-library {:filters filters}]
|
||||
[:& assets-libraries {:filters filters}]]]]]]]))
|
||||
[:& (mf/provider ctx:filters) {:value filters}
|
||||
[:& (mf/provider ctx:toggle-ordering) {:value toggle-ordering}
|
||||
[:& (mf/provider ctx:toggle-list-style) {:value toggle-list-style}
|
||||
[:div.libraries-wrapper
|
||||
[:& assets-local-library {:filters filters}]
|
||||
[:& assets-libraries {:filters filters}]]]]]]))
|
||||
|
|
Loading…
Add table
Reference in a new issue