diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 442c43b47..fcbd882bb 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -190,7 +190,16 @@ (conj (:id shape))))] (reduce-objects objects (complement frame-shape?) add-frame []))) +(defn get-root-objects + "Get all the objects under the root object" + [objects] + (let [add-shape + (fn [result shape] + (conj result shape))] + (reduce-objects objects (complement frame-shape?) add-shape []))) + (defn get-root-shapes + "Get all shapes that are not frames" [objects] (let [add-shape (fn [result shape] @@ -688,11 +697,11 @@ (defn start-page-index [objects] - (with-meta objects {::index-frames (get-frames objects)})) + (with-meta objects {::index-frames (get-frames (with-meta objects nil))})) (defn update-page-index [objects] - (with-meta objects {::index-frames (get-frames objects)})) + (with-meta objects {::index-frames (get-frames (with-meta objects nil))})) (defn start-object-indices [file] diff --git a/frontend/src/app/main/data/workspace/persistence.cljs b/frontend/src/app/main/data/workspace/persistence.cljs index 64c237b69..8536e6074 100644 --- a/frontend/src/app/main/data/workspace/persistence.cljs +++ b/frontend/src/app/main/data/workspace/persistence.cljs @@ -157,7 +157,7 @@ (->> (rx/from frame-updates) (rx/flat-map (fn [[page-id frames]] (->> frames (map #(vector page-id %))))) - (rx/map (fn [[page-id frame-id]] (dwt/update-thumbnail page-id frame-id)))) + (rx/map (fn [[page-id frame-id]] (dwt/update-thumbnail (:id file) page-id frame-id)))) (->> (rx/of lagged) (rx/mapcat seq) (rx/map #(shapes-changes-persisted file-id %))))))) diff --git a/frontend/src/app/main/data/workspace/thumbnails.cljs b/frontend/src/app/main/data/workspace/thumbnails.cljs index 1a97606df..7ca84cda1 100644 --- a/frontend/src/app/main/data/workspace/thumbnails.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails.cljs @@ -56,30 +56,35 @@ (defn update-thumbnail "Updates the thumbnail information for the given frame `id`" - [page-id frame-id] - (ptk/reify ::update-thumbnail - ptk/WatchEvent - (watch [_ state _] - (let [object-id (dm/str page-id frame-id) - file-id (:current-file-id state) - blob-result (thumbnail-stream object-id)] + ([page-id frame-id] + (update-thumbnail nil page-id frame-id)) - (->> blob-result - (rx/merge-map - (fn [blob] - (if (some? blob) - (wapi/read-file-as-data-url blob) - (rx/of nil)))) + ([file-id page-id frame-id] + (ptk/reify ::update-thumbnail + ptk/WatchEvent + (watch [_ state _] + (let [object-id (dm/str page-id frame-id) + file-id (or file-id (:current-file-id state)) + blob-result (thumbnail-stream object-id)] - (rx/merge-map - (fn [data] - (when (some? file-id) - (let [params {:file-id file-id :object-id object-id :data data}] - (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) - (rx/ignore)))))))))))) + (->> blob-result + (rx/merge-map + (fn [blob] + (if (some? blob) + (wapi/read-file-as-data-url blob) + (rx/of nil)))) + + (rx/merge-map + (fn [data] + (if (some? file-id) + (let [params {:file-id file-id :object-id object-id :data data}] + (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) + (rx/ignore)))) + + (rx/empty)))))))))) (defn- extract-frame-changes "Process a changes set in a commit to extract the frames that are changing" diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs index c9f62c7b8..61a4fc00f 100644 --- a/frontend/src/app/main/render.cljs +++ b/frontend/src/app/main/render.cljs @@ -62,10 +62,10 @@ (defn- calculate-dimensions [objects] (let [rect - (->> (cph/get-immediate-children objects) + (->> (cph/get-root-objects objects) (map #(if (some? (:children-bounds %)) (:children-bounds %) - (:selrect %))) + (gsh/points->selrect (:points %)))) (gsh/join-selrects))] (-> rect (update :x mth/finite 0) @@ -82,9 +82,10 @@ (mf/fnc frame-wrapper [{:keys [shape] :as props}] - (let [childs (mapv #(get objects %) (:shapes shape)) + (let [render-thumbnails? (mf/use-ctx muc/render-thumbnails) + childs (mapv #(get objects %) (:shapes shape)) shape (gsh/transform-shape shape)] - (if (some? (:thumbnail shape)) + (if (and render-thumbnails? (some? (:thumbnail shape))) [:& frame/frame-thumbnail {:shape shape :bounds (:children-bounds shape)}] [:& frame-shape {:shape shape :childs childs}]))))) @@ -221,52 +222,37 @@ vbox (format-viewbox dim) bgcolor (dm/get-in data [:options :background] default-color) - frame-wrapper - (mf/use-memo - (mf/deps objects) - #(frame-wrapper-factory objects)) - shape-wrapper (mf/use-memo (mf/deps objects) #(shape-wrapper-factory objects))] - [:& (mf/provider embed/context) {:value render-embed?} - [:& (mf/provider export/include-metadata-ctx) {:value include-metadata?} - [:svg {:view-box vbox - :version "1.1" - :xmlns "http://www.w3.org/2000/svg" - :xmlnsXlink "http://www.w3.org/1999/xlink" - :xmlns:penpot (when include-metadata? "https://penpot.app/xmlns") - :style {:width "100%" - :height "100%" - :background bgcolor} - :fill "none"} + [:& (mf/provider muc/render-thumbnails) {:value thumbnails?} + [:& (mf/provider embed/context) {:value render-embed?} + [:& (mf/provider export/include-metadata-ctx) {:value include-metadata?} + [:svg {:view-box vbox + :version "1.1" + :xmlns "http://www.w3.org/2000/svg" + :xmlnsXlink "http://www.w3.org/1999/xlink" + :xmlns:penpot (when include-metadata? "https://penpot.app/xmlns") + :style {:width "100%" + :height "100%" + :background bgcolor} + :fill "none"} - (when include-metadata? - [:& export/export-page {:options (:options data)}]) + (when include-metadata? + [:& export/export-page {:options (:options data)}]) - (let [shapes (->> shapes - (remove cph/frame-shape?) - (mapcat #(cph/get-children-with-self objects (:id %)))) - fonts (ff/shapes->fonts shapes)] - [:& ff/fontfaces-style {:fonts fonts}]) + (let [shapes (->> shapes + (remove cph/frame-shape?) + (mapcat #(cph/get-children-with-self objects (:id %)))) + fonts (ff/shapes->fonts shapes)] + [:& ff/fontfaces-style {:fonts fonts}]) - (for [item shapes] - (let [frame? (= (:type item) :frame)] - (cond - (and frame? thumbnails? (some? (:thumbnail item))) - [:> shape-container {:shape item} - [:& frame/frame-thumbnail {:shape item :bounds (:children-bounds item)}]] - - frame? - [:> shape-container {:shape item} - [:& frame-wrapper {:shape item - :key (:id item)}]] - :else - [:& shape-wrapper {:shape item - :key (:id item)}])))]]])) + (for [item shapes] + [:& shape-wrapper {:shape item + :key (:id item)}])]]]])) ;; Component that serves for render frame thumbnails, mainly used in @@ -278,7 +264,7 @@ (let [frame-id (:id frame) include-metadata? (mf/use-ctx export/include-metadata-ctx) - bounds (or (:children-bounds frame) (:selrect frame)) + bounds (or (:children-bounds frame) (gsh/points->rect (:points frame))) modifier (mf/with-memo [(:x bounds) (:y bounds)] diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index d430ea5f2..34a3518c9 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -23,3 +23,4 @@ (def current-file-id (mf/create-context nil)) (def scroll-ctx (mf/create-context nil)) (def active-frames-ctx (mf/create-context nil)) +(def render-thumbnails (mf/create-context nil))