mirror of
https://github.com/penpot/penpot.git
synced 2025-04-30 00:36:19 +02:00
✨ Ensure workspace page loading and intialization process
This commit is contained in:
parent
6b3a988526
commit
b8107ee497
4 changed files with 99 additions and 51 deletions
|
@ -120,7 +120,7 @@
|
||||||
;; to lost team features updating
|
;; to lost team features updating
|
||||||
|
|
||||||
;; When newly computed features does not match exactly with
|
;; When newly computed features does not match exactly with
|
||||||
;; the features defined on team row, we update it.
|
;; the features defined on team row, we update it
|
||||||
(when (not= features (:features team))
|
(when (not= features (:features team))
|
||||||
(let [features (db/create-array conn "text" features)]
|
(let [features (db/create-array conn "text" features)]
|
||||||
(db/update! conn :team
|
(db/update! conn :team
|
||||||
|
|
|
@ -334,7 +334,8 @@
|
||||||
(rx/take-until stopper-s))))))
|
(rx/take-until stopper-s))))))
|
||||||
|
|
||||||
(defn initialize-workspace
|
(defn initialize-workspace
|
||||||
[file-id]
|
[team-id file-id]
|
||||||
|
(assert (uuid? team-id) "expected valud uuid for `team-id`")
|
||||||
(assert (uuid? file-id) "expected valud uuid for `file-id`")
|
(assert (uuid? file-id) "expected valud uuid for `file-id`")
|
||||||
(ptk/reify ::initialize-workspace
|
(ptk/reify ::initialize-workspace
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
|
@ -410,7 +411,7 @@
|
||||||
(unchecked-set ug/global "name" name)))))
|
(unchecked-set ug/global "name" name)))))
|
||||||
|
|
||||||
(defn finalize-workspace
|
(defn finalize-workspace
|
||||||
[file-id]
|
[_team-id file-id]
|
||||||
(ptk/reify ::finalize-workspace
|
(ptk/reify ::finalize-workspace
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -444,8 +445,9 @@
|
||||||
(ptk/reify ::reload-current-file
|
(ptk/reify ::reload-current-file
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (:current-file-id state)]
|
(let [file-id (:current-file-id state)
|
||||||
(rx/of (initialize-workspace file-id))))))
|
team-id (:current-team-id state)]
|
||||||
|
(rx/of (initialize-workspace team-id file-id))))))
|
||||||
|
|
||||||
;; Make this event callable through dynamic resolution
|
;; Make this event callable through dynamic resolution
|
||||||
(defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file))
|
(defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file))
|
||||||
|
@ -488,18 +490,25 @@
|
||||||
(defn initialize-page
|
(defn initialize-page
|
||||||
[file-id page-id]
|
[file-id page-id]
|
||||||
(assert (uuid? file-id) "expected valid uuid for `file-id`")
|
(assert (uuid? file-id) "expected valid uuid for `file-id`")
|
||||||
|
(assert (uuid? page-id) "expected valid uuid for `page-id`")
|
||||||
|
|
||||||
(ptk/reify ::initialize-page
|
(ptk/reify ::initialize-page
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(if-let [page (dsh/lookup-page state file-id page-id)]
|
(if-let [page (dsh/lookup-page state file-id page-id)]
|
||||||
(rx/concat (rx/of (initialize-page* file-id page-id page)
|
(rx/concat
|
||||||
|
(rx/of (initialize-page* file-id page-id page)
|
||||||
(dwth/watch-state-changes file-id page-id)
|
(dwth/watch-state-changes file-id page-id)
|
||||||
(dwl/watch-component-changes))
|
(dwl/watch-component-changes))
|
||||||
(let [profile (:profile state)
|
(let [profile (:profile state)
|
||||||
props (get profile :props)]
|
props (get profile :props)]
|
||||||
(when (not (:workspace-visited props))
|
(when (not (:workspace-visited props))
|
||||||
(rx/of (select-frame-tool file-id page-id)))))
|
(rx/of (select-frame-tool file-id page-id)))))
|
||||||
|
|
||||||
|
;; NOTE: this redirect is necessary for cases where user
|
||||||
|
;; explicitly passes an non-existing page-id on the url
|
||||||
|
;; params, so on check it we can detect that there are no data
|
||||||
|
;; for the page and redirect user to an existing page
|
||||||
(rx/of (dcm/go-to-workspace :file-id file-id ::rt/replace true))))))
|
(rx/of (dcm/go-to-workspace :file-id file-id ::rt/replace true))))))
|
||||||
|
|
||||||
(defn finalize-page
|
(defn finalize-page
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.persistence :as dwp]
|
[app.main.data.persistence :as dwp]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.thumbnails :as th]
|
[app.main.data.workspace.thumbnails :as th]
|
||||||
|
@ -97,7 +98,8 @@
|
||||||
(ptk/reify ::restore-version
|
(ptk/reify ::restore-version
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-id (:current-file-id state)]
|
(let [file-id (:current-file-id state)
|
||||||
|
team-id (:current-team-id state)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of ::dwp/force-persist
|
(rx/of ::dwp/force-persist
|
||||||
(dw/remove-layout-flag :document-history))
|
(dw/remove-layout-flag :document-history))
|
||||||
|
@ -106,7 +108,7 @@
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/mapcat #(rp/cmd! :restore-file-snapshot {:file-id file-id :id id}))
|
(rx/mapcat #(rp/cmd! :restore-file-snapshot {:file-id file-id :id id}))
|
||||||
(rx/tap #(th/clear-queue!))
|
(rx/tap #(th/clear-queue!))
|
||||||
(rx/map #(dw/initialize-workspace file-id)))
|
(rx/map #(dw/initialize-workspace team-id file-id)))
|
||||||
(case origin
|
(case origin
|
||||||
:version
|
:version
|
||||||
(rx/of (ptk/event ::ev/event {::ev/name "restore-pin-version"}))
|
(rx/of (ptk/event ::ev/event {::ev/name "restore-pin-version"}))
|
||||||
|
@ -200,7 +202,10 @@
|
||||||
|
|
||||||
(ptk/reify ::restore-version-from-plugins
|
(ptk/reify ::restore-version-from-plugins
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
|
;; FIXME: revisit this
|
||||||
|
(let [file (dsh/lookup-file state file-id)
|
||||||
|
team-id (:team-id file)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (ptk/event ::ev/event {::ev/name "restore-version-plugin"})
|
(rx/of (ptk/event ::ev/event {::ev/name "restore-version-plugin"})
|
||||||
::dwp/force-persist)
|
::dwp/force-persist)
|
||||||
|
@ -210,11 +215,11 @@
|
||||||
(rx/filter #(or (nil? %) (= :saved %)))
|
(rx/filter #(or (nil? %) (= :saved %)))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/mapcat #(rp/cmd! :restore-file-snapshot {:file-id file-id :id id}))
|
(rx/mapcat #(rp/cmd! :restore-file-snapshot {:file-id file-id :id id}))
|
||||||
(rx/map #(dw/initialize-workspace file-id)))
|
(rx/map #(dw/initialize-workspace team-id file-id)))
|
||||||
|
|
||||||
(->> (rx/of 1)
|
(->> (rx/of 1)
|
||||||
(rx/tap resolve)
|
(rx/tap resolve)
|
||||||
(rx/ignore))))))
|
(rx/ignore)))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.common :as dcm]
|
[app.main.data.common :as dcm]
|
||||||
|
[app.main.data.helpers :as dsh]
|
||||||
[app.main.data.persistence :as dps]
|
[app.main.data.persistence :as dps]
|
||||||
[app.main.data.plugins :as dpl]
|
[app.main.data.plugins :as dpl]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
@ -45,9 +46,10 @@
|
||||||
(mf/defc workspace-content*
|
(mf/defc workspace-content*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [file layout page wglobal]}]
|
[{:keys [file layout page wglobal]}]
|
||||||
|
|
||||||
(let [palete-size (mf/use-state nil)
|
(let [palete-size (mf/use-state nil)
|
||||||
selected (mf/deref refs/selected-shapes)
|
selected (mf/deref refs/selected-shapes)
|
||||||
page-id (:id page)
|
page-id (get page :id)
|
||||||
|
|
||||||
{:keys [vport] :as wlocal} (mf/deref refs/workspace-local)
|
{:keys [vport] :as wlocal} (mf/deref refs/workspace-local)
|
||||||
{:keys [options-mode]} wglobal
|
{:keys [options-mode]} wglobal
|
||||||
|
@ -120,10 +122,46 @@
|
||||||
:overlay true
|
:overlay true
|
||||||
:file-loading true}])
|
:file-loading true}])
|
||||||
|
|
||||||
|
(defn- make-team-ref
|
||||||
|
[team-id]
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(let [teams (get state :teams)]
|
||||||
|
(get teams team-id)))
|
||||||
|
st/state))
|
||||||
|
|
||||||
|
(defn- make-file-ref
|
||||||
|
[file-id]
|
||||||
|
(l/derived (fn [state]
|
||||||
|
;; NOTE: for ensure ordering of execution, we need to
|
||||||
|
;; wait the file initialization completly success until
|
||||||
|
;; mark this file availablea and unlock the rendering
|
||||||
|
;; of the following components
|
||||||
|
(when (= (get state :current-file-id) file-id)
|
||||||
|
(let [files (get state :files)
|
||||||
|
file (get files file-id)]
|
||||||
|
(-> file
|
||||||
|
(dissoc :data)
|
||||||
|
(assoc ::has-data (contains? file :data))))))
|
||||||
|
st/state))
|
||||||
|
|
||||||
|
(defn- make-page-ref
|
||||||
|
[file-id page-id]
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(let [current-page-id (get state :current-page-id)]
|
||||||
|
;; NOTE: for ensure ordering of execution, we need to
|
||||||
|
;; wait the page initialization completly success until
|
||||||
|
;; mark this file availablea and unlock the rendering
|
||||||
|
;; of the following components
|
||||||
|
(when (= current-page-id page-id)
|
||||||
|
(dsh/lookup-page state file-id page-id))))
|
||||||
|
st/state))
|
||||||
|
|
||||||
(mf/defc workspace-page*
|
(mf/defc workspace-page*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [page-id file-id file layout wglobal]}]
|
[{:keys [page-id file-id file layout wglobal]}]
|
||||||
(let [page (mf/deref refs/workspace-page)]
|
(let [page-ref (mf/with-memo [file-id page-id]
|
||||||
|
(make-page-ref file-id page-id))
|
||||||
|
page (mf/deref page-ref)]
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
(let [focus-out #(st/emit! (dw/workspace-focus-lost))
|
(let [focus-out #(st/emit! (dw/workspace-focus-lost))
|
||||||
|
@ -133,8 +171,7 @@
|
||||||
(mf/with-effect [file-id page-id]
|
(mf/with-effect [file-id page-id]
|
||||||
(st/emit! (dw/initialize-page file-id page-id))
|
(st/emit! (dw/initialize-page file-id page-id))
|
||||||
(fn []
|
(fn []
|
||||||
(when page-id
|
(st/emit! (dw/finalize-page file-id page-id))))
|
||||||
(st/emit! (dw/finalize-page file-id page-id)))))
|
|
||||||
|
|
||||||
(if (some? page)
|
(if (some? page)
|
||||||
[:> workspace-content* {:file file
|
[:> workspace-content* {:file file
|
||||||
|
@ -143,18 +180,9 @@
|
||||||
:layout layout}]
|
:layout layout}]
|
||||||
[:> workspace-loader*])))
|
[:> workspace-loader*])))
|
||||||
|
|
||||||
(def ^:private ref:file-without-data
|
|
||||||
(l/derived (fn [file]
|
|
||||||
(-> file
|
|
||||||
(dissoc :data)
|
|
||||||
(assoc ::has-data (contains? file :data))))
|
|
||||||
refs/file
|
|
||||||
=))
|
|
||||||
|
|
||||||
(mf/defc workspace*
|
(mf/defc workspace*
|
||||||
{::mf/props :obj
|
{::mf/wrap [mf/memo]}
|
||||||
::mf/wrap [mf/memo]}
|
[{:keys [team-id project-id file-id page-id layout-name]}]
|
||||||
[{:keys [project-id file-id page-id layout-name]}]
|
|
||||||
|
|
||||||
(let [file-id (hooks/use-equal-memo file-id)
|
(let [file-id (hooks/use-equal-memo file-id)
|
||||||
page-id (hooks/use-equal-memo page-id)
|
page-id (hooks/use-equal-memo page-id)
|
||||||
|
@ -162,8 +190,15 @@
|
||||||
layout (mf/deref refs/workspace-layout)
|
layout (mf/deref refs/workspace-layout)
|
||||||
wglobal (mf/deref refs/workspace-global)
|
wglobal (mf/deref refs/workspace-global)
|
||||||
|
|
||||||
team (mf/deref refs/team)
|
team-ref (mf/with-memo [team-id]
|
||||||
file (mf/deref ref:file-without-data)
|
(make-team-ref team-id))
|
||||||
|
file-ref (mf/with-memo [file-id]
|
||||||
|
(make-file-ref file-id))
|
||||||
|
|
||||||
|
team (mf/deref team-ref)
|
||||||
|
file (mf/deref file-ref)
|
||||||
|
|
||||||
|
file-loaded? (get file ::has-data)
|
||||||
|
|
||||||
file-name (:name file)
|
file-name (:name file)
|
||||||
permissions (:permissions team)
|
permissions (:permissions team)
|
||||||
|
@ -187,14 +222,14 @@
|
||||||
(when file-name
|
(when file-name
|
||||||
(dom/set-html-title (tr "title.workspace" file-name))))
|
(dom/set-html-title (tr "title.workspace" file-name))))
|
||||||
|
|
||||||
(mf/with-effect [file-id]
|
(mf/with-effect [team-id file-id]
|
||||||
(st/emit! (dw/initialize-workspace file-id))
|
(st/emit! (dw/initialize-workspace team-id file-id))
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! ::dps/force-persist
|
(st/emit! ::dps/force-persist
|
||||||
(dw/finalize-workspace file-id))))
|
(dw/finalize-workspace team-id file-id))))
|
||||||
|
|
||||||
(mf/with-effect [file page-id]
|
(mf/with-effect [file-id page-id file-loaded?]
|
||||||
(when-not page-id
|
(when (and file-loaded? (not page-id))
|
||||||
(st/emit! (dcm/go-to-workspace :file-id file-id ::rt/replace true))))
|
(st/emit! (dcm/go-to-workspace :file-id file-id ::rt/replace true))))
|
||||||
|
|
||||||
[:> (mf/provider ctx/current-project-id) {:value project-id}
|
[:> (mf/provider ctx/current-project-id) {:value project-id}
|
||||||
|
@ -208,8 +243,7 @@
|
||||||
:style {:background-color background-color
|
:style {:background-color background-color
|
||||||
:touch-action "none"}}
|
:touch-action "none"}}
|
||||||
[:> context-menu*]
|
[:> context-menu*]
|
||||||
|
(if (and file-loaded? page-id)
|
||||||
(if (::has-data file)
|
|
||||||
[:> workspace-page*
|
[:> workspace-page*
|
||||||
{:page-id page-id
|
{:page-id page-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
|
|
Loading…
Add table
Reference in a new issue