🎉 Integrate storage/pointer-map file feature

This commit is contained in:
Andrey Antukh 2022-11-01 09:46:54 +01:00 committed by Andrés Moya
parent a42d7164ad
commit 76333cec26
45 changed files with 2100 additions and 1408 deletions

View file

@ -110,7 +110,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)]
(->> (rp/query :team-members {:team-id team-id})
(->> (rp/query! :team-members {:team-id team-id})
(rx/map team-members-fetched))))))
;; --- EVENT: fetch-team-stats
@ -128,7 +128,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)]
(->> (rp/query :team-stats {:team-id team-id})
(->> (rp/query! :team-stats {:team-id team-id})
(rx/map team-stats-fetched))))))
;; --- EVENT: fetch-team-invitations
@ -146,7 +146,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)]
(->> (rp/query :team-invitations {:team-id team-id})
(->> (rp/query! :team-invitations {:team-id team-id})
(rx/map team-invitations-fetched))))))
;; --- EVENT: fetch-projects
@ -165,7 +165,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)]
(->> (rp/query :projects {:team-id team-id})
(->> (rp/query! :projects {:team-id team-id})
(rx/map projects-fetched))))))
;; --- EVENT: search
@ -193,7 +193,7 @@
(watch [_ state _]
(let [team-id (:current-team-id state)
params (assoc params :team-id team-id)]
(->> (rp/query :search-files params)
(->> (rp/query! :search-files params)
(rx/map search-result-fetched))))))
;; --- EVENT: files
@ -222,7 +222,7 @@
(ptk/reify ::fetch-files
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :project-files {:project-id project-id})
(->> (rp/cmd! :get-project-files {:project-id project-id})
(rx/map #(files-fetched project-id %))))))
;; --- EVENT: shared-files
@ -243,7 +243,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)]
(->> (rp/query :team-shared-files {:team-id team-id})
(->> (rp/cmd! :get-team-shared-files {:team-id team-id})
(rx/map shared-files-fetched))))))
;; --- EVENT: Get files that use this shared-file
@ -269,7 +269,8 @@
ptk/WatchEvent
(watch [_ _ _]
(->> (rx/from files)
(rx/mapcat (fn [file] (rp/query :library-using-files {:file-id (:id file)})))
(rx/map :id)
(rx/mapcat #(rp/cmd! :get-library-file-references {:file-id %}))
(rx/reduce into [])
(rx/map library-using-files-fetched)))))
@ -292,7 +293,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (or team-id (:current-team-id state))]
(->> (rp/query :team-recent-files {:team-id team-id})
(->> (rp/cmd! :get-team-recent-files {:team-id team-id})
(rx/map recent-files-fetched)))))))
@ -588,7 +589,7 @@
new-name (str name " " (tr "dashboard.copy-suffix"))]
(->> (rp/command! :duplicate-project {:project-id id :name new-name})
(->> (rp/cmd! :duplicate-project {:project-id id :name new-name})
(rx/tap on-success)
(rx/map project-duplicated)
(rx/catch on-error))))))
@ -608,7 +609,7 @@
:or {on-success identity
on-error rx/throw}} (meta params)]
(->> (rp/command! :move-project {:project-id id :team-id team-id})
(->> (rp/cmd! :move-project {:project-id id :team-id team-id})
(rx/tap on-success)
(rx/catch on-error))))))
@ -683,7 +684,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [team-id (uuid/uuid (get-in state [:route :path-params :team-id]))]
(->> (rp/mutation :delete-file {:id id})
(->> (rp/cmd! :delete-file {:id id})
(rx/map #(file-deleted team-id project-id)))))))
;; --- Rename File
@ -706,7 +707,7 @@
ptk/WatchEvent
(watch [_ _ _]
(let [params (select-keys params [:id :name])]
(->> (rp/mutation :rename-file params)
(->> (rp/cmd! :rename-file params)
(rx/ignore))))))
;; --- Set File shared
@ -731,7 +732,7 @@
ptk/WatchEvent
(watch [_ _ _]
(let [params {:id id :is-shared is-shared}]
(->> (rp/mutation :set-file-shared params)
(->> (rp/cmd! :set-file-shared params)
(rx/ignore))))))
;; --- EVENT: create-file
@ -774,7 +775,7 @@
(assoc :name name)
(assoc :features features))]
(->> (rp/mutation! :create-file params)
(->> (rp/cmd! :create-file params)
(rx/tap on-success)
(rx/map #(with-meta (file-created %) (meta it)))
(rx/catch on-error))))))
@ -794,7 +795,7 @@
new-name (str name " " (tr "dashboard.copy-suffix"))]
(->> (rp/command! :duplicate-file {:file-id id :name new-name})
(->> (rp/cmd! :duplicate-file {:file-id id :name new-name})
(rx/tap on-success)
(rx/map file-created)
(rx/catch on-error))))))
@ -816,7 +817,7 @@
(let [{:keys [on-success on-error]
:or {on-success identity
on-error rx/throw}} (meta params)]
(->> (rp/command! :move-files {:ids ids :project-id project-id})
(->> (rp/cmd! :move-files {:ids ids :project-id project-id})
(rx/tap on-success)
(rx/catch on-error))))))
@ -836,8 +837,7 @@
(let [{:keys [on-success on-error]
:or {on-success identity
on-error rx/throw}} (meta params)]
(->> (rp/command! :clone-template {:project-id project-id :template-id template-id})
(->> (rp/cmd! :clone-template {:project-id project-id :template-id template-id})
(rx/tap on-success)
(rx/catch on-error))))))

View file

@ -357,7 +357,7 @@
ptk/WatchEvent
(watch [_ _ _]
(let [params {:id id :name name}]
(->> (rp/mutation :rename-file params)
(->> (rp/cmd! :rename-file params)
(rx/ignore))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.libraries
(:require
[app.common.data :as d]
[app.common.files.features :as ffeat]
[app.common.geom.point :as gpt]
[app.common.logging :as log]
[app.common.pages :as cp]
@ -19,7 +20,7 @@
[app.common.types.components-list :as ctkl]
[app.common.types.container :as ctn]
[app.common.types.file :as ctf]
[app.common.types.file.media-object :as ctfm]
[app.common.types.file.media-object :as ctfm]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape-tree :as ctst]
[app.common.types.typography :as ctt]
@ -359,7 +360,7 @@
(pcb/with-library-data data)
(pcb/update-component id update-fn))]
(rx/of (dch/commit-changes changes))))))
(rx/of (dch/commit-changes changes))))))
(defn duplicate-component
"Create a new component copied from the one with the given id."
@ -428,7 +429,7 @@
component (ctf/get-deleted-component file-data component-id)
page (ctpl/get-page file-data (:main-instance-page component))
; Make a new main instance, with the same id of the original
; Make a new main instance, with the same id of the original
[_main-instance shapes]
(ctn/make-component-instance page
component
@ -446,8 +447,8 @@
changes
shapes)
; restore-component change needs to be done after add main instance
; because when undo changes, the orden is inverse
; restore-component change needs to be done after add main instance
; because when undo changes, the orden is inverse
changes (pcb/restore-component changes component-id)]
(rx/of (dch/commit-changes (assoc changes :file-id library-id)))))))
@ -508,12 +509,12 @@
(cph/clean-loops objects))
changes (reduce
(fn [changes id]
(dwlh/generate-detach-instance changes container id))
(-> (pcb/empty-changes it)
(pcb/with-container container)
(pcb/with-objects objects))
selected)]
(fn [changes id]
(dwlh/generate-detach-instance changes container id))
(-> (pcb/empty-changes it)
(pcb/with-container container)
(pcb/with-objects objects))
selected)]
(rx/of (dch/commit-changes changes))))))
@ -572,8 +573,8 @@
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
(:redo-changes changes)
file))
(rx/of (dch/commit-changes changes))))))
file))
(rx/of (dch/commit-changes changes))))))
(defn update-component
"Modify the component linked to the shape with the given id, in the
@ -624,11 +625,11 @@
(log/debug :msg "UPDATE-COMPONENT finished"
:js/local-changes (log-changes
(:redo-changes local-changes)
file)
(:redo-changes local-changes)
file)
:js/nonlocal-changes (log-changes
(:redo-changes nonlocal-changes)
file))
(:redo-changes nonlocal-changes)
file))
(rx/of
(when (seq (:redo-changes local-changes))
@ -705,48 +706,48 @@
sync-typographies? (or (nil? asset-type) (= asset-type :typographies))
library-changes (reduce
pcb/concat-changes
(pcb/empty-changes it)
[(when sync-components?
(dwlh/generate-sync-library it file-id :components asset-id library-id state))
(when sync-colors?
(dwlh/generate-sync-library it file-id :colors asset-id library-id state))
(when sync-typographies?
(dwlh/generate-sync-library it file-id :typographies asset-id library-id state))])
pcb/concat-changes
(pcb/empty-changes it)
[(when sync-components?
(dwlh/generate-sync-library it file-id :components asset-id library-id state))
(when sync-colors?
(dwlh/generate-sync-library it file-id :colors asset-id library-id state))
(when sync-typographies?
(dwlh/generate-sync-library it file-id :typographies asset-id library-id state))])
file-changes (reduce
pcb/concat-changes
(pcb/empty-changes it)
[(when sync-components?
(dwlh/generate-sync-file it file-id :components asset-id library-id state))
(when sync-colors?
(dwlh/generate-sync-file it file-id :colors asset-id library-id state))
(when sync-typographies?
(dwlh/generate-sync-file it file-id :typographies asset-id library-id state))])
pcb/concat-changes
(pcb/empty-changes it)
[(when sync-components?
(dwlh/generate-sync-file it file-id :components asset-id library-id state))
(when sync-colors?
(dwlh/generate-sync-file it file-id :colors asset-id library-id state))
(when sync-typographies?
(dwlh/generate-sync-file it file-id :typographies asset-id library-id state))])
changes (pcb/concat-changes library-changes file-changes)]
(log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes
(:redo-changes changes)
file))
(:redo-changes changes)
file))
(rx/concat
(rx/of (dm/hide-tag :sync-dialog))
(when (seq (:redo-changes changes))
(rx/of (dch/commit-changes (assoc changes ;; TODO a ver qué pasa con esto
:file-id file-id))))
(when (not= file-id library-id)
;; When we have just updated the library file, give some time for the
;; update to finish, before marking this file as synced.
;; TODO: look for a more precise way of syncing this.
;; Maybe by using the stream (second argument passed to watch)
;; to wait for the corresponding changes-committed and then proceed
;; with the :update-sync mutation.
(rx/concat (rx/timer 3000)
(rp/mutation :update-sync
{:file-id file-id
:library-id library-id})))
(when (and (seq (:redo-changes library-changes))
sync-components?)
(rx/of (sync-file-2nd-stage file-id library-id asset-id))))))))))
(rx/of (dm/hide-tag :sync-dialog))
(when (seq (:redo-changes changes))
(rx/of (dch/commit-changes (assoc changes ;; TODO a ver qué pasa con esto
:file-id file-id))))
(when (not= file-id library-id)
;; When we have just updated the library file, give some time for the
;; update to finish, before marking this file as synced.
;; TODO: look for a more precise way of syncing this.
;; Maybe by using the stream (second argument passed to watch)
;; to wait for the corresponding changes-committed and then proceed
;; with the :update-file-library-sync-status mutation.
(rx/concat (rx/timer 3000)
(rp/cmd! :update-file-library-sync-status
{:file-id file-id
:library-id library-id})))
(when (and (seq (:redo-changes library-changes))
sync-components?)
(rx/of (sync-file-2nd-stage file-id library-id asset-id))))))))))
(defn- sync-file-2nd-stage
"If some components have been modified, we need to launch another synchronization
@ -775,8 +776,8 @@
(dwlh/generate-sync-library it file-id :components asset-id library-id state)])]
(log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes
(:redo-changes changes)
file))
(:redo-changes changes)
file))
(when (seq (:redo-changes changes))
(rx/of (dch/commit-changes (assoc changes :file-id file-id))))))))
@ -788,9 +789,9 @@
ptk/WatchEvent
(watch [_ state _]
(rp/mutation :ignore-sync
{:file-id (get-in state [:workspace-file :id])
:date (dt/now)}))))
(rp/cmd! :ignore-file-library-sync-status
{:file-id (get-in state [:workspace-file :id])
:date (dt/now)}))))
(defn notify-sync-file
[file-id]
@ -852,8 +853,8 @@
(log/info :msg "DETECTED COMPONENTS CHANGED"
:ids (map str components-changed))
(run! st/emit!
(map #(update-component-sync % (:id data))
components-changed)))))]
(map #(update-component-sync % (:id data))
components-changed)))))]
(when components-v2
(->> change-s
@ -880,7 +881,7 @@
ptk/WatchEvent
(watch [_ _ _]
(let [params {:id id :is-shared is-shared}]
(->> (rp/mutation :set-file-shared params)
(->> (rp/cmd! :set-file-shared params)
(rx/ignore))))))
(defn- shared-files-fetched
@ -898,7 +899,7 @@
(ptk/reify ::fetch-shared-files
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :team-shared-files {:team-id team-id})
(->> (rp/cmd! :get-team-shared-files {:team-id team-id})
(rx/map shared-files-fetched)))))
;; --- Link and unlink Files
@ -908,13 +909,16 @@
(ptk/reify ::attach-library
ptk/WatchEvent
(watch [_ state _]
(let [components-v2 (features/active-feature? state :components-v2)
fetched #(assoc-in %2 [:workspace-libraries (:id %1)] %1)
params {:file-id file-id
:library-id library-id}]
(->> (rp/mutation :link-file-to-library params)
(rx/mapcat #(rp/query :file {:id library-id :components-v2 components-v2}))
(rx/map #(partial fetched %)))))))
(let [features (cond-> ffeat/enabled
(features/active-feature? state :components-v2)
(conj "components/v2"))]
(rx/concat
(->> (rp/cmd! :link-file-to-library {:file-id file-id :library-id library-id})
(rx/ignore))
(->> (rp/cmd! :get-file {:id library-id :features features})
(rx/map (fn [file]
(fn [state]
(assoc-in state [:workspace-libraries library-id] file))))))))))
(defn unlink-file-from-library
[file-id library-id]
@ -927,5 +931,5 @@
(watch [_ _ _]
(let [params {:file-id file-id
:library-id library-id}]
(->> (rp/mutation :unlink-file-from-library params)
(->> (rp/cmd! :unlink-file-from-library params)
(rx/ignore))))))

View file

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.features :as ffeat]
[app.common.logging :as log]
[app.common.pages :as cp]
[app.common.pages.changes-spec :as pcs]
@ -18,7 +19,6 @@
[app.config :as cf]
[app.main.data.dashboard :as dd]
[app.main.data.fonts :as df]
[app.main.data.modal :as modal]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwt]
@ -26,7 +26,6 @@
[app.main.repo :as rp]
[app.main.store :as st]
[app.util.http :as http]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[app.util.time :as dt]
[beicon.core :as rx]
@ -138,7 +137,11 @@
(ptk/reify ::persist-changes
ptk/WatchEvent
(watch [_ state _]
(let [features (cond-> #{}
(let [;; this features set does not includes the ffeat/enabled
;; because they are already available on the backend and
;; this request provides a set of features to enable in
;; this request.
features (cond-> #{}
(features/active-feature? state :components-v2)
(conj "components/v2"))
sid (:session-id state)
@ -150,7 +153,7 @@
:features features}]
(when (= file-id (:id params))
(->> (rp/mutation :update-file params)
(->> (rp/cmd! :update-file params)
(rx/mapcat (fn [lagged]
(log/debug :hint "changes persisted" :lagged (count lagged))
(let [lagged (cond->> lagged
@ -285,14 +288,13 @@
ptk/WatchEvent
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)
features (cond-> #{}
features (cond-> ffeat/enabled
(features/active-feature? state :components-v2)
(conj "components/v2"))]
(->> (rx/zip (rp/query! :file-raw {:id file-id :features features})
(->> (rx/zip (rp/cmd! :get-raw-file {:id file-id :features features})
(rp/query! :team-users {:file-id file-id})
(rp/query! :project {:id project-id})
(rp/query! :file-libraries {:file-id file-id})
(rp/cmd! :get-file-libraries {:file-id file-id})
(rp/cmd! :get-profiles-for-file-comments {:file-id file-id :share-id share-id}))
(rx/take 1)
(rx/map (fn [[file-raw users project libraries file-comments-users]]
@ -303,16 +305,7 @@
:file-comments-users file-comments-users}))
(rx/mapcat (fn [{:keys [project] :as bundle}]
(rx/of (ptk/data-event ::bundle-fetched bundle)
(df/load-team-fonts (:team-id project)))))
(rx/catch (fn [err]
(if (and (= (:type err) :restriction)
(= (:code err) :feature-disabled))
(let [team-id (:current-team-id state)]
(rx/of (modal/show
{:type :alert
:message (tr "errors.components-v2")
:on-accept #(st/emit! (rt/nav :dashboard-projects {:team-id team-id}))})))
(rx/throw err)))))))))
(df/load-team-fonts (:team-id project))))))))))
;; --- Helpers

View file

@ -81,7 +81,7 @@
(rx/merge
;; Update the local copy of the thumbnails so we don't need to request it again
(rx/of #(assoc-in % [:workspace-file :thumbnails object-id] data))
(->> (rp/mutation! :upsert-file-object-thumbnail params)
(->> (rp/cmd! :upsert-file-object-thumbnail params)
(rx/ignore))))
(rx/empty))))))))))

View file

@ -14,6 +14,7 @@
[app.common.spec :as us]
[app.config :as cf]
[app.main.data.messages :as msg]
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.util.globals :as glob]
@ -167,6 +168,26 @@
(ts/schedule
#(st/emit! (rt/assign-exception error))))
(defmethod ptk/handle-error :restriction
[{:keys [code] :as error}]
(cond
(= :feature-mismatch code)
(let [message (tr "errors.feature-mismatch" (:feature error))]
(st/emit! (modal/show
{:type :alert
:message message
:on-accept #(prn "kaka")})))
(= :features-not-supported code)
(let [message (tr "errors.feature-not-supported" (:feature error))]
(st/emit! (modal/show
{:type :alert
:message message
:on-accept #(prn "kaka")})))
:else
(ptk/handle-error (assoc error :type :server-error))))
;; This happens when the backed server fails to process the
;; request. This can be caused by an internal assertion or any other
;; uncontrolled error.

View file

@ -16,7 +16,7 @@
(log/set-level! :debug)
(def features-list #{:auto-layout :components-v2})
(def available-features #{:auto-layout :components-v2})
(defn- toggle-feature
[feature]
@ -38,14 +38,14 @@
(defn toggle-feature!
[feature]
(assert (contains? features-list feature) "Not supported feature")
(assert (contains? available-features feature) "Not supported feature")
(st/emit! (toggle-feature feature)))
(defn active-feature?
([feature]
(active-feature? @st/state feature))
([state feature]
(assert (contains? features-list feature) "Not supported feature")
(assert (contains? available-features feature) "Not supported feature")
(contains? (get state :features) feature)))
(def features
@ -57,7 +57,7 @@
(defn use-feature
[feature]
(assert (contains? features-list feature) "Not supported feature")
(assert (contains? available-features feature) "Not supported feature")
(let [active-feature-ref (mf/use-memo (mf/deps feature) #(active-feature feature))
active-feature? (mf/deref active-feature-ref)]
active-feature?))
@ -69,6 +69,6 @@
(when *assert*
;; By default, all features disabled, except in development
;; environment, that are enabled except components-v2
(doseq [f features-list]
(doseq [f available-features]
(when (not= f :components-v2)
(toggle-feature! f)))))

View file

@ -12,6 +12,8 @@
[app.util.http :as http]
[beicon.core :as rx]))
(derive :get-file ::query)
(defn handle-response
[{:keys [status body] :as response}]
(cond
@ -48,7 +50,6 @@
query api."
([id params]
(send-query! id params nil))
([id params {:keys [raw-transit?]}]
(let [decode-transit (if raw-transit?
http/conditional-error-decode-transit
@ -74,14 +75,24 @@
(defn- send-command!
"A simple helper for a common case of sending and receiving transit
data to the penpot mutation api."
[id params {:keys [response-type form-data?]}]
(->> (http/send! {:method :post
:uri (u/join @cf/public-uri "api/rpc/command/" (name id))
:credentials "include"
:body (if form-data? (http/form-data params) (http/transit-data params))
:response-type (or response-type :text)})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)))
[id params {:keys [response-type form-data? raw-transit?]}]
(let [decode-fn (if raw-transit?
http/conditional-error-decode-transit
http/conditional-decode-transit)
method (if (isa? id ::query) :get :post)]
(->> (http/send! {:method method
:uri (u/join @cf/public-uri "api/rpc/command/" (name id))
:credentials "include"
:body (when (= method :post)
(if form-data?
(http/form-data params)
(http/transit-data params)))
:query (when (= method :get)
params)
:response-type (or response-type :text)})
(rx/map decode-fn)
(rx/mapcat handle-response))))
(defn- dispatch [& args] (first args))
@ -93,9 +104,9 @@
[id params]
(send-query! id params))
(defmethod query :file-raw
(defmethod command :get-raw-file
[_id params]
(send-query! :file params {:raw-transit? true}))
(send-command! :get-file params {:raw-transit? true}))
(defmethod mutation :default
[id params]

View file

@ -7,6 +7,7 @@
(ns app.main.ui.dashboard.grid
(:require
[app.common.data.macros :as dm]
[app.common.files.features :as ffeat]
[app.common.logging :as log]
[app.main.data.dashboard :as dd]
[app.main.data.messages :as msg]
@ -34,18 +35,21 @@
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(log/set-level! :info)
(log/set-level! :debug)
;; --- Grid Item Thumbnail
(defn ask-for-thumbnail
"Creates some hooks to handle the files thumbnails cache"
[file]
(wrk/ask! {:cmd :thumbnails/generate
:revn (:revn file)
:file-id (:id file)
:file-name (:name file)
:components-v2 (features/active-feature? :components-v2)}))
(let [features (cond-> ffeat/enabled
(features/active-feature? :components-v2)
(conj "components/v2"))]
(wrk/ask! {:cmd :thumbnails/generate
:revn (:revn file)
:file-id (:id file)
:file-name (:name file)
:features features})))
(mf/defc grid-item-thumbnail
{::mf/wrap [mf/memo]}
@ -61,10 +65,10 @@
(rx/subscribe-on :af)
(rx/subs (fn [{:keys [data fonts] :as params}]
(run! fonts/ensure-loaded! fonts)
(log/info :hint "loaded thumbnail"
:file-id (dm/str (:id file))
:file-name (:name file)
:elapsed (str/ffmt "%ms" (tp)))
(log/debug :hint "loaded thumbnail"
:file-id (dm/str (:id file))
:file-name (:name file)
:elapsed (str/ffmt "%ms" (tp)))
(when-let [node (mf/ref-val container)]
(dom/set-html! node data))))))))

View file

@ -98,22 +98,23 @@
[{:keys [page-id file-id object-id render-embed?]}]
(let [components-v2 (features/use-feature :components-v2)
fetch-state (mf/use-fn
(mf/deps file-id page-id object-id)
(mf/deps file-id page-id object-id components-v2)
(fn []
(->> (rx/zip
(repo/query! :font-variants {:file-id file-id})
(repo/query! :page {:file-id file-id
:page-id page-id
:object-id object-id
:components-v2 components-v2}))
(rx/tap (fn [[fonts]]
(when (seq fonts)
(st/emit! (df/fonts-fetched fonts)))))
(rx/map (comp :objects second))
(rx/map (fn [objects]
(let [objects (render/adapt-objects-for-shape objects object-id)]
{:objects objects
:object (get objects object-id)}))))))
(let [features (cond-> #{} components-v2 (conj "components/v2"))]
(->> (rx/zip
(repo/query! :font-variants {:file-id file-id})
(repo/cmd! :page {:file-id file-id
:page-id page-id
:object-id object-id
:features features}))
(rx/tap (fn [[fonts]]
(when (seq fonts)
(st/emit! (df/fonts-fetched fonts)))))
(rx/map (comp :objects second))
(rx/map (fn [objects]
(let [objects (render/adapt-objects-for-shape objects object-id)]
{:objects objects
:object (get objects object-id)})))))))
{:keys [objects object]} (use-resource fetch-state)]
@ -137,17 +138,18 @@
[{:keys [page-id file-id object-ids render-embed?]}]
(let [components-v2 (features/use-feature :components-v2)
fetch-state (mf/use-fn
(mf/deps file-id page-id)
(mf/deps file-id page-id components-v2)
(fn []
(->> (rx/zip
(repo/query! :font-variants {:file-id file-id})
(repo/query! :page {:file-id file-id
:page-id page-id
:components-v2 components-v2}))
(rx/tap (fn [[fonts]]
(when (seq fonts)
(st/emit! (df/fonts-fetched fonts)))))
(rx/map (comp :objects second)))))
(let [features (cond-> #{} components-v2 (conj "components/v2"))]
(->> (rx/zip
(repo/query! :font-variants {:file-id file-id})
(repo/cmd! :get-page {:file-id file-id
:page-id page-id
:features features}))
(rx/tap (fn [[fonts]]
(when (seq fonts)
(st/emit! (df/fonts-fetched fonts)))))
(rx/map (comp :objects second))))))
objects (use-resource fetch-state)]
@ -204,7 +206,7 @@
[{:keys [file-id embed] :as props}]
(let [fetch (mf/use-fn
(mf/deps file-id)
(fn [] (repo/query! :file {:id file-id})))
(fn [] (repo/cmd! :get-file {:id file-id})))
file (use-resource fetch)
state (mf/use-state nil)]

View file

@ -139,6 +139,7 @@
[{:keys [body headers] :as response}]
(let [contenttype (get headers "content-type")]
(if (and (str/starts-with? contenttype "application/transit+json")
(string? body)
(pos? (count body)))
(assoc response :body (t/decode-str body))
response)))

View file

@ -155,14 +155,15 @@
(->> (r/render-components (:data file) :deleted-components)
(rx/map #(vector (str (:id file) "/deleted-components.svg") %))))
(defn fetch-file-with-libraries [file-id components-v2]
(->> (rx/zip (rp/query :file {:id file-id :components-v2 components-v2})
(rp/query :file-libraries {:file-id file-id}))
(rx/map
(fn [[file file-libraries]]
(let [libraries-ids (->> file-libraries (map :id) (filterv #(not= (:id file) %)))]
(-> file
(assoc :libraries libraries-ids)))))))
(defn fetch-file-with-libraries
[file-id components-v2]
(let [features (cond-> #{} components-v2 (conj "components/v2"))]
(->> (rx/zip (rp/cmd! :get-file {:id file-id :features features})
(rp/cmd! :get-file-libraries {:file-id file-id}))
(rx/map
(fn [[file file-libraries]]
(let [libraries-ids (->> file-libraries (map :id) (filterv #(not= (:id file) %)))]
(assoc file :libraries libraries-ids)))))))
(defn get-component-ref-file
[objects shape]

View file

@ -6,6 +6,7 @@
(ns app.worker.impl
(:require
[app.common.data.macros :as dm]
[app.common.logging :as log]
[app.common.pages.changes :as ch]
[app.common.transit :as t]
@ -36,18 +37,16 @@
(let [data (-> (t/decode-str file-raw) :data)
message (assoc message :data data)]
(reset! state data)
(handler (-> message
(assoc :cmd :selection/initialize-index)))
(handler (-> message
(assoc :cmd :snaps/initialize-index)))))
(handler (assoc message :cmd :selection/initialize-index))
(handler (assoc message :cmd :snaps/initialize-index))))
(defmethod handler :update-page-indices
[{:keys [page-id changes] :as message}]
(let [old-page (get-in @state [:pages-index page-id])]
(let [old-page (dm/get-in @state [:pages-index page-id])]
(swap! state ch/process-changes changes false)
(let [new-page (get-in @state [:pages-index page-id])
(let [new-page (dm/get-in @state [:pages-index page-id])
message (assoc message
:old-page old-page
:new-page new-page)]

View file

@ -15,7 +15,6 @@
[app.common.logging :as log]
[app.common.media :as cm]
[app.common.text :as ct]
[app.common.types.file :as ctf]
[app.common.uuid :as uuid]
[app.main.repo :as rp]
[app.util.http :as http]
@ -128,16 +127,15 @@
(defn create-file
"Create a new file on the back-end"
[context components-v2]
(let [resolve (:resolve context)
file-id (resolve (:file-id context))]
(rp/mutation :create-temp-file
{:id file-id
:name (:name context)
:is-shared (:shared context)
:project-id (:project-id context)
:data (-> ctf/empty-file-data
(assoc :id file-id)
(assoc-in [:options :components-v2] components-v2))})))
(let [resolve-fn (:resolve context)
file-id (resolve-fn (:file-id context))
features (cond-> #{} components-v2 (conj "components/v2"))]
(rp/cmd! :create-temp-file
{:id file-id
:name (:name context)
:is-shared (:shared context)
:project-id (:project-id context)
:features features})))
(defn link-file-libraries
"Create a new file on the back-end"
@ -147,7 +145,7 @@
libraries (->> context :libraries (mapv resolve))]
(->> (rx/from libraries)
(rx/map #(hash-map :file-id file-id :library-id %))
(rx/flat-map (partial rp/mutation :link-file-to-library)))))
(rx/flat-map (partial rp/cmd! :link-file-to-library)))))
(defn send-changes
"Creates batches of changes to be sent to the backend"
@ -165,17 +163,17 @@
(->> (rx/from (d/enumerate batches))
(rx/merge-map
(fn [[i change-batch]]
(->> (rp/mutation :update-temp-file
{:id file-id
:session-id session-id
:revn i
:changes change-batch})
(->> (rp/cmd! :update-temp-file
{:id file-id
:session-id session-id
:revn i
:changes change-batch})
(rx/tap #(do (swap! processed inc)
(progress! context :upload-data @processed total))))))
(rx/map first)
(rx/ignore))
(->> (rp/mutation :persist-temp-file {:id file-id})
(->> (rp/cmd! :persist-temp-file {:id file-id})
;; We use merge to keep some information not stored in back-end
(rx/map #(merge file %))))))

View file

@ -7,6 +7,7 @@
(ns app.worker.thumbnails
(:require
["react-dom/server" :as rds]
[app.common.logging :as log]
[app.common.uri :as u]
[app.config :as cf]
[app.main.fonts :as fonts]
@ -17,6 +18,9 @@
[debug :refer [debug?]]
[rumext.v2 :as mf]))
(log/set-level! :trace)
(defn- handle-response
[{:keys [body status] :as response}]
(cond
@ -48,30 +52,29 @@
(= :request-body-too-large code)))
(defn- request-data-for-thumbnail
[file-id revn components-v2]
(let [path "api/rpc/query/file-data-for-thumbnail"
params {:file-id file-id
:revn revn
:strip-frames-with-thumbnails true
:components-v2 components-v2}
request {:method :get
:uri (u/join @cf/public-uri path)
:credentials "include"
:query params}]
[file-id revn features]
(let [path "api/rpc/command/get-file-data-for-thumbnail"
params {:file-id file-id
:revn revn
:strip-frames-with-thumbnails true
:features features}
request {:method :get
:uri (u/join @cf/public-uri path)
:credentials "include"
:query params}]
(->> (http/send! request)
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))))
(defn- request-thumbnail
[file-id revn]
(let [path "api/rpc/query/file-thumbnail"
(let [path "api/rpc/command/get-file-thumbnail"
params {:file-id file-id
:revn revn}
request {:method :get
:uri (u/join @cf/public-uri path)
:credentials "include"
:query params}]
(->> (http/send! request)
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))))
@ -91,7 +94,7 @@
(defn- persist-thumbnail
[{:keys [file-id data revn fonts]}]
(let [path "api/rpc/mutation/upsert-file-thumbnail"
(let [path "api/rpc/command/upsert-file-thumbnail"
params {:file-id file-id
:revn revn
:props {:fonts fonts}
@ -108,19 +111,22 @@
(rx/map (constantly params)))))
(defmethod impl/handler :thumbnails/generate
[{:keys [file-id revn components-v2] :as message}]
[{:keys [file-id revn features] :as message}]
(letfn [(on-result [{:keys [data props]}]
{:data data
:fonts (:fonts props)})
(on-cache-miss [_]
(->> (request-data-for-thumbnail file-id revn components-v2)
(log/debug :hint "request-thumbnail" :file-id file-id :revn revn :cache "miss")
(->> (request-data-for-thumbnail file-id revn features)
(rx/map render-thumbnail)
(rx/mapcat persist-thumbnail)))]
(if (debug? :disable-thumbnail-cache)
(->> (request-data-for-thumbnail file-id revn components-v2)
(->> (request-data-for-thumbnail file-id revn features)
(rx/map render-thumbnail))
(->> (request-thumbnail file-id revn)
(rx/tap (fn [_]
(log/debug :hint "request-thumbnail" :file-id file-id :revn revn :cache "hit")))
(rx/catch not-found? on-cache-miss)
(rx/map on-result)))))