mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 02:28:18 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
aae78055c8
5 changed files with 75 additions and 44 deletions
|
@ -28,22 +28,27 @@
|
|||
(rx/filter #(= % id))
|
||||
(rx/take 1)))
|
||||
|
||||
(defn thumbnail-stream
|
||||
(defn thumbnail-canvas-blob-stream
|
||||
[object-id]
|
||||
(rx/create
|
||||
(fn [subs]
|
||||
;; We look in the DOM a canvas that 1) matches the id and 2) that it's not empty
|
||||
;; will be empty on first rendering before drawing the thumbnail and we don't want to store that
|
||||
(let [node (dom/query (dm/fmt "canvas.thumbnail-canvas[data-object-id='%'][data-ready='true']" object-id))]
|
||||
(if (some? node)
|
||||
;; Look for the thumbnail canvas to send the data to the backend
|
||||
|
||||
(let [node (dom/query (dm/fmt "canvas.thumbnail-canvas[data-object-id='%'][data-ready='true']" object-id))
|
||||
stopper (->> st/stream
|
||||
(rx/filter (ptk/type? :app.main.data.workspace/finalize-page))
|
||||
(rx/take 1))]
|
||||
(if (some? node)
|
||||
;; Success: we generate the blob (async call)
|
||||
(rx/create
|
||||
(fn [subs]
|
||||
(.toBlob node (fn [blob]
|
||||
(rx/push! subs blob)
|
||||
(rx/end! subs))
|
||||
"image/png")
|
||||
"image/png")))
|
||||
|
||||
;; If we cannot find the node we send `nil` and the upsert will delete the thumbnail
|
||||
(do (rx/push! subs nil)
|
||||
(rx/end! subs)))))))
|
||||
;; Not found, we retry after delay
|
||||
(->> (rx/timer 250)
|
||||
(rx/flat-map #(thumbnail-canvas-blob-stream object-id))
|
||||
(rx/take-until stopper)))))
|
||||
|
||||
(defn clear-thumbnail
|
||||
[page-id frame-id]
|
||||
|
@ -64,7 +69,7 @@
|
|||
(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)
|
||||
blob-result (thumbnail-canvas-blob-stream object-id)
|
||||
params {:file-id file-id :object-id object-id :data nil}]
|
||||
|
||||
(rx/concat
|
||||
|
@ -80,7 +85,7 @@
|
|||
|
||||
(rx/merge-map
|
||||
(fn [data]
|
||||
(if (some? file-id)
|
||||
(if (and (some? data) (some? file-id))
|
||||
(let [params (assoc params :data data)]
|
||||
(rx/merge
|
||||
;; Update the local copy of the thumbnails so we don't need to request it again
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as ts]
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -114,26 +113,39 @@
|
|||
|
||||
generate-thumbnail
|
||||
(mf/use-callback
|
||||
(fn []
|
||||
(let [node @node-ref
|
||||
frame-html (dom/node->xml node)
|
||||
(fn generate-thumbnail []
|
||||
(try
|
||||
;; When starting generating the canvas we mark it as not ready so its not send to back until
|
||||
;; we have time to update it
|
||||
(let [canvas-node (mf/ref-val frame-canvas-ref)]
|
||||
(dom/set-property! canvas-node "data-ready" "false"))
|
||||
(let [node @node-ref]
|
||||
(if (dom/has-children? node)
|
||||
;; The frame-content need to have children in order to generate the thumbnail
|
||||
(let [style-node (dom/query (dm/str "#frame-container-" (:id shape) " style"))
|
||||
|
||||
{:keys [x y width height]} @shape-bb-ref
|
||||
{:keys [x y width height]} @shape-bb-ref
|
||||
viewbox (dm/str x " " y " " width " " height)
|
||||
|
||||
style-node (dom/query (dm/str "#frame-container-" (:id shape) " style"))
|
||||
style-str (or (-> style-node dom/node->xml) "")
|
||||
;; This is way faster than creating a node through the DOM API
|
||||
svg-data
|
||||
(dm/fmt "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"%\" width=\"%\" height=\"%\" fill=\"none\">% %</svg>"
|
||||
viewbox
|
||||
width
|
||||
height
|
||||
(if (some? style-node) (dom/node->xml style-node) "")
|
||||
(dom/node->xml node))
|
||||
|
||||
svg-node
|
||||
(-> (dom/make-node "http://www.w3.org/2000/svg" "svg")
|
||||
(dom/set-property! "version" "1.1")
|
||||
(dom/set-property! "viewBox" (dm/str x " " y " " width " " height))
|
||||
(dom/set-property! "width" width)
|
||||
(dom/set-property! "height" height)
|
||||
(dom/set-property! "fill" "none")
|
||||
(obj/set! "innerHTML" (dm/str style-str frame-html)))
|
||||
img-src (-> svg-node dom/node->xml dom/svg->data-uri)]
|
||||
blob (js/Blob. #js [svg-data] #js {:type "image/svg+xml;charset=utf-8"})
|
||||
|
||||
(reset! image-url img-src))))
|
||||
img-src (.createObjectURL js/URL blob)]
|
||||
(reset! image-url img-src))
|
||||
|
||||
;; Node not yet ready, we schedule a new generation
|
||||
(ts/schedule generate-thumbnail)))
|
||||
|
||||
(catch :default e
|
||||
(.error js/console e)))))
|
||||
|
||||
on-change-frame
|
||||
(mf/use-callback
|
||||
|
|
|
@ -248,16 +248,15 @@
|
|||
(dissoc :content)))
|
||||
|
||||
(defn- is-bool-descendant?
|
||||
[shape all-shapes selected-shape-ids]
|
||||
[[_ shape] objects selected-shape-ids]
|
||||
|
||||
(let [parent-id (:parent-id shape)
|
||||
parent (->> all-shapes
|
||||
(filter #(= (:id %) parent-id))
|
||||
first)]
|
||||
parent (get objects parent-id)]
|
||||
(cond
|
||||
(nil? shape) false ;; failsafe
|
||||
(some #{(:id shape)} selected-shape-ids) false ;; if it is one of the selected shapes, it is considerer not a bool descendant
|
||||
(contains? selected-shape-ids (:id shape)) false ;; if it is one of the selected shapes, it is considerer not a bool descendant
|
||||
(= :bool (:type parent)) true ;; if its parent is of type bool, it is a bool descendant
|
||||
:else (is-bool-descendant? parent all-shapes selected-shape-ids)))) ;; else, check its parent
|
||||
:else (recur [parent-id parent] objects selected-shape-ids)))) ;; else, check its parent
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "shapes-with-children" "page-id" "file-id"]))]
|
||||
|
@ -267,8 +266,13 @@
|
|||
shapes-with-children (unchecked-get props "shapes-with-children")
|
||||
|
||||
;; remove children from bool shapes
|
||||
shape-ids (map :id shapes)
|
||||
shapes-with-children (filter #(not (is-bool-descendant? % shapes-with-children shape-ids)) shapes-with-children)
|
||||
shape-ids (into #{} (map :id) shapes)
|
||||
|
||||
objects (->> shapes-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
||||
objects
|
||||
(into {}
|
||||
(filter #(not (is-bool-descendant? % objects shape-ids)))
|
||||
objects)
|
||||
|
||||
workspace-modifiers (mf/deref refs/workspace-modifiers)
|
||||
shapes (map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers])) shapes)
|
||||
|
@ -276,7 +280,7 @@
|
|||
page-id (unchecked-get props "page-id")
|
||||
file-id (unchecked-get props "file-id")
|
||||
shared-libs (unchecked-get props "shared-libs")
|
||||
objects (->> shapes-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
||||
|
||||
show-caps (some #(and (= :path (:type %)) (gsh/open-path? %)) shapes)
|
||||
|
||||
;; Selrect/points only used for measures and it's the one that changes the most. We separate it
|
||||
|
|
|
@ -264,12 +264,14 @@
|
|||
(defn append-child!
|
||||
[^js el child]
|
||||
(when (some? el)
|
||||
(.appendChild ^js el child)))
|
||||
(.appendChild ^js el child))
|
||||
el)
|
||||
|
||||
(defn remove-child!
|
||||
[^js el child]
|
||||
(when (some? el)
|
||||
(.removeChild ^js el child)))
|
||||
(.removeChild ^js el child))
|
||||
el)
|
||||
|
||||
(defn get-first-child
|
||||
[^js el]
|
||||
|
@ -639,3 +641,13 @@
|
|||
|
||||
{:ascent (.-fontBoundingBoxAscent measure)
|
||||
:descent (.-fontBoundingBoxDescent measure)}))
|
||||
|
||||
(defn clone-node
|
||||
([^js node]
|
||||
(clone-node node true))
|
||||
([^js node deep?]
|
||||
(.cloneNode node deep?)))
|
||||
|
||||
(defn has-children?
|
||||
[^js node]
|
||||
(> (-> node .-children .-length) 0))
|
||||
|
|
|
@ -131,9 +131,7 @@
|
|||
|
||||
(defn ^:export ^boolean debug?
|
||||
[option]
|
||||
(if *assert*
|
||||
(boolean (@*debug* option))
|
||||
false))
|
||||
(boolean (@*debug* option)))
|
||||
|
||||
(defn ^:export toggle-debug [name] (let [option (keyword name)]
|
||||
(if (debug? option)
|
||||
|
|
Loading…
Add table
Reference in a new issue