0
Fork 0
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:
Alejandro Alonso 2024-06-25 15:54:32 +02:00
commit 6e734f2eac
4 changed files with 105 additions and 77 deletions

View file

@ -41,16 +41,19 @@
(let [components-v2 (dm/get-in file [:data :options :components-v2]) (let [components-v2 (dm/get-in file [:data :options :components-v2])
component-id (:current-component-id file) component-id (:current-component-id file)
change (cond-> change change (cond-> change
(and add-container? (some? component-id)) (and add-container? (some? component-id) (not components-v2))
(-> (assoc :component-id component-id) (-> (assoc :component-id component-id)
(cond-> (some? (:current-frame-id file)) (cond-> (some? (:current-frame-id file))
(assoc :frame-id (:current-frame-id file)))) (assoc :frame-id (:current-frame-id file))))
(and add-container? (nil? component-id)) (and add-container? (or (nil? component-id) components-v2))
(assoc :page-id (:current-page-id file) (assoc :page-id (:current-page-id file)
:frame-id (:current-frame-id file))) :frame-id (:current-frame-id file)))
valid? (ch/check-change! change)] valid? (or (and components-v2
(nil? (:component-id change))
(nil? (:page-id change)))
(ch/check-change! change))]
(when-not valid? (when-not valid?
(let [explain (sm/explain ::ch/change change)] (let [explain (sm/explain ::ch/change change)]
@ -62,7 +65,7 @@
::sm/explain explain)))) ::sm/explain explain))))
(cond-> file (cond-> file
(and valid? (not (and components-v2 add-container? (some? component-id)))) (and valid? (or (not add-container?) (some? (:component-id change)) (some? (:page-id change))))
(-> (update :changes conjv change) ;; In components-v2 we do not add shapes (-> (update :changes conjv change) ;; In components-v2 we do not add shapes
(update :data ch/process-changes [change] false)) ;; inside a component (update :data ch/process-changes [change] false)) ;; inside a component
@ -524,6 +527,11 @@
path (:path data) path (:path data)
main-instance-id (:main-instance-id data) main-instance-id (:main-instance-id data)
main-instance-page (:main-instance-page data) main-instance-page (:main-instance-page data)
;; In components v1 we must create the root shape and set it inside
;; the :objects attribute of the component. When in components-v2,
;; this will be ignored as the root shape has already been created
;; in its page, by the normal page import.
attrs (-> data attrs (-> data
(assoc :type root-type) (assoc :type root-type)
(assoc :x (:x selrect)) (assoc :x (:x selrect))
@ -559,6 +567,29 @@
(assoc :current-component-id (:id obj)) (assoc :current-component-id (:id obj))
(assoc :current-frame-id (if (= (:type obj) :frame) (:id obj) uuid/zero)))))) (assoc :current-frame-id (if (= (:type obj) :frame) (:id obj) uuid/zero))))))
(defn start-deleted-component
[file data]
(let [attrs (-> data
(assoc :id (:main-instance-id data))
(assoc :component-file (:id file))
(assoc :component-id (:id data))
(assoc :x (:main-instance-x data))
(assoc :y (:main-instance-y data))
(dissoc :path)
(dissoc :main-instance-id)
(dissoc :main-instance-page)
(dissoc :main-instance-x)
(dissoc :main-instance-y)
(dissoc :main-instance-parent)
(dissoc :main-instance-frame))]
;; To create a deleted component, first we add all shapes of the main instance
;; in the main instance page, and in the finish event we delete it.
(-> file
(update :parent-stack conjv (:main-instance-parent data))
(assoc :current-page-id (:main-instance-page data))
(assoc :current-frame-id (:main-instance-frame data))
(add-artboard attrs))))
(defn finish-component (defn finish-component
[file] [file]
(let [component-id (:current-component-id file) (let [component-id (:current-component-id file)
@ -623,43 +654,18 @@
(update :parent-stack pop)))) (update :parent-stack pop))))
(defn finish-deleted-component (defn finish-deleted-component
[component-id page-id main-instance-x main-instance-y file] [component-id file]
(let [file (assoc file :current-component-id component-id) (let [file (assoc file :current-component-id component-id)
page (ctpl/get-page (:data file) page-id) component (ctkl/get-component (:data file) component-id)]
component (ctkl/get-component (:data file) component-id) (-> file
main-instance-id (:main-instance-id component) (close-artboard)
(commit-change {:type :del-component
; To obtain a deleted component, we first create the component
; and the main instance in the workspace, and then delete them.
[_ shapes]
(ctn/make-component-instance page
component
(:data file)
(gpt/point main-instance-x
main-instance-y)
true
{:main-instance true
:force-id main-instance-id})]
(as-> file $
(reduce #(commit-change %1
{:type :add-obj
:id (:id %2)
:page-id (:id page)
:parent-id (:parent-id %2)
:frame-id (:frame-id %2)
:ignore-touched true
:obj %2})
$
shapes)
(commit-change $ {:type :del-component
:id component-id}) :id component-id})
(reduce #(commit-change %1 {:type :del-obj (commit-change {:type :del-obj
:page-id page-id :page-id (:main-instance-page component)
:ignore-touched true :id (:main-instance-id component)
:id (:id %2)}) :ignore-touched true})
$ (dissoc :current-page-id))))
shapes)
(dissoc $ :current-component-id))))
(defn create-component-instance (defn create-component-instance
[file data] [file data]
@ -670,7 +676,6 @@
page-id (:current-page-id file) page-id (:current-page-id file)
page (ctpl/get-page (:data file) page-id) page (ctpl/get-page (:data file) page-id)
component (ctkl/get-component (:data file) component-id) component (ctkl/get-component (:data file) component-id)
;; main-instance-id (:main-instance-id component)
components-v2 (dm/get-in file [:options :components-v2]) components-v2 (dm/get-in file [:options :components-v2])

View file

@ -23,6 +23,7 @@
[app.common.geom.shapes.bounds :as gsb] [app.common.geom.shapes.bounds :as gsb]
[app.common.logging :as l] [app.common.logging :as l]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.types.components-list :as ctkl]
[app.common.types.file :as ctf] [app.common.types.file :as ctf]
[app.common.types.modifiers :as ctm] [app.common.types.modifiers :as ctm]
[app.common.types.shape-tree :as ctst] [app.common.types.shape-tree :as ctst]
@ -484,15 +485,18 @@
path (:path component) path (:path component)
root-id (or (:main-instance-id component) root-id (or (:main-instance-id component)
(:id component)) (:id component))
orig-root (get (:objects component) root-id)
objects (adapt-objects-for-shape (:objects component) objects (adapt-objects-for-shape (:objects component)
root-id) root-id)
root-shape (get objects root-id) root-shape (get objects root-id)
selrect (:selrect root-shape) selrect (:selrect root-shape)
main-instance-id (:main-instance-id component) main-instance-id (:main-instance-id component)
main-instance-page (:main-instance-page component) main-instance-page (:main-instance-page component)
main-instance-x (:main-instance-x component) main-instance-x (when (:deleted component) (:x orig-root))
main-instance-y (:main-instance-y component) main-instance-y (when (:deleted component) (:y orig-root))
main-instance-parent (when (:deleted component) (:parent-id orig-root))
main-instance-frame (when (:deleted component) (:frame-id orig-root))
vbox vbox
(format-viewbox (format-viewbox
@ -516,7 +520,9 @@
"penpot:main-instance-id" main-instance-id "penpot:main-instance-id" main-instance-id
"penpot:main-instance-page" main-instance-page "penpot:main-instance-page" main-instance-page
"penpot:main-instance-x" main-instance-x "penpot:main-instance-x" main-instance-x
"penpot:main-instance-y" main-instance-y} "penpot:main-instance-y" main-instance-y
"penpot:main-instance-parent" main-instance-parent
"penpot:main-instance-frame" main-instance-frame}
[:title name] [:title name]
[:> shape-container {:shape root-shape} [:> shape-container {:shape root-shape}
(case (:type root-shape) (case (:type root-shape)
@ -525,8 +531,10 @@
(mf/defc components-svg (mf/defc components-svg
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [data children embed include-metadata source]}] [{:keys [data children embed include-metadata deleted?]}]
(let [source (keyword (d/nilv source "components"))] (let [components (if (not deleted?)
(ctkl/components-seq data)
(ctkl/deleted-components-seq data))]
[:& (mf/provider embed/context) {:value embed} [:& (mf/provider embed/context) {:value embed}
[:& (mf/provider export/include-metadata-ctx) {:value include-metadata} [:& (mf/provider export/include-metadata-ctx) {:value include-metadata}
[:svg {:version "1.1" [:svg {:version "1.1"
@ -536,9 +544,9 @@
:style {:display (when-not (some? children) "none")} :style {:display (when-not (some? children) "none")}
:fill "none"} :fill "none"}
[:defs [:defs
(for [[id component] (source data)] (for [component components]
(let [component (ctf/load-component-objects data component)] (let [component (ctf/load-component-objects data component)]
[:& component-symbol {:key (dm/str id) :component component}]))] [:& component-symbol {:key (dm/str (:id component)) :component component}]))]
children]]])) children]]]))
@ -595,10 +603,12 @@
(rds/renderToStaticMarkup elem))))))) (rds/renderToStaticMarkup elem)))))))
(defn render-components (defn render-components
[data source] [data deleted?]
(let [;; Join all components objects into a single map (let [;; Join all components objects into a single map
objects (->> (source data) components (if (not deleted?)
(vals) (ctkl/components-seq data)
(ctkl/deleted-components-seq data))
objects (->> components
(map (partial ctf/load-component-objects data)) (map (partial ctf/load-component-objects data))
(map :objects) (map :objects)
(reduce conj))] (reduce conj))]
@ -615,7 +625,7 @@
#js {:data data #js {:data data
:embed true :embed true
:include-metadata true :include-metadata true
:source (name source)})] :deleted? deleted?})]
(rds/renderToStaticMarkup elem)))))))) (rds/renderToStaticMarkup elem))))))))
(defn render-frame (defn render-frame

View file

@ -52,7 +52,7 @@
:libraries (->> (:libraries file) (into #{}) (mapv str)) :libraries (->> (:libraries file) (into #{}) (mapv str))
:exportType (d/name export-type) :exportType (d/name export-type)
:hasComponents (d/not-empty? (ctkl/components-seq (:data file))) :hasComponents (d/not-empty? (ctkl/components-seq (:data file)))
:hasDeletedComponents (d/not-empty? (get-in file [:data :deleted-components])) :hasDeletedComponents (d/not-empty? (ctkl/deleted-components-seq (:data file)))
:hasMedia (d/not-empty? (get-in file [:data :media])) :hasMedia (d/not-empty? (get-in file [:data :media]))
:hasColors (d/not-empty? (get-in file [:data :colors])) :hasColors (d/not-empty? (get-in file [:data :colors]))
:hasTypographies (d/not-empty? (get-in file [:data :typographies]))}))))] :hasTypographies (d/not-empty? (get-in file [:data :typographies]))}))))]
@ -151,12 +151,12 @@
(defn parse-library-components (defn parse-library-components
[file] [file]
(->> (r/render-components (:data file) :components) (->> (r/render-components (:data file) false)
(rx/map #(vector (str (:id file) "/components.svg") %)))) (rx/map #(vector (str (:id file) "/components.svg") %))))
(defn parse-deleted-components (defn parse-deleted-components
[file] [file]
(->> (r/render-components (:data file) :deleted-components) (->> (r/render-components (:data file) true)
(rx/map #(vector (str (:id file) "/deleted-components.svg") %)))) (rx/map #(vector (str (:id file) "/deleted-components.svg") %))))
(defn fetch-file-with-libraries (defn fetch-file-with-libraries
@ -380,7 +380,7 @@
deleted-components-stream deleted-components-stream
(->> files-stream (->> files-stream
(rx/merge-map vals) (rx/merge-map vals)
(rx/filter #(d/not-empty? (get-in % [:data :deleted-components]))) (rx/filter #(d/not-empty? (ctkl/deleted-components-seq (:data %))))
(rx/merge-map parse-deleted-components)) (rx/merge-map parse-deleted-components))
pages-stream pages-stream

View file

@ -253,6 +253,7 @@
frame (when (and (some? frame-id) (not= frame-id uuid/zero)) frame (when (and (some? frame-id) (not= frame-id uuid/zero))
(fb/lookup-shape file frame-id))] (fb/lookup-shape file frame-id))]
(js/console.log " translate-frame" (clj->js frame))
(if (some? frame) (if (some? frame)
(-> data (-> data
(d/update-when :x + (:x frame)) (d/update-when :x + (:x frame))
@ -283,7 +284,13 @@
(cond-> (some? old-id) (cond-> (some? old-id)
(assoc :id (resolve old-id))) (assoc :id (resolve old-id)))
(cond-> (< (:version context 1) 2) (cond-> (< (:version context 1) 2)
(translate-frame type file)))] (translate-frame type file))
;; Shapes inside the deleted component should be stored with absolute coordinates
;; so we calculate that with the x and y stored in the context
(cond-> (:x context)
(assoc :x (:x context)))
(cond-> (:y context)
(assoc :y (:y context))))]
(try (try
(let [file (case type (let [file (case type
:frame (fb/add-artboard file data) :frame (fb/add-artboard file data)
@ -455,17 +462,19 @@
(rx/map fb/finish-component)))) (rx/map fb/finish-component))))
(defn import-deleted-component [context file node] (defn import-deleted-component [context file node]
(let [resolve (:resolve context) (let [resolve (:resolve context)
content (parser/find-node node :g) content (parser/find-node node :g)
file-id (:id file) file-id (:id file)
old-id (parser/get-id node) old-id (parser/get-id node)
id (resolve old-id) id (resolve old-id)
path (get-in node [:attrs :penpot:path] "") path (get-in node [:attrs :penpot:path] "")
main-instance-id (resolve (uuid (get-in node [:attrs :penpot:main-instance-id] ""))) main-instance-id (resolve (uuid (get-in node [:attrs :penpot:main-instance-id] "")))
main-instance-page (resolve (uuid (get-in node [:attrs :penpot:main-instance-page] ""))) main-instance-page (resolve (uuid (get-in node [:attrs :penpot:main-instance-page] "")))
main-instance-x (get-in node [:attrs :penpot:main-instance-x] "") main-instance-x (-> (get-in node [:attrs :penpot:main-instance-x] "") (d/parse-double))
main-instance-y (get-in node [:attrs :penpot:main-instance-y] "") main-instance-y (-> (get-in node [:attrs :penpot:main-instance-y] "") (d/parse-double))
type (parser/get-type content) main-instance-parent (resolve (uuid (get-in node [:attrs :penpot:main-instance-parent] "")))
main-instance-frame (resolve (uuid (get-in node [:attrs :penpot:main-instance-frame] "")))
type (parser/get-type content)
data (-> (parser/parse-data type content) data (-> (parser/parse-data type content)
(assoc :path path) (assoc :path path)
@ -473,12 +482,20 @@
(assoc :main-instance-id main-instance-id) (assoc :main-instance-id main-instance-id)
(assoc :main-instance-page main-instance-page) (assoc :main-instance-page main-instance-page)
(assoc :main-instance-x main-instance-x) (assoc :main-instance-x main-instance-x)
(assoc :main-instance-y main-instance-y)) (assoc :main-instance-y main-instance-y)
(assoc :main-instance-parent main-instance-parent)
(assoc :main-instance-frame main-instance-frame))
file (-> file (fb/start-component data)) file (-> file
(fb/start-component data)
(fb/start-deleted-component data))
component-id (:current-component-id file) component-id (:current-component-id file)
children (parser/node-seq node)] children (parser/node-seq node)
;; Shapes inside the deleted component should be stored with absolute coordinates so we include this info in the context.
context (-> context
(assoc :x main-instance-x)
(assoc :y main-instance-y))]
(->> (rx/from children) (->> (rx/from children)
(rx/filter parser/shape?) (rx/filter parser/shape?)
(rx/skip 1) (rx/skip 1)
@ -486,11 +503,7 @@
(rx/mapcat (partial resolve-media context file-id)) (rx/mapcat (partial resolve-media context file-id))
(rx/reduce (partial process-import-node context) file) (rx/reduce (partial process-import-node context) file)
(rx/map fb/finish-component) (rx/map fb/finish-component)
(rx/map (partial fb/finish-deleted-component (rx/map (partial fb/finish-deleted-component component-id)))))
component-id
main-instance-page
main-instance-x
main-instance-y)))))
(defn process-pages (defn process-pages
[context file] [context file]