mirror of
https://github.com/penpot/penpot.git
synced 2025-07-30 17:38:35 +02:00
✨ Add workspace initialization fix for broken shape references
Is the code that executes at workspace initialization that checks all the shape children for broken references and proceed to emit a special event that fixes the shape children references.
This commit is contained in:
parent
2ec5a3ba6a
commit
7efeeec9b1
4 changed files with 71 additions and 8 deletions
|
@ -93,6 +93,13 @@
|
||||||
[:component-id {:optional true} ::sm/uuid]
|
[:component-id {:optional true} ::sm/uuid]
|
||||||
[:ignore-touched {:optional true} :boolean]]]
|
[:ignore-touched {:optional true} :boolean]]]
|
||||||
|
|
||||||
|
[:fix-obj
|
||||||
|
[:map {:title "FixObjChange"}
|
||||||
|
[:type [:= :fix-obj]]
|
||||||
|
[:id ::sm/uuid]
|
||||||
|
[:page-id {:optional true} ::sm/uuid]
|
||||||
|
[:component-id {:optional true} ::sm/uuid]]]
|
||||||
|
|
||||||
[:mov-objects
|
[:mov-objects
|
||||||
[:map {:title "MovObjectsChange"}
|
[:map {:title "MovObjectsChange"}
|
||||||
[:type [:= :mov-objects]]
|
[:type [:= :mov-objects]]
|
||||||
|
@ -218,7 +225,7 @@
|
||||||
|
|
||||||
(sm/def! ::changes
|
(sm/def! ::changes
|
||||||
[:sequential {:gen/max 2} ::change])
|
[:sequential {:gen/max 2} ::change])
|
||||||
|
|
||||||
(def change?
|
(def change?
|
||||||
(sm/pred-fn ::change))
|
(sm/pred-fn ::change))
|
||||||
|
|
||||||
|
@ -337,6 +344,12 @@
|
||||||
(d/update-in-when data [:pages-index page-id] ctst/delete-shape id ignore-touched)
|
(d/update-in-when data [:pages-index page-id] ctst/delete-shape id ignore-touched)
|
||||||
(d/update-in-when data [:components component-id] ctst/delete-shape id ignore-touched)))
|
(d/update-in-when data [:components component-id] ctst/delete-shape id ignore-touched)))
|
||||||
|
|
||||||
|
(defmethod process-change :fix-obj
|
||||||
|
[data {:keys [page-id component-id] :as params}]
|
||||||
|
(if page-id
|
||||||
|
(d/update-in-when data [:pages-index page-id] ctst/fix-shape-children params)
|
||||||
|
(d/update-in-when data [:components component-id] ctst/fix-shape-children params)))
|
||||||
|
|
||||||
;; FIXME: remove, seems like this method is already unused
|
;; FIXME: remove, seems like this method is already unused
|
||||||
;; reg-objects operation "regenerates" the geometry and selrect of the parent groups
|
;; reg-objects operation "regenerates" the geometry and selrect of the parent groups
|
||||||
(defmethod process-change :reg-objects
|
(defmethod process-change :reg-objects
|
||||||
|
|
|
@ -90,16 +90,24 @@
|
||||||
|
|
||||||
(delete-from-objects [objects]
|
(delete-from-objects [objects]
|
||||||
(if-let [target (get objects shape-id)]
|
(if-let [target (get objects shape-id)]
|
||||||
(let [parent-id (or (:parent-id target)
|
(let [parent-id (or (:parent-id target)
|
||||||
(:frame-id target))
|
(:frame-id target))
|
||||||
children-ids (cph/get-children-ids objects shape-id)]
|
children-ids (cph/get-children-ids objects shape-id)]
|
||||||
(-> (reduce dissoc objects children-ids)
|
(-> (reduce dissoc objects (cons shape-id children-ids))
|
||||||
(dissoc shape-id)
|
|
||||||
(d/update-when parent-id delete-from-parent)))
|
(d/update-when parent-id delete-from-parent)))
|
||||||
objects))]
|
objects))]
|
||||||
|
|
||||||
(update container :objects delete-from-objects))))
|
(update container :objects delete-from-objects))))
|
||||||
|
|
||||||
|
(defn fix-shape-children
|
||||||
|
"Checks and fix the children relations of the shape. If a children does not
|
||||||
|
exists on the objects tree, it will be removed from shape."
|
||||||
|
[{:keys [objects] :as container} {:keys [id] :as params}]
|
||||||
|
(let [contains? (partial contains? objects)]
|
||||||
|
(d/update-in-when container [:objects id :shapes]
|
||||||
|
(fn [shapes]
|
||||||
|
(into [] (filter contains?) shapes)))))
|
||||||
|
|
||||||
(defn get-frames
|
(defn get-frames
|
||||||
"Retrieves all frame objects as vector"
|
"Retrieves all frame objects as vector"
|
||||||
([objects] (get-frames objects nil))
|
([objects] (get-frames objects nil))
|
||||||
|
@ -350,6 +358,7 @@
|
||||||
(some? force-id) force-id
|
(some? force-id) force-id
|
||||||
keep-ids? (:id object)
|
keep-ids? (:id object)
|
||||||
:else (uuid/next))]
|
:else (uuid/next))]
|
||||||
|
|
||||||
(loop [child-ids (seq (:shapes object))
|
(loop [child-ids (seq (:shapes object))
|
||||||
new-direct-children []
|
new-direct-children []
|
||||||
new-children []
|
new-children []
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
[app.main.data.workspace.drawing.common :as dwdc]
|
[app.main.data.workspace.drawing.common :as dwdc]
|
||||||
[app.main.data.workspace.edition :as dwe]
|
[app.main.data.workspace.edition :as dwe]
|
||||||
[app.main.data.workspace.fix-bool-contents :as fbc]
|
[app.main.data.workspace.fix-bool-contents :as fbc]
|
||||||
|
[app.main.data.workspace.fix-broken-shape-links :as fbs]
|
||||||
[app.main.data.workspace.fix-deleted-fonts :as fdf]
|
[app.main.data.workspace.fix-deleted-fonts :as fdf]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.main.data.workspace.guides :as dwgu]
|
[app.main.data.workspace.guides :as dwgu]
|
||||||
|
@ -130,8 +131,10 @@
|
||||||
has-graphics? (-> file :media seq)
|
has-graphics? (-> file :media seq)
|
||||||
components-v2 (features/active-feature? state :components-v2)]
|
components-v2 (features/active-feature? state :components-v2)]
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (fbc/fix-bool-contents))
|
(rx/of (fbc/fix-bool-contents)
|
||||||
(rx/of (fdf/fix-deleted-fonts))
|
(fdf/fix-deleted-fonts)
|
||||||
|
(fbs/fix-broken-shapes))
|
||||||
|
|
||||||
(if (and has-graphics? components-v2)
|
(if (and has-graphics? components-v2)
|
||||||
(rx/of (remove-graphics (:id file) (:name file)))
|
(rx/of (remove-graphics (:id file) (:name file)))
|
||||||
(rx/empty)))))))
|
(rx/empty)))))))
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.data.workspace.fix-broken-shape-links
|
||||||
|
(:require
|
||||||
|
[app.main.data.workspace.changes :as dch]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
|
(defn- generate-changes
|
||||||
|
[attr {:keys [objects id]}]
|
||||||
|
(let [base {:type :fix-obj attr id}
|
||||||
|
contains? (partial contains? objects)
|
||||||
|
xform (comp
|
||||||
|
(remove #(every? contains? (:shapes %)))
|
||||||
|
(map #(assoc base :id (:id %))))]
|
||||||
|
(sequence xform (vals objects))))
|
||||||
|
|
||||||
|
(defn fix-broken-shapes
|
||||||
|
[]
|
||||||
|
(ptk/reify ::fix-broken-shape-links
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [it state _]
|
||||||
|
(let [data (get state :workspace-data)
|
||||||
|
changes (concat
|
||||||
|
(mapcat (partial generate-changes :page-id)
|
||||||
|
(vals (:pages-index data)))
|
||||||
|
(mapcat (partial generate-changes :component-id)
|
||||||
|
(vals (:components data))))]
|
||||||
|
|
||||||
|
(rx/of (dch/commit-changes
|
||||||
|
{:origin it
|
||||||
|
:redo-changes (vec changes)
|
||||||
|
:undo-changes []
|
||||||
|
:save-undo? false}))))))
|
Loading…
Add table
Add a link
Reference in a new issue