mirror of
https://github.com/penpot/penpot.git
synced 2025-06-02 11:31:39 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
f7dbb4f944
18 changed files with 190 additions and 100 deletions
|
@ -7,6 +7,7 @@
|
||||||
(ns app.common.pages.helpers
|
(ns app.common.pages.helpers
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.spec.page :as spec.page]
|
[app.common.spec.page :as spec.page]
|
||||||
|
@ -92,7 +93,7 @@
|
||||||
"Returns a vector of parents of the specified shape."
|
"Returns a vector of parents of the specified shape."
|
||||||
[objects shape-id]
|
[objects shape-id]
|
||||||
(loop [result [] id shape-id]
|
(loop [result [] id shape-id]
|
||||||
(if-let [parent-id (->> id (get objects) :parent-id)]
|
(if-let [parent-id (dm/get-in objects [id :parent-id])]
|
||||||
(recur (conj result parent-id) parent-id)
|
(recur (conj result parent-id) parent-id)
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,17 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.set :as set]))
|
[clojure.set :as set]))
|
||||||
|
|
||||||
(defn calculate-frame-z-index [z-index frame-id objects]
|
(defn calculate-frame-z-index
|
||||||
|
[z-index frame-id base-idx objects]
|
||||||
|
|
||||||
(let [is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
(let [is-frame? (fn [id] (= :frame (get-in objects [id :type])))
|
||||||
frame-shapes (->> objects (vals) (filterv #(= (:frame-id %) frame-id)))
|
|
||||||
children (or (get-in objects [frame-id :shapes]) [])]
|
children (or (get-in objects [frame-id :shapes]) [])]
|
||||||
|
|
||||||
(if (empty? children)
|
(if (empty? children)
|
||||||
z-index
|
z-index
|
||||||
(loop [current (peek children)
|
(loop [current (peek children)
|
||||||
pending (pop children)
|
pending (pop children)
|
||||||
current-idx (count frame-shapes)
|
current-idx base-idx
|
||||||
z-index z-index]
|
z-index z-index]
|
||||||
|
|
||||||
(let [children (get-in objects [current :shapes])
|
(let [children (get-in objects [current :shapes])
|
||||||
|
@ -46,10 +47,15 @@
|
||||||
[objects]
|
[objects]
|
||||||
|
|
||||||
(let [frames (cph/get-frames objects)
|
(let [frames (cph/get-frames objects)
|
||||||
z-index (calculate-frame-z-index {} uuid/zero objects)]
|
|
||||||
|
by-frame (cph/objects-by-frame objects)
|
||||||
|
frame-base-idx (d/update-vals by-frame count)
|
||||||
|
|
||||||
|
z-index (calculate-frame-z-index {} uuid/zero (get frame-base-idx uuid/zero) objects)]
|
||||||
(->> frames
|
(->> frames
|
||||||
(map :id)
|
(reduce
|
||||||
(reduce #(calculate-frame-z-index %1 %2 objects) z-index))))
|
(fn [z-index {:keys [id]}]
|
||||||
|
(calculate-frame-z-index z-index id (get frame-base-idx id) objects)) z-index))))
|
||||||
|
|
||||||
(defn update-z-index
|
(defn update-z-index
|
||||||
"Updates the z-index given a set of ids to change and the old and new objects
|
"Updates the z-index given a set of ids to change and the old and new objects
|
||||||
|
@ -65,10 +71,13 @@
|
||||||
(map :id)
|
(map :id)
|
||||||
(filter #(contains? changed-frames %)))
|
(filter #(contains? changed-frames %)))
|
||||||
|
|
||||||
z-index (calculate-frame-z-index z-index uuid/zero new-objects)]
|
by-frame (cph/objects-by-frame new-objects)
|
||||||
|
frame-base-idx (d/update-vals by-frame count)
|
||||||
|
z-index (calculate-frame-z-index z-index uuid/zero (get frame-base-idx uuid/zero) new-objects)]
|
||||||
|
|
||||||
(->> frames
|
(->> frames
|
||||||
(reduce #(calculate-frame-z-index %1 %2 new-objects) z-index))))
|
(reduce (fn [z-index id]
|
||||||
|
(calculate-frame-z-index z-index id (get frame-base-idx id) new-objects)) z-index))))
|
||||||
|
|
||||||
(defn generate-child-parent-index
|
(defn generate-child-parent-index
|
||||||
[objects]
|
[objects]
|
||||||
|
@ -84,10 +93,10 @@
|
||||||
(generate-child-all-parents-index objects (vals objects)))
|
(generate-child-all-parents-index objects (vals objects)))
|
||||||
|
|
||||||
([objects shapes]
|
([objects shapes]
|
||||||
(let [xf-parents (comp
|
(let [shape->entry
|
||||||
(map :id)
|
(fn [shape]
|
||||||
(map #(vector % (cph/get-parent-ids objects %))))]
|
[(:id shape) (cph/get-parent-ids objects (:id shape))])]
|
||||||
(into {} xf-parents shapes))))
|
(into {} (map shape->entry) shapes))))
|
||||||
|
|
||||||
(defn create-clip-index
|
(defn create-clip-index
|
||||||
"Retrieves the mask information for an object"
|
"Retrieves the mask information for an object"
|
||||||
|
|
|
@ -125,25 +125,34 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
grid-column-gap: 8px;
|
grid-column-gap: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
& .back-button {
|
& .back-button {
|
||||||
cursor: pointer;
|
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
transform: rotate(180deg);
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
fill: $color-white;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
svg {
|
svg {
|
||||||
fill: $color-primary;
|
fill: $color-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& svg {
|
& .focus-name {
|
||||||
fill: $color-white;
|
overflow: hidden;
|
||||||
}
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .focus-mode {
|
& .focus-mode {
|
||||||
|
|
|
@ -115,17 +115,24 @@
|
||||||
(rx/filter (ptk/type? ::dwp/bundle-fetched))
|
(rx/filter (ptk/type? ::dwp/bundle-fetched))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/map deref)
|
(rx/map deref)
|
||||||
(rx/mapcat (fn [bundle]
|
(rx/mapcat
|
||||||
(let [team-id (-> bundle :project :team-id)]
|
(fn [bundle]
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (dwn/initialize team-id file-id)
|
(rx/of (dwc/initialize-indices bundle))
|
||||||
(dwp/initialize-file-persistence file-id)
|
|
||||||
(dwc/initialize-indices bundle))
|
|
||||||
|
|
||||||
(->> stream
|
(->> (rx/of bundle)
|
||||||
(rx/filter #(= ::dwc/index-initialized %))
|
(rx/mapcat
|
||||||
(rx/take 1)
|
(fn [bundle]
|
||||||
(rx/map #(file-initialized bundle))))))))))
|
(let [bundle (assoc bundle :file (t/decode-str (:file-raw bundle)))
|
||||||
|
team-id (dm/get-in bundle [:project :team-id])]
|
||||||
|
(rx/merge
|
||||||
|
(rx/of (dwn/initialize team-id file-id)
|
||||||
|
(dwp/initialize-file-persistence file-id))
|
||||||
|
|
||||||
|
(->> stream
|
||||||
|
(rx/filter #(= ::dwc/index-initialized %))
|
||||||
|
(rx/take 1)
|
||||||
|
(rx/map #(file-initialized bundle))))))))))))))
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ _ _]
|
(effect [_ _ _]
|
||||||
|
|
|
@ -48,13 +48,12 @@
|
||||||
;; --- Selection Index Handling
|
;; --- Selection Index Handling
|
||||||
|
|
||||||
(defn initialize-indices
|
(defn initialize-indices
|
||||||
[{:keys [file] :as bundle}]
|
[{:keys [file-raw] :as bundle}]
|
||||||
(ptk/reify ::setup-selection-index
|
(ptk/reify ::setup-selection-index
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(let [msg {:cmd :initialize-indices
|
(let [msg {:cmd :initialize-indices
|
||||||
:file-id (:id file)
|
:file-raw file-raw}]
|
||||||
:data (:data file)}]
|
|
||||||
(->> (uw/ask! msg)
|
(->> (uw/ask! msg)
|
||||||
(rx/map (constantly ::index-initialized)))))))
|
(rx/map (constantly ::index-initialized)))))))
|
||||||
|
|
||||||
|
|
|
@ -251,8 +251,8 @@
|
||||||
(rp/query :project {:id project-id})
|
(rp/query :project {:id project-id})
|
||||||
(rp/query :file-libraries {:file-id file-id}))
|
(rp/query :file-libraries {:file-id file-id}))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/map (fn [[file users project libraries]]
|
(rx/map (fn [[file-raw users project libraries]]
|
||||||
{:file file
|
{:file-raw file-raw
|
||||||
:users users
|
:users users
|
||||||
:project project
|
:project project
|
||||||
:libraries libraries}))
|
:libraries libraries}))
|
||||||
|
|
|
@ -421,8 +421,11 @@
|
||||||
(assoc :position (if (= (:axis %) :x)
|
(assoc :position (if (= (:axis %) :x)
|
||||||
(+ (:position %) (- (:x new-frame) (:x frame)))
|
(+ (:position %) (- (:x new-frame) (:x frame)))
|
||||||
(+ (:position %) (- (:y new-frame) (:y frame))))))))]
|
(+ (:position %) (- (:y new-frame) (:y frame))))))))]
|
||||||
(conj g
|
|
||||||
(into {} (map (juxt :id identity) new-guides)))))
|
(if-not (empty? new-guides)
|
||||||
|
(conj g
|
||||||
|
(into {} (map (juxt :id identity) new-guides)))
|
||||||
|
{})))
|
||||||
guides
|
guides
|
||||||
frames)]
|
frames)]
|
||||||
(-> (pcb/with-page changes page)
|
(-> (pcb/with-page changes page)
|
||||||
|
|
|
@ -378,7 +378,7 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(dissoc :workspace-modifiers)
|
(dissoc :workspace-modifiers)
|
||||||
(update :workspace-local dissoc :current-move-selected)))))
|
(dissoc ::current-move-selected)))))
|
||||||
|
|
||||||
;; -- Resize --------------------------------------------------------
|
;; -- Resize --------------------------------------------------------
|
||||||
|
|
||||||
|
@ -721,15 +721,15 @@
|
||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (nil? (get-in state [:workspace-local :current-move-selected]))
|
(if (nil? (get state ::current-move-selected))
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:workspace-local :transform] :move)
|
(assoc-in [:workspace-local :transform] :move)
|
||||||
(assoc-in [:workspace-local :current-move-selected] same-event))
|
(assoc ::current-move-selected same-event))
|
||||||
state))
|
state))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(if (= same-event (get-in state [:workspace-local :current-move-selected]))
|
(if (= same-event (get state ::current-move-selected))
|
||||||
(let [selected (wsh/lookup-selected state {:omit-blocked? true})
|
(let [selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||||
nudge (get-in state [:profile :props :nudge] {:big 10 :small 1})
|
nudge (get-in state [:profile :props :nudge] {:big 10 :small 1})
|
||||||
move-events (->> stream
|
move-events (->> stream
|
||||||
|
@ -744,10 +744,10 @@
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(->> move-events
|
(->> move-events
|
||||||
(rx/take-until stopper)
|
|
||||||
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
|
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
|
||||||
(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
|
(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
|
||||||
(rx/map (partial set-modifiers selected)))
|
(rx/map (partial set-modifiers selected))
|
||||||
|
(rx/take-until stopper))
|
||||||
(rx/of (move-selected direction shift?)))
|
(rx/of (move-selected direction shift?)))
|
||||||
|
|
||||||
(rx/of (apply-modifiers selected)
|
(rx/of (apply-modifiers selected)
|
||||||
|
|
|
@ -35,8 +35,7 @@
|
||||||
(rx/throw {:type :validation
|
(rx/throw {:type :validation
|
||||||
:code :request-body-too-large})
|
:code :request-body-too-large})
|
||||||
|
|
||||||
(and (>= status 400)
|
(and (>= status 400) (map? body))
|
||||||
(map? body))
|
|
||||||
(rx/throw body)
|
(rx/throw body)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
|
@ -49,13 +48,19 @@
|
||||||
(defn- send-query!
|
(defn- send-query!
|
||||||
"A simple helper for send and receive transit data on the penpot
|
"A simple helper for send and receive transit data on the penpot
|
||||||
query api."
|
query api."
|
||||||
[id params]
|
([id params]
|
||||||
(->> (http/send! {:method :get
|
(send-query! id params nil))
|
||||||
:uri (u/join base-uri "api/rpc/query/" (name id))
|
|
||||||
:credentials "include"
|
([id params {:keys [raw-transit?]}]
|
||||||
:query params})
|
(let [decode-transit (if raw-transit?
|
||||||
(rx/map http/conditional-decode-transit)
|
identity
|
||||||
(rx/mapcat handle-response)))
|
(partial rx/map http/conditional-decode-transit))]
|
||||||
|
(->> (http/send! {:method :get
|
||||||
|
:uri (u/join base-uri "api/rpc/query/" (name id))
|
||||||
|
:credentials "include"
|
||||||
|
:query params})
|
||||||
|
(decode-transit)
|
||||||
|
(rx/mapcat handle-response)))))
|
||||||
|
|
||||||
(defn- send-mutation!
|
(defn- send-mutation!
|
||||||
"A simple helper for a common case of sending and receiving transit
|
"A simple helper for a common case of sending and receiving transit
|
||||||
|
@ -77,6 +82,10 @@
|
||||||
[id params]
|
[id params]
|
||||||
(send-query! id params))
|
(send-query! id params))
|
||||||
|
|
||||||
|
(defmethod query :file
|
||||||
|
[id params]
|
||||||
|
(send-query! id params {:raw-transit? true}))
|
||||||
|
|
||||||
(defmethod mutation :default
|
(defmethod mutation :default
|
||||||
[id params]
|
[id params]
|
||||||
(send-mutation! id params))
|
(send-mutation! id params))
|
||||||
|
|
|
@ -50,17 +50,17 @@
|
||||||
(let [mask (unchecked-get props "mask")
|
(let [mask (unchecked-get props "mask")
|
||||||
render-id (mf/use-ctx muc/render-ctx)
|
render-id (mf/use-ctx muc/render-ctx)
|
||||||
svg-text? (and (= :text (:type mask)) (some? (:position-data mask)))
|
svg-text? (and (= :text (:type mask)) (some? (:position-data mask)))
|
||||||
|
|
||||||
;; This factory is generic, it's used for viewer, workspace and handoff.
|
;; This factory is generic, it's used for viewer, workspace and handoff.
|
||||||
;; These props are generated in viewer wrappers only, in the rest of the
|
;; These props are generated in viewer wrappers only, in the rest of the
|
||||||
;; cases these props will be nil, not affecting the code.
|
;; cases these props will be nil, not affecting the code.
|
||||||
fixed? (unchecked-get props "fixed?")
|
fixed? (unchecked-get props "fixed?")
|
||||||
delta (unchecked-get props "delta")
|
delta (unchecked-get props "delta")
|
||||||
mask-for-bb (-> (gsh/transform-shape mask)
|
mask-bb (-> (gsh/transform-shape mask)
|
||||||
(cond-> fixed? (gsh/move delta)))
|
(cond-> fixed? (gsh/move delta))
|
||||||
|
(:points))
|
||||||
|
|
||||||
mask-bb (cond
|
mask-bb-rect (gsh/points->rect mask-bb)]
|
||||||
svg-text? (gst/position-data-points mask-for-bb)
|
|
||||||
:else (:points mask-for-bb))]
|
|
||||||
[:defs
|
[:defs
|
||||||
[:filter {:id (filter-id render-id mask)}
|
[:filter {:id (filter-id render-id mask)}
|
||||||
[:feFlood {:flood-color "white"
|
[:feFlood {:flood-color "white"
|
||||||
|
@ -81,7 +81,12 @@
|
||||||
;; When te shape is a text we pass to the shape the info and disable the filter.
|
;; When te shape is a text we pass to the shape the info and disable the filter.
|
||||||
;; There is a bug in Firefox with filters and texts. We change the text to white at shape level
|
;; There is a bug in Firefox with filters and texts. We change the text to white at shape level
|
||||||
[:mask {:class "mask-shape"
|
[:mask {:class "mask-shape"
|
||||||
:id (mask-id render-id mask)}
|
:id (mask-id render-id mask)
|
||||||
|
:x (:x mask-bb-rect)
|
||||||
|
:y (:y mask-bb-rect)
|
||||||
|
:width (:width mask-bb-rect)
|
||||||
|
:height (:height mask-bb-rect)
|
||||||
|
:mask-units "userSpaceOnUse"}
|
||||||
[:g {:filter (when-not svg-text? (filter-url render-id mask))}
|
[:g {:filter (when-not svg-text? (filter-url render-id mask))}
|
||||||
[:& shape-wrapper {:shape (-> mask (dissoc :shadow :blur) (assoc :is-mask? true))}]]]])))
|
[:& shape-wrapper {:shape (-> mask (dissoc :shadow :blur) (assoc :is-mask? true))}]]]])))
|
||||||
|
|
||||||
|
|
|
@ -38,15 +38,13 @@
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
(mf/deps transforms)
|
(mf/deps transforms)
|
||||||
(fn []
|
(fn []
|
||||||
(when (and (nil? @prev-transforms)
|
(when (and (empty? @prev-modifiers) (d/not-empty? modifiers))
|
||||||
(some? transforms))
|
|
||||||
(utils/start-transform! node shapes))
|
(utils/start-transform! node shapes))
|
||||||
|
|
||||||
(when (some? modifiers)
|
(when (d/not-empty? modifiers)
|
||||||
(utils/update-transform! node shapes transforms modifiers))
|
(utils/update-transform! node shapes transforms modifiers))
|
||||||
|
|
||||||
(when (and (some? @prev-modifiers)
|
(when (and (d/not-empty? @prev-modifiers) (empty? modifiers))
|
||||||
(empty? modifiers))
|
|
||||||
(utils/remove-transform! node @prev-shapes))
|
(utils/remove-transform! node @prev-shapes))
|
||||||
|
|
||||||
(reset! prev-modifiers modifiers)
|
(reset! prev-modifiers modifiers)
|
||||||
|
|
|
@ -498,11 +498,9 @@
|
||||||
[:div#layers.tool-window
|
[:div#layers.tool-window
|
||||||
(if (d/not-empty? focus)
|
(if (d/not-empty? focus)
|
||||||
[:div.tool-window-bar
|
[:div.tool-window-bar
|
||||||
[:div.focus-title
|
[:div.focus-title {:on-click #(st/emit! (dw/toggle-focus-mode))}
|
||||||
[:button.back-button
|
[:button.back-button i/arrow-slide]
|
||||||
{:on-click #(st/emit! (dw/toggle-focus-mode))}
|
[:div.focus-name (or title (tr "workspace.focus.selection"))]
|
||||||
i/arrow-slide]
|
|
||||||
[:span (or title (tr "workspace.focus.selection"))]
|
|
||||||
[:div.focus-mode (tr "workspace.focus.focus-mode")]]]
|
[:div.focus-mode (tr "workspace.focus.focus-mode")]]]
|
||||||
|
|
||||||
filter-component)
|
filter-component)
|
||||||
|
|
|
@ -150,10 +150,14 @@
|
||||||
|
|
||||||
(when (or (= (dom/get-tag-name node) "mask")
|
(when (or (= (dom/get-tag-name node) "mask")
|
||||||
(= (dom/get-tag-name node) "filter"))
|
(= (dom/get-tag-name node) "filter"))
|
||||||
(dom/set-attribute! node "data-old-x" (dom/get-attribute node "x"))
|
(let [old-x (dom/get-attribute node "x")
|
||||||
(dom/set-attribute! node "data-old-y" (dom/get-attribute node "y"))
|
old-y (dom/get-attribute node "y")
|
||||||
(dom/set-attribute! node "data-old-width" (dom/get-attribute node "width"))
|
old-width (dom/get-attribute node "width")
|
||||||
(dom/set-attribute! node "data-old-height" (dom/get-attribute node "height"))))))))
|
old-height (dom/get-attribute node "height")]
|
||||||
|
(dom/set-attribute! node "data-old-x" old-x)
|
||||||
|
(dom/set-attribute! node "data-old-y" old-y)
|
||||||
|
(dom/set-attribute! node "data-old-width" old-width)
|
||||||
|
(dom/set-attribute! node "data-old-height" old-height))))))))
|
||||||
|
|
||||||
(defn set-transform-att!
|
(defn set-transform-att!
|
||||||
[node att value]
|
[node att value]
|
||||||
|
@ -208,10 +212,19 @@
|
||||||
;; The shape width/height will be automaticaly setup when the modifiers are applied
|
;; The shape width/height will be automaticaly setup when the modifiers are applied
|
||||||
nil
|
nil
|
||||||
|
|
||||||
|
(or (= (dom/get-tag-name node) "mask")
|
||||||
|
(= (dom/get-tag-name node) "filter"))
|
||||||
|
(do
|
||||||
|
(dom/remove-attribute! node "data-old-x")
|
||||||
|
(dom/remove-attribute! node "data-old-y")
|
||||||
|
(dom/remove-attribute! node "data-old-width")
|
||||||
|
(dom/remove-attribute! node "data-old-height"))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(let [old-transform (dom/get-attribute node "data-old-transform")]
|
(let [old-transform (dom/get-attribute node "data-old-transform")]
|
||||||
(when-not (some? old-transform)
|
(if (some? old-transform)
|
||||||
(dom/remove-attribute! node "data-old-transform")
|
(do (dom/remove-attribute! node "data-old-transform")
|
||||||
|
(dom/set-attribute! node "transform" old-transform))
|
||||||
(dom/remove-attribute! node "transform")))))))))
|
(dom/remove-attribute! node "transform")))))))))
|
||||||
|
|
||||||
(defn format-viewbox [vbox]
|
(defn format-viewbox [vbox]
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
(ns app.util.worker
|
(ns app.util.worker
|
||||||
"A lightweight layer on top of webworkers api."
|
"A lightweight layer on top of webworkers api."
|
||||||
(:require
|
(:require
|
||||||
[app.common.transit :as t]
|
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.globals :refer [global]]
|
[app.util.globals :refer [global]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
[app.worker.messages :as wm]
|
||||||
[beicon.core :as rx]))
|
[beicon.core :as rx]))
|
||||||
|
|
||||||
(declare handle-response)
|
(declare handle-response)
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
(rx/take-while #(not (:completed %)) ob)
|
(rx/take-while #(not (:completed %)) ob)
|
||||||
(rx/take 1 ob)))
|
(rx/take 1 ob)))
|
||||||
|
|
||||||
data (t/encode-str message)
|
data (wm/encode message)
|
||||||
instance (:instance worker)]
|
instance (:instance worker)]
|
||||||
|
|
||||||
(if (some? instance)
|
(if (some? instance)
|
||||||
|
@ -71,11 +71,10 @@
|
||||||
|
|
||||||
handle-message
|
handle-message
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [data (.-data event)
|
(let [message (wm/decode (.-data event))]
|
||||||
data (t/decode-str data)]
|
(if (:error message)
|
||||||
(if (:error data)
|
(on-error (:error message))
|
||||||
(on-error (:error data))
|
(rx/push! bus message))))
|
||||||
(rx/push! bus data))))
|
|
||||||
|
|
||||||
handle-error
|
handle-error
|
||||||
(fn [error]
|
(fn [error]
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.transit :as t]
|
|
||||||
[app.worker.export]
|
[app.worker.export]
|
||||||
[app.worker.impl :as impl]
|
[app.worker.impl :as impl]
|
||||||
[app.worker.import]
|
[app.worker.import]
|
||||||
|
[app.worker.messages :as wm]
|
||||||
[app.worker.selection]
|
[app.worker.selection]
|
||||||
[app.worker.snaps]
|
[app.worker.snaps]
|
||||||
[app.worker.thumbnails]
|
[app.worker.thumbnails]
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
[{:keys [sender-id payload] :as message}]
|
[{:keys [sender-id payload] :as message}]
|
||||||
(us/assert ::message message)
|
(us/assert ::message message)
|
||||||
(letfn [(post [msg]
|
(letfn [(post [msg]
|
||||||
(let [msg (-> msg (assoc :reply-to sender-id) (t/encode-str))]
|
(let [msg (-> msg (assoc :reply-to sender-id) (wm/encode))]
|
||||||
(.postMessage js/self msg)))
|
(.postMessage js/self msg)))
|
||||||
|
|
||||||
(reply [result]
|
(reply [result]
|
||||||
|
@ -91,8 +91,8 @@
|
||||||
"Sends to the client a notification that its messages have been dropped"
|
"Sends to the client a notification that its messages have been dropped"
|
||||||
[{:keys [sender-id] :as message}]
|
[{:keys [sender-id] :as message}]
|
||||||
(us/assert ::message message)
|
(us/assert ::message message)
|
||||||
(.postMessage js/self (t/encode-str {:reply-to sender-id
|
(.postMessage js/self (wm/encode {:reply-to sender-id
|
||||||
:dropped true})))
|
:dropped true})))
|
||||||
|
|
||||||
(defn subscribe-buffer-messages
|
(defn subscribe-buffer-messages
|
||||||
"Creates a subscription to process the buffer messages"
|
"Creates a subscription to process the buffer messages"
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
[event]
|
[event]
|
||||||
(when (nil? (.-source event))
|
(when (nil? (.-source event))
|
||||||
(let [message (.-data event)
|
(let [message (.-data event)
|
||||||
message (t/decode-str message)]
|
message (wm/decode message)]
|
||||||
(if (:buffer? message)
|
(if (:buffer? message)
|
||||||
(rx/push! buffer message)
|
(rx/push! buffer message)
|
||||||
(handle-message message)))))
|
(handle-message message)))))
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.worker.impl
|
(ns app.worker.impl
|
||||||
(:require
|
(:require
|
||||||
[app.common.pages.changes :as ch]
|
[app.common.pages.changes :as ch]
|
||||||
|
[app.common.transit :as t]
|
||||||
[app.util.globals :refer [global]]
|
[app.util.globals :refer [global]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[okulary.core :as l]))
|
[okulary.core :as l]))
|
||||||
|
@ -28,14 +29,15 @@
|
||||||
message)
|
message)
|
||||||
|
|
||||||
(defmethod handler :initialize-indices
|
(defmethod handler :initialize-indices
|
||||||
[{:keys [data] :as message}]
|
[{:keys [file-raw] :as message}]
|
||||||
|
|
||||||
(reset! state data)
|
(let [data (-> (t/decode-str file-raw) :data)
|
||||||
|
message (assoc message :data data)]
|
||||||
(handler (-> message
|
(reset! state data)
|
||||||
(assoc :cmd :selection/initialize-index)))
|
(handler (-> message
|
||||||
(handler (-> message
|
(assoc :cmd :selection/initialize-index)))
|
||||||
(assoc :cmd :snaps/initialize-index))))
|
(handler (-> message
|
||||||
|
(assoc :cmd :snaps/initialize-index)))))
|
||||||
|
|
||||||
(defmethod handler :update-page-indices
|
(defmethod handler :update-page-indices
|
||||||
[{:keys [page-id changes] :as message}]
|
[{:keys [page-id changes] :as message}]
|
||||||
|
|
36
frontend/src/app/worker/messages.cljs
Normal file
36
frontend/src/app/worker/messages.cljs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns app.worker.messages
|
||||||
|
"A lightweight layer on top of webworkers api."
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.transit :as t]
|
||||||
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
|
(defn encode [{:keys [sender-id reply-to payload buffer?] :as message}]
|
||||||
|
#js {:cmd (d/name (:cmd payload))
|
||||||
|
:senderId (when sender-id (str sender-id))
|
||||||
|
:replyTo (when reply-to (str reply-to))
|
||||||
|
:payload (if (= :initialize-indices (:cmd payload))
|
||||||
|
(:file-raw payload)
|
||||||
|
(when (some? payload) (t/encode-str payload)))
|
||||||
|
:buffer (when (some? buffer?) buffer?)})
|
||||||
|
|
||||||
|
(defn decode [^js data]
|
||||||
|
(let [cmd (obj/get data "cmd")
|
||||||
|
sender-id (obj/get data "senderId")
|
||||||
|
reply-to (obj/get data "replyTo")
|
||||||
|
payload (obj/get data "payload")
|
||||||
|
buffer (obj/get data "buffer")]
|
||||||
|
(d/without-nils
|
||||||
|
{:sender-id (when sender-id (uuid sender-id))
|
||||||
|
:reply-to (when reply-to (uuid reply-to))
|
||||||
|
:payload (if (= cmd "initialize-indices")
|
||||||
|
{:cmd :initialize-indices
|
||||||
|
:file-raw payload}
|
||||||
|
(when (some? payload) (t/decode-str payload)))
|
||||||
|
:buffer? buffer})))
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
(defonce state (l/atom {}))
|
(defonce state (l/atom {}))
|
||||||
|
|
||||||
(defn index-shape
|
(defn make-index-shape
|
||||||
[objects parents-index clip-parents-index]
|
[objects parents-index clip-parents-index]
|
||||||
(fn [index shape]
|
(fn [index shape]
|
||||||
(let [{:keys [x y width height]}
|
(let [{:keys [x y width height]}
|
||||||
|
@ -77,13 +77,16 @@
|
||||||
(let [shapes (-> objects (dissoc uuid/zero) vals)
|
(let [shapes (-> objects (dissoc uuid/zero) vals)
|
||||||
parents-index (cp/generate-child-all-parents-index objects)
|
parents-index (cp/generate-child-all-parents-index objects)
|
||||||
clip-parents-index (cp/create-clip-index objects parents-index)
|
clip-parents-index (cp/create-clip-index objects parents-index)
|
||||||
bounds (-> objects objects-bounds add-padding-bounds)
|
|
||||||
|
|
||||||
index (reduce (index-shape objects parents-index clip-parents-index)
|
root-shapes (cph/get-immediate-children objects uuid/zero)
|
||||||
(qdt/create (clj->js bounds))
|
bounds (-> root-shapes gsh/selection-rect add-padding-bounds)
|
||||||
shapes)
|
|
||||||
|
|
||||||
z-index (cp/calculate-z-index objects)]
|
index-shape (make-index-shape objects parents-index clip-parents-index)
|
||||||
|
initial-quadtree (qdt/create (clj->js bounds))
|
||||||
|
|
||||||
|
index (reduce index-shape initial-quadtree shapes)
|
||||||
|
|
||||||
|
z-index (cp/calculate-z-index objects)]
|
||||||
|
|
||||||
{:index index :z-index z-index :bounds bounds}))
|
{:index index :z-index z-index :bounds bounds}))
|
||||||
|
|
||||||
|
@ -106,9 +109,8 @@
|
||||||
|
|
||||||
new-index (qdt/remove-all index changed-ids)
|
new-index (qdt/remove-all index changed-ids)
|
||||||
|
|
||||||
index (reduce (index-shape new-objects parents-index clip-parents-index)
|
index-shape (make-index-shape new-objects parents-index clip-parents-index)
|
||||||
new-index
|
index (reduce index-shape new-index shapes)
|
||||||
shapes)
|
|
||||||
|
|
||||||
z-index (cp/update-z-index z-index changed-ids old-objects new-objects)]
|
z-index (cp/update-z-index z-index changed-ids old-objects new-objects)]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue