mirror of
https://github.com/penpot/penpot.git
synced 2025-03-10 14:51:37 -05:00
✨ Improved frame indices
This commit is contained in:
parent
ca326ac231
commit
108291337d
9 changed files with 62 additions and 144 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
### :sparkles: New features
|
||||
|
||||
- Allow for nested boards inside other boards and groups
|
||||
- Allow for nested and rotated boards inside other boards and groups [Taiga #2874](https://tree.taiga.io/project/penpot/us/2874?milestone=319982)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
### :arrow_up: Deps updates
|
||||
|
|
|
@ -153,30 +153,23 @@
|
|||
(:shapes)
|
||||
(keep lookup)))))
|
||||
|
||||
(defn get-frames-ids
|
||||
"Retrieves all frame objects as vector. It is not implemented in
|
||||
function of `get-immediate-children` for performance reasons. This
|
||||
function is executed in the render hot path."
|
||||
[objects]
|
||||
(let [lookup (d/getf objects)
|
||||
xform (comp (remove #(= uuid/zero %))
|
||||
(keep lookup)
|
||||
(filter frame-shape?)
|
||||
(map :id))]
|
||||
(->> (keys objects)
|
||||
(into [] xform))))
|
||||
|
||||
(defn get-frames
|
||||
"Retrieves all frame objects as vector. It is not implemented in
|
||||
function of `get-immediate-children` for performance reasons. This
|
||||
function is executed in the render hot path."
|
||||
"Retrieves all frame objects as vector"
|
||||
[objects]
|
||||
(let [lookup (d/getf objects)
|
||||
xform (comp (remove #(= uuid/zero %))
|
||||
(keep lookup)
|
||||
(filter frame-shape?))]
|
||||
(->> (keys objects)
|
||||
(into [] xform))))
|
||||
(if (contains? (meta objects) ::index-frames)
|
||||
(::index-frames (meta objects))
|
||||
(let [lookup (d/getf objects)
|
||||
xform (comp (remove #(= uuid/zero %))
|
||||
(keep lookup)
|
||||
(filter frame-shape?))]
|
||||
(->> (keys objects)
|
||||
(into [] xform)))))
|
||||
|
||||
(defn get-frames-ids
|
||||
"Retrieves all frame ids as vector"
|
||||
[objects]
|
||||
(->> (get-frames objects)
|
||||
(mapv :id)))
|
||||
|
||||
(defn get-nested-frames
|
||||
[objects frame-id]
|
||||
|
@ -197,25 +190,19 @@
|
|||
(conj (:id shape))))]
|
||||
(reduce-objects objects (complement frame-shape?) add-frame [])))
|
||||
|
||||
(defn get-root-shapes-ids
|
||||
(defn get-root-shapes
|
||||
[objects]
|
||||
(let [add-shape
|
||||
(fn [result shape]
|
||||
(cond-> result
|
||||
(not (frame-shape? shape))
|
||||
(conj (:id shape))))]
|
||||
(conj shape)))]
|
||||
(reduce-objects objects (complement frame-shape?) add-shape [])))
|
||||
|
||||
(defn get-root-frames
|
||||
"Retrieves all frame objects as vector. It is not implemented in
|
||||
function of `get-immediate-children` for performance reasons. This
|
||||
function is executed in the render hot path."
|
||||
(defn get-root-shapes-ids
|
||||
[objects]
|
||||
(let [lookup (d/getf objects)
|
||||
xform (comp (keep lookup)
|
||||
(filter frame-shape?))]
|
||||
(->> (:shapes (lookup uuid/zero))
|
||||
(into [] xform))))
|
||||
(->> (get-root-shapes objects)
|
||||
(mapv :id)))
|
||||
|
||||
(defn- get-base
|
||||
[objects id-a id-b]
|
||||
|
@ -697,3 +684,22 @@
|
|||
identity
|
||||
(remove :hide-in-viewer)))
|
||||
(sort-z-index objects (get-frames-ids objects) {:top-frames? true}))))
|
||||
|
||||
|
||||
(defn start-page-index
|
||||
[objects]
|
||||
(with-meta objects {::index-frames (get-frames objects)}))
|
||||
|
||||
(defn update-page-index
|
||||
[objects]
|
||||
(with-meta objects {::index-frames (get-frames objects)}))
|
||||
|
||||
(defn start-object-indices
|
||||
[file]
|
||||
(letfn [(process-index [page-index page-id]
|
||||
(update-in page-index [page-id :objects] start-page-index))]
|
||||
(update file :pages-index #(reduce process-index % (keys %)))))
|
||||
|
||||
(defn update-object-indices
|
||||
[file page-id]
|
||||
(update-in file [:pages-index page-id :objects] update-page-index))
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
[app.main.data.workspace.fix-bool-contents :as fbc]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.guides :as dwgu]
|
||||
[app.main.data.workspace.indices :as dwidx]
|
||||
[app.main.data.workspace.interactions :as dwi]
|
||||
[app.main.data.workspace.layers :as dwly]
|
||||
[app.main.data.workspace.layout :as layout]
|
||||
|
@ -128,9 +127,7 @@
|
|||
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)
|
||||
(dwidx/start-indexing))
|
||||
|
||||
(dwp/initialize-file-persistence file-id))
|
||||
(->> stream
|
||||
(rx/filter #(= ::dwc/index-initialized %))
|
||||
(rx/take 1)
|
||||
|
@ -153,6 +150,7 @@
|
|||
:workspace-project project
|
||||
:workspace-file (assoc file :initialized true)
|
||||
:workspace-data (-> (:data file)
|
||||
(cph/start-object-indices)
|
||||
;; DEBUG: Uncomment this to try out migrations in local without changing
|
||||
;; the version number
|
||||
#_(assoc :version 17)
|
||||
|
@ -196,7 +194,6 @@
|
|||
(watch [_ _ _]
|
||||
(rx/merge
|
||||
(rx/of (dwn/finalize file-id))
|
||||
(rx/of (dwidx/stop-indexing))
|
||||
(->> (rx/of ::dwp/finalize)
|
||||
(rx/observe-on :async))))))
|
||||
|
||||
|
|
|
@ -162,7 +162,10 @@
|
|||
(us/assert ::spec.change/changes redo-changes)
|
||||
(us/assert ::spec.change/changes undo-changes)
|
||||
|
||||
(update-in state path cp/process-changes redo-changes false)
|
||||
(update-in state path (fn [file]
|
||||
(-> file
|
||||
(cp/process-changes redo-changes false)
|
||||
(cph/update-object-indices page-id))))
|
||||
|
||||
(catch :default err
|
||||
(log/error :js/error err)
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
;; 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.main.data.workspace.indices
|
||||
(:require
|
||||
[app.main.data.workspace.changes :as dwc]
|
||||
[app.main.data.workspace.indices.object-tree :as dwi-object-tree]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.refs :as refs]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(def stop-indexing? (ptk/type? ::stop-indexing))
|
||||
|
||||
(def objects-changes #{:add-obj :mod-obj :del-obj :mov-objects})
|
||||
|
||||
(defn stop-indexing
|
||||
[]
|
||||
(ptk/reify ::stop-indexing
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(dissoc :index-object-tree)))))
|
||||
|
||||
(defn process-changes
|
||||
"Simplify changes so we have only the type of operation and the ids"
|
||||
[changes]
|
||||
(->> changes
|
||||
(filter #(contains? objects-changes (:type %)))
|
||||
(mapcat (fn [{:keys [type id shapes]}]
|
||||
(if (some? shapes)
|
||||
(->> shapes (map #(vector type %)))
|
||||
[[type id]])))))
|
||||
|
||||
(defn update-indexing
|
||||
[change-type shape-id old-objects new-objects]
|
||||
(ptk/reify ::update-indexing
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :index-object-tree dwi-object-tree/update-index shape-id change-type old-objects new-objects)))))
|
||||
|
||||
(defn start-indexing
|
||||
[]
|
||||
(ptk/reify ::start-indexing
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)]
|
||||
(-> state
|
||||
(assoc :index-object-tree (dwi-object-tree/init-index objects)))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stopper (->> stream (rx/filter stop-indexing?) (rx/take 1))
|
||||
objects-delta (->> (rx/from-atom refs/workspace-page-objects {:emit-current-value? true}) (rx/buffer 2 1))]
|
||||
(->> stream
|
||||
(rx/filter dwc/commit-changes?)
|
||||
(rx/flat-map #(->> % deref :changes process-changes))
|
||||
(rx/with-latest-from objects-delta)
|
||||
(rx/map (fn [[[type id] [objects-old objects-new]]]
|
||||
(update-indexing type id objects-old objects-new)))
|
||||
#_(rx/tap (fn [[[type id] [objects-old objects-new]]]
|
||||
(let [obj-old (get objects-old id)
|
||||
obj-new (get objects-new id)]
|
||||
(prn ">change" (or (:name obj-old) (:name obj-new)))
|
||||
(prn " > " type)
|
||||
(.log js/console " >" (clj->js obj-old))
|
||||
(.log js/console " >" (clj->js obj-new))
|
||||
|
||||
)))
|
||||
(rx/take-until stopper)
|
||||
(rx/ignore))))))
|
|
@ -1,16 +0,0 @@
|
|||
;; 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.main.data.workspace.indices.object-tree)
|
||||
|
||||
(defn objects-tree
|
||||
[_objects])
|
||||
|
||||
(defn init-index
|
||||
[_objects])
|
||||
|
||||
(defn update-index
|
||||
[_index _shape-id _change-type _old-objects _new-objects])
|
|
@ -73,12 +73,13 @@
|
|||
|
||||
(rx/merge-map
|
||||
(fn [data]
|
||||
(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)))))))))))
|
||||
(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))))))))))))
|
||||
|
||||
(defn- extract-frame-changes
|
||||
"Process a changes set in a commit to extract the frames that are changing"
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
[app.main.ui.workspace.shapes.path.common :as pc]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn apply-content-modifiers
|
||||
[shape content-modifiers]
|
||||
(let [shape (update shape :content upc/apply-content-modifiers content-modifiers)
|
||||
[_ new-selrect] (helpers/content->points+selrect shape (:content shape))]
|
||||
(assoc shape :selrect new-selrect)))
|
||||
|
||||
(mf/defc path-wrapper
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
@ -22,11 +28,7 @@
|
|||
content-modifiers (mf/deref content-modifiers-ref)
|
||||
editing-id (mf/deref refs/selected-edition)
|
||||
editing? (= editing-id (:id shape))
|
||||
shape (update shape :content upc/apply-content-modifiers content-modifiers)
|
||||
|
||||
[_ new-selrect]
|
||||
(helpers/content->points+selrect shape (:content shape))
|
||||
shape (assoc shape :selrect new-selrect)]
|
||||
shape (mf/use-memo (mf/deps shape content-modifiers) #(apply-content-modifiers shape content-modifiers))]
|
||||
|
||||
[:> shape-container {:shape shape
|
||||
:pointer-events (when editing? "none")}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
(defn strip-modifier
|
||||
[modifier]
|
||||
(if (or (some? (get-in modifier [:modifiers :resize-vector]))
|
||||
(some? (get-in modifier [:modifiers :resize-vector-2])))
|
||||
(if (or (some? (dm/get-in modifier [:modifiers :resize-vector]))
|
||||
(some? (dm/get-in modifier [:modifiers :resize-vector-2])))
|
||||
modifier
|
||||
(d/update-when modifier :modifiers dissoc :displacement :rotation)))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue