0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-16 09:41:41 -05:00

Merge pull request #3570 from penpot/niwinz-develop-experiments-1

 Add performance enhancements (part 2)
This commit is contained in:
Alejandro 2023-09-01 12:58:54 +02:00 committed by GitHub
commit 6080b778d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 295 additions and 175 deletions

View file

@ -29,9 +29,16 @@
(defn is-direct-child-of-root?
([objects id]
(is-direct-child-of-root? (get objects id)))
([{:keys [frame-id type]}]
(and (= type :frame)
(= frame-id uuid/zero))))
([shape]
(and (some? shape) (= (dm/get-prop shape :frame-id) uuid/zero))))
(defn root-frame?
([objects id]
(root-frame? (get objects id)))
([shape]
(and (some? shape)
(= (dm/get-prop shape :type) :frame)
(= (dm/get-prop shape :frame-id) uuid/zero))))
(defn frame-shape?
([objects id]
@ -228,7 +235,7 @@
(or (root? frame) (nil? frame))
nil
(is-direct-child-of-root? frame)
(root-frame? frame)
frame
:else
@ -613,7 +620,7 @@
(->> (get-parent-ids objects shape-id)
(cons shape-id)
(map (d/getf objects))
(d/seek is-direct-child-of-root?)
(d/seek root-frame?)
:id))
(defn comparator-layout-z-index

View file

@ -9,8 +9,7 @@
(:refer-clojure :exclude [defrecord assoc! clone])
#?(:cljs (:require-macros [app.common.record]))
#?(:clj
(:import java.util.Map
java.util.Map$Entry)))
(:import java.util.Map$Entry)))
#_:clj-kondo/ignore
(defmacro caching-hash
@ -37,18 +36,24 @@
:else `(. ~this-sym ~(property-symbol field))))
fields)))
(defprotocol ICustomRecordEquiv
(-equiv-with-exceptions [_ other exceptions]))
#?(:clj
(defn emit-impl-js
[tagname base-fields]
(let [fields (conj base-fields '$meta '$extmap (with-meta '$hash {:mutable true}))
key-sym (gensym "key-")
val-sym (gensym "val-")
othr-sym (with-meta 'other {:tag tagname})
this-sym (with-meta 'this {:tag tagname})]
['cljs.core/ICloneable
['cljs.core/IRecord
'cljs.core/ICloneable
`(~'-clone [~this-sym]
(new ~tagname ~@(generate-field-access this-sym val-sym fields)))
'IHash
'cljs.core/IHash
`(~'-hash [~this-sym]
(caching-hash ~this-sym
(fn [coll#]
@ -58,16 +63,41 @@
(. ~this-sym ~'-$hash)))
'cljs.core/IEquiv
`(~'-equiv [~this-sym ~val-sym]
(and (some? ~val-sym)
(identical? (.-constructor ~this-sym)
(.-constructor ~val-sym))
~@(map (fn [field]
`(= (.. ~this-sym ~(property-symbol field))
(.. ~(with-meta val-sym {:tag tagname}) ~(property-symbol field))))
base-fields)
(= (. ~this-sym ~'-$extmap)
(. ~(with-meta val-sym {:tag tagname}) ~'-$extmap))))
`(~'-equiv [~this-sym ~othr-sym]
(or (identical? ~this-sym ~othr-sym)
(and (some? ~othr-sym)
(identical? (.-constructor ~this-sym)
(.-constructor ~othr-sym))
~@(map (fn [field]
`(= (.. ~this-sym ~(property-symbol field))
(.. ~(with-meta othr-sym {:tag tagname}) ~(property-symbol field))))
base-fields)
(= (. ~this-sym ~'-$extmap)
(. ~(with-meta othr-sym {:tag tagname}) ~'-$extmap)))))
`ICustomRecordEquiv
`(~'-equiv-with-exceptions [~this-sym ~othr-sym ~'exceptions]
(or (identical? ~this-sym ~othr-sym)
(and (some? ~othr-sym)
(identical? (.-constructor ~this-sym)
(.-constructor ~othr-sym))
(and ~@(->> base-fields
(map (fn [field]
`(= (.. ~this-sym ~(property-symbol field))
(.. ~(with-meta othr-sym {:tag tagname}) ~(property-symbol field))))))
(== (count (. ~this-sym ~'-$extmap))
(count (. ~othr-sym ~'-$extmap))))
(reduce-kv (fn [~'_ ~'k ~'v]
(if (contains? ~'exceptions ~'k)
true
(if (= (get (. ~this-sym ~'-$extmap) ~'k ::not-exists) ~'v)
true
(reduced false))))
true
(. ~othr-sym ~'-$extmap)))))
'cljs.core/IMeta
`(~'-meta [~this-sym] (. ~this-sym ~'-$meta))
@ -175,16 +205,17 @@
val-sym 'val
this-sym (with-meta 'this {:tag tagname})]
['clojure.lang.MapEquivalence
['clojure.lang.IRecord
'clojure.lang.IPersistentMap
`(~'equiv [~this-sym ~'other]
(and (instance? java.util.Map ~'other) (= (.count ~this-sym) (.size ^Map ~'other))
(every? (fn [^clojure.lang.MapEntry e#]
(let [k# (.key e#)]
(and (.containsKey ^Map ~'other k#)
(= (.val e#) (.get ^Map ~'other k#)))))
(.seq ~this-sym))))
`(~'equiv [~this-sym ~val-sym]
(and (some? ~val-sym)
(instance? ~tagname ~val-sym)
~@(map (fn [field]
`(= (.. ~this-sym ~(property-symbol field))
(.. ~(with-meta val-sym {:tag tagname}) ~(property-symbol field))))
base-fields)
(= (. ~this-sym ~'-$extmap)
(. ~(with-meta val-sym {:tag tagname}) ~'-$extmap))))
`(~'entryAt [~this-sym ~key-sym]
(let [v# (.valAt ~this-sym ~key-sym ::not-found)]

View file

@ -474,7 +474,7 @@
ids (if (boolean? blocked)
(into ids (->> ids (mapcat #(cph/get-children-ids objects %))))
ids)]
(rx/of (dch/update-shapes ids update-fn))))))
(rx/of (dch/update-shapes ids update-fn {:attrs #{:blocked :hidden}}))))))
(defn toggle-visibility-selected
[]

View file

@ -15,9 +15,18 @@
(def ^:dynamic *css-data* nil)
(def ^:private xform-css
(map (fn [k]
(let [cn (name k)]
(or (get *css-data* (keyword cn)) cn)))))
(keep (fn [k]
(cond
(keyword? k)
(let [knm (name k)
kns (namespace k)]
(case kns
"global" knm
"old-css" (if (nil? *css-data*) knm "")
(or (get *css-data* (keyword knm)) knm)))
(string? k)
k))))
(defmacro css*
"Just coerces all params to strings and concats them with
@ -35,7 +44,8 @@
(let [fname (-> *ns* meta :file)
path (str (subs fname 0 (- (count fname) 4)) "css.json")
data (-> (slurp (io/resource path))
(json/read-str :key-fn keyword))]
(json/read-str :key-fn keyword)
(or {}))]
(if (symbol? (first selectors))
`(if ~(with-meta (first selectors) {:tag 'boolean})
@ -51,7 +61,8 @@
(let [fname (-> *ns* meta :file)
path (str (subs fname 0 (- (count fname) 4)) "css.json")]
(-> (slurp (io/resource path))
(json/read-str :key-fn keyword))))
(json/read-str :key-fn keyword)
(or {}))))
(def ^:private xform-css-case
(comp
@ -59,8 +70,13 @@
(keep (fn [[k v]]
(let [cls (cond
(keyword? k)
(let [cn (name k)]
(or (get *css-data* (keyword cn)) cn))
(let [knm (name k)
kns (namespace k)]
(case kns
"global" knm
"old-css" (if (nil? *css-data*) knm "")
(or (get *css-data* (keyword knm)) knm)))
(string? k)
k)]
(when cls
@ -75,7 +91,8 @@
(let [fname (-> *ns* meta :file)
path (str (subs fname 0 (- (count fname) 4)) "css.json")
data (-> (slurp (io/resource path))
(json/read-str :key-fn keyword))]
(json/read-str :key-fn keyword)
(or {}))]
(if (symbol? (first params))
`(if ~(with-meta (first params) {:tag 'boolean})

View file

@ -302,11 +302,14 @@
(fn [entries _]
(run! (partial rx/push! intersection-subject) (seq entries)))
#js {:rootMargin "0px"
:threshold 1.0})))
:threshold #js [0 1.0]})))
(defn use-visible
[ref & {:keys [once?]}]
(let [[state update-state!] (mf/useState false)]
(let [state (mf/useState false)
update-state! (aget state 1)
state (aget state 0)]
(mf/with-effect [once?]
(let [node (mf/ref-val ref)
stream (->> intersection-subject
@ -314,15 +317,16 @@
(let [target (unchecked-get entry "target")]
(identical? target node))))
(rx/map (fn [entry]
(let [ratio (unchecked-get entry "intersectionRatio")
intersecting? (unchecked-get entry "isIntersecting")]
(or intersecting? (> ratio 0.5)))))
(let [ratio (unchecked-get entry "intersectionRatio")
intersecting? (unchecked-get entry "isIntersecting")
intersecting? (or ^boolean intersecting?
^boolean (> ratio 0.5))]
(when (and (true? intersecting?) (true? once?))
(.unobserve ^js @intersection-observer node))
intersecting?)))
(rx/dedupe))
stream (if once?
(->> stream
(rx/filter identity)
(rx/take 1))
stream)
subs (rx/subscribe stream update-state!)]
(.observe ^js @intersection-observer node)
(fn []

View file

@ -34,7 +34,7 @@
[shape hover?]
(fn [event]
(when-not (or (cph/group-shape? shape)
(cph/is-direct-child-of-root? shape))
(cph/root-frame? shape))
(dom/prevent-default event)
(dom/stop-propagation event)
(st/emit! (dv/hover-shape (:id shape) hover?)))))
@ -42,7 +42,7 @@
(defn select-shape [shape]
(fn [event]
(when-not (or (cph/group-shape? shape)
(cph/is-direct-child-of-root? shape))
(cph/root-frame? shape))
(dom/stop-propagation event)
(dom/prevent-default event)
(cond

View file

@ -53,9 +53,8 @@
;; We group the objects together per frame-id so if an object of a different
;; frame changes won't affect the rendering frame
frame-objects
(mf/use-memo
(mf/deps objects)
#(cph/objects-by-frame objects))]
(mf/with-memo [objects]
(cph/objects-by-frame objects))]
[:g {:id (dm/str "shape-" uuid/zero)}
[:& (mf/provider ctx/active-frames) {:value active-frames}
@ -68,46 +67,47 @@
[:g.frame-children
(for [shape shapes]
[:g.ws-shape-wrapper {:key (:id shape)}
(cond
(not (cph/frame-shape? shape))
[:& shape-wrapper
{:shape shape}]
(cph/is-direct-child-of-root? shape)
[:g.ws-shape-wrapper {:key (dm/str (dm/get-prop shape :id))}
(if ^boolean (cph/frame-shape? shape)
[:& root-frame-wrapper
{:shape shape
:objects (get frame-objects (:id shape))
:thumbnail? (not (contains? active-frames (:id shape)))}]
:objects (get frame-objects (dm/get-prop shape :id))
:thumbnail? (not (contains? active-frames (dm/get-prop shape :id)))}]
[:& shape-wrapper {:shape shape}])])]]]))
:else
[:& nested-frame-wrapper
{:shape shape
:objects (get frame-objects (:id shape))}])])]]]))
(defn- check-shape-wrapper-props
[np op]
(frame/check-shape (unchecked-get np "shape")
(unchecked-get op "shape")))
(mf/defc shape-wrapper
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))]
{::mf/wrap [#(mf/memo' % check-shape-wrapper-props)]
::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
(let [shape (unchecked-get props "shape")
shape-type (dm/get-prop shape :type)
shape-id (dm/get-prop shape :id)
;; FIXME: WARN: this breaks react rule of hooks (hooks can't be under conditional)
active-frames
(when (cph/is-direct-child-of-root? shape) (mf/use-ctx ctx/active-frames))
(when (cph/root-frame? shape)
(mf/use-ctx ctx/active-frames))
thumbnail?
(and (some? active-frames)
(not (contains? active-frames (:id shape))))
(not (contains? active-frames shape-id)))
opts #js {:shape shape :thumbnail? thumbnail?}
[wrapper wrapper-props]
(if (= :svg-raw (:type shape))
(if (= :svg-raw shape-type)
[mf/Fragment nil]
["g" #js {:className "workspace-shape-wrapper"}])]
(when (and (some? shape) (not (:hidden shape)))
(when (and (some? shape)
(not ^boolean (:hidden shape)))
[:> wrapper wrapper-props
(case (:type shape)
(case shape-type
:path [:> path/path-wrapper opts]
:text [:> text/text-wrapper opts]
:group [:> group-wrapper opts]
@ -125,4 +125,3 @@
(def bool-wrapper (bool/bool-wrapper-factory shape-wrapper))
(def root-frame-wrapper (frame/root-frame-wrapper-factory shape-wrapper))
(def nested-frame-wrapper (frame/nested-frame-wrapper-factory shape-wrapper))

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.common.record :as cr]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwt]
[app.main.refs :as refs]
@ -25,17 +26,36 @@
[beicon.core :as rx]
[rumext.v2 :as mf]))
(def ^:private excluded-attrs
#{:blocked
:hide-fill-on-export
:collapsed
:remote-synced
:exports})
(defn check-shape
[new-shape old-shape]
(cr/-equiv-with-exceptions old-shape new-shape excluded-attrs))
(defn check-frame-props
[np op]
(check-shape (unchecked-get np "shape")
(unchecked-get op "shape")))
(defn frame-shape-factory
[shape-wrapper]
(let [frame-shape (frame/frame-shape shape-wrapper)]
(mf/fnc frame-shape-inner
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))]
{::mf/wrap [#(mf/memo' % check-frame-props)]
::mf/wrap-props false
::mf/forward-ref true}
[props ref]
(let [shape (unchecked-get props "shape")
childs-ref (mf/use-memo (mf/deps (:id shape)) #(refs/children-objects (:id shape)))
shape-id (dm/get-prop shape :id)
childs-ref (mf/with-memo [shape-id]
(refs/children-objects shape-id))
childs (mf/deref childs-ref)]
[:& (mf/provider embed/context) {:value true}
@ -46,8 +66,8 @@
[new-props old-props]
(and (= (unchecked-get new-props "thumbnail?")
(unchecked-get old-props "thumbnail?"))
(= (unchecked-get new-props "shape")
(unchecked-get old-props "shape"))))
(check-shape (unchecked-get new-props "shape")
(unchecked-get old-props "shape"))))
(defn nested-frame-wrapper-factory
[shape-wrapper]

View file

@ -125,34 +125,32 @@
(defn text-properties-equal?
[shape other]
;; FIXME: use dm/get-prop
(or (identical? shape other)
(and
;; Check if both shapes are equivalent removing their geometry data
(= (dissoc shape :migrate :points :selrect :height :width :x :y :position-data :modifiers)
(dissoc other :migrate :points :selrect :height :width :x :y :position-data :modifiers))
;; Check if the position and size is close. If any of these changes the shape has changed
;; and if not there is no geometry relevant change
(mth/close? (:x shape) (:x other))
(mth/close? (:y shape) (:y other))
(mth/close? (:width shape) (:width other))
(mth/close? (:height shape) (:height other)))))
(and (= (:content shape) (:content other))
;; Check if the position and size is close. If any of these changes the shape has changed
;; and if not there is no geometry relevant change
(mth/close? (:x shape) (:x other))
(mth/close? (:y shape) (:y other))
(mth/close? (:width shape) (:width other))
(mth/close? (:height shape) (:height other)))))
(mf/defc text-changes-renderer
{::mf/wrap-props false}
[props]
(let [text-shapes (obj/get props "text-shapes")
(let [text-shapes (unchecked-get props "text-shapes")
prev-text-shapes (hooks/use-previous text-shapes)
;; We store in the state the texts still pending to be calculated so we can
;; get its position
pending-update (mf/use-state {})
pending-update* (mf/use-state {})
pending-update (deref pending-update*)
text-change?
(fn [id]
(let [new-shape (get text-shapes id)
old-shape (get prev-text-shapes id)
remote? (some? (-> new-shape meta :session-id))]
remote? (some? (-> new-shape meta :session-id))]
(or (and (not remote?) ;; changes caused by a remote peer are not re-calculated
(not (text-properties-equal? old-shape new-shape)))
@ -160,9 +158,8 @@
(nil? (:position-data new-shape)))))
changed-texts
(mf/use-memo
(mf/deps text-shapes @pending-update)
#(let [pending-shapes (into #{} (vals @pending-update))]
(mf/with-memo [text-shapes pending-update]
(let [pending-shapes (into #{} (vals pending-update))]
(->> (keys text-shapes)
(filter (fn [id]
(or (contains? pending-shapes id)
@ -170,18 +167,18 @@
(map (d/getf text-shapes)))))
handle-update-shape
(mf/use-callback
(mf/use-fn
(fn [shape node]
;; Unique to indentify the pending state
(let [uid (js/Symbol)]
(swap! pending-update assoc uid (:id shape))
(swap! pending-update* assoc uid (:id shape))
(p/then
(update-text-shape shape node)
#(swap! pending-update dissoc uid)))))]
#(swap! pending-update* dissoc uid)))))]
[:.text-changes-renderer
(for [{:keys [id] :as shape} changed-texts]
[:& text-container {:key (str (dm/str "text-container-" id))
[:& text-container {:key (dm/str "text-container-" id)
:shape shape
:on-update handle-update-shape}])]))
@ -213,7 +210,7 @@
[:.text-changes-renderer
(for [{:keys [id] :as shape} changed-texts]
[:& text-container {:key (str (dm/str "text-container-" id))
[:& text-container {:key (dm/str "text-container-" id)
:shape shape
:on-update handle-update-shape}])]))

View file

@ -5,7 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.assets
(:require-macros [app.main.style :refer [css]])
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.data.modal :as modal]
@ -80,7 +80,6 @@
:open-menu false})
filters (deref filters*)
term (:term filters)
ordering (:ordering filters)
list-style (:list-style filters)
menu-open? (:open-menu filters)
section (:section filters)
@ -175,22 +174,22 @@
:data-test "typographies"}]]
(if ^boolean new-css-system
[:div {:class (css :assets-bar)}
[:div {:class (css :assets-header)}
[:div {:class (stl/css :assets-bar)}
[:div {:class (stl/css :assets-header)}
(when-not ^boolean read-only?
[:button {:class (css :libraries-button)
:on-click #(modal/show! :libraries-dialog {})}
[:span {:class (css :libraries-icon)}
[:button {:class (stl/css :libraries-button)
:on-click show-libraries-dialog}
[:span {:class (stl/css :libraries-icon)}
i/library-refactor]
(tr "workspace.assets.libraries")])
[:div {:class (css :search-wrapper)}
[:div {:class (stl/css :search-wrapper)}
[:& search-bar {:on-change on-search-term-change
:value term
:placeholder (tr "workspace.assets.search")}
[:button
{:on-click on-open-menu
:class (dom/classnames (css :section-button) true)}
:class (stl/css :section-button)}
i/filter-refactor]]
[:& context-menu-a11y
{:on-close on-menu-close
@ -203,7 +202,7 @@
:left 64
:options options
:workspace? true}]
[:button {:class (css :sort-button)
[:button {:class (stl/css :sort-button)
:on-click toggle-ordering}
(if reverse-sort?
i/asc-sort-refactor
@ -212,7 +211,7 @@
[:& (mf/provider cmm/assets-filters) {:value filters}
[:& (mf/provider cmm/assets-toggle-ordering) {:value toggle-ordering}
[:& (mf/provider cmm/assets-toggle-list-style) {:value toggle-list-style}
[:div {:class (dom/classnames (css :libraries-wrapper) true)}
[:div {:class (stl/css :libraries-wrapper)}
[:& assets-local-library {:filters filters}]
[:& assets-libraries {:filters filters}]]]]]]

View file

@ -303,11 +303,12 @@
[:div.dragging])])))
(mf/defc colors-group
[{:keys [file-id prefix groups open-groups local? selected
[{:keys [file-id prefix groups open-groups force-open? local? selected
multi-colors? multi-assets? on-asset-click on-assets-delete
on-clear-selection on-group on-rename-group on-ungroup colors
selected-full]}]
(let [group-open? (get open-groups prefix true)
(let [group-open? (or ^boolean force-open?
^boolean (get open-groups prefix (if (= prefix "") true false)))
new-css-system (mf/use-ctx ctx/new-css-system)
dragging* (mf/use-state false)
dragging? (deref dragging*)
@ -391,6 +392,7 @@
:key (dm/str "group-" path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:local? local?
:selected selected
:multi-colors? multi-colors?
@ -454,6 +456,7 @@
:key (dm/str "group-" path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:local? local?
:selected selected
:multi-colors? multi-colors?
@ -468,7 +471,7 @@
:selected-full selected-full}]))])])))
(mf/defc colors-section
[{:keys [file-id local? colors open? open-status-ref selected reverse-sort?
[{:keys [file-id local? colors open? force-open? open-status-ref selected reverse-sort?
on-asset-click on-assets-delete on-clear-selection] :as props}]
(let [selected (:colors selected)
@ -607,6 +610,7 @@
:prefix ""
:groups groups
:open-groups open-groups
:force-open? force-open?
:local? local?
:selected selected
:multi-colors? multi-colors?

View file

@ -34,21 +34,23 @@
(defn apply-filters
[coll {:keys [ordering term] :as filters}]
(let [reverse? (= :desc ordering)
comp-fn (if ^boolean reverse? > <)]
(->> coll
(filter (fn [item]
(or (matches-search (:name item "!$!") term)
(matches-search (:value item "!$!") term))))
; Sort by folder order, but
; putting all "root" items
; always first, independently
; of sort order.
(sort-by #(str/lower (cph/merge-path-item (if (empty? (:path %))
(if reverse? "z" "a")
(:path %))
(:name %)))
comp-fn))))
(let [reverse? (= :desc ordering)]
(cond->> coll
(not ^boolean (str/empty? term))
(filter (fn [item]
(or (matches-search (:name item "!$!") term)
(matches-search (:path item "!$!") term)
(matches-search (:value item "!$!") term))))
;; Sort by folder order, but putting all "root" items always
;; first, independently of sort order.
:always
(sort-by (fn [{:keys [path name] :as item}]
(let [path (if (str/empty? path)
(if reverse? "z" "a")
path)]
(str/lower (cph/merge-path-item path name))))
(if ^boolean reverse? > <)))))
(defn add-group
[asset group-name]

View file

@ -25,6 +25,7 @@
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.sidebar.assets.groups :as grp]
@ -65,6 +66,8 @@
new-css-system (mf/use-ctx ctx/new-css-system)
component-id (:id component)
visible? (h/use-visible item-ref :once? true)
;; NOTE: we don't use reactive deref for it because we don't
;; really need rerender on any change on the file change. If
;; the component changes, it will trigger rerender anyway.
@ -180,8 +183,9 @@
(when (and (some? root-shape)
(some? container))
[:*
[:& component-svg {:root-shape root-shape
:objects (:objects container)}]
(when visible?
[:& component-svg {:root-shape root-shape
:objects (:objects container)}])
(let [renaming? (= renaming (:id component))]
[:*
[:& editable-label
@ -202,11 +206,12 @@
(mf/defc components-group
{::mf/wrap-props false}
[{:keys [file-id prefix groups open-groups renaming listing-thumbs? selected on-asset-click
[{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected on-asset-click
on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu
selected-full]}]
(let [group-open? (get open-groups prefix true)
(let [group-open? (or ^boolean force-open?
^boolean (get open-groups prefix (if (= prefix "") true false)))
new-css-system (mf/use-ctx ctx/new-css-system)
dragging* (mf/use-state false)
dragging? (deref dragging*)
@ -232,6 +237,7 @@
(mf/deps dragging* prefix selected-paths selected-full)
(fn [event]
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-component)))]
(if ^boolean new-css-system
[:div {:class (dom/classnames (css :component-group) true)
:on-drag-enter on-drag-enter
@ -294,6 +300,7 @@
:prefix (cph/merge-path-item prefix path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:renaming renaming
:listing-thumbs? listing-thumbs?
:selected selected
@ -367,6 +374,7 @@
:prefix (cph/merge-path-item prefix path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:renaming renaming
:listing-thumbs? listing-thumbs?
:selected selected
@ -381,8 +389,9 @@
(mf/defc components-section
{::mf/wrap-props false}
[{:keys [file-id local? components listing-thumbs? open? reverse-sort? selected
on-asset-click on-assets-delete on-clear-selection open-status-ref]}]
[{:keys [file-id local? components listing-thumbs? open? force-open?
reverse-sort? selected on-asset-click on-assets-delete
on-clear-selection open-status-ref]}]
(let [input-ref (mf/use-ref nil)
@ -599,24 +608,27 @@
:multi true
:ref input-ref
:on-selected on-file-selected}]])]))
[:& cmm/asset-section-block {:role :content}
[:& components-group {:file-id file-id
:prefix ""
:groups groups
:open-groups open-groups
:renaming (when ^boolean renaming? current-component-id)
:listing-thumbs? listing-thumbs?
:selected selected
:on-asset-click on-asset-click
:on-drag-start on-drag-start
:do-rename do-rename
:cancel-rename cancel-rename
:on-rename-group on-rename-group
:on-group on-group
:on-ungroup on-ungroup
:on-context-menu on-context-menu
:selected-full selected-full}]
(when local?
(when ^boolean open?
[:& components-group {:file-id file-id
:prefix ""
:groups groups
:open-groups open-groups
:force-open? force-open?
:renaming (when ^boolean renaming? current-component-id)
:listing-thumbs? listing-thumbs?
:selected selected
:on-asset-click on-asset-click
:on-drag-start on-drag-start
:do-rename do-rename
:cancel-rename cancel-rename
:on-rename-group on-rename-group
:on-group on-group
:on-ungroup on-ungroup
:on-context-menu on-context-menu
:selected-full selected-full}])
(when ^boolean local?
[:& cmm/assets-context-menu
{:on-close on-close-menu
:state @menu-state

View file

@ -149,7 +149,6 @@
(or (pos? (count typographies))
(str/empty? filters-term)))
selected-lens (mf/with-memo [file-id]
(-> (l/key file-id)
(l/derived lens:selected)))
@ -160,6 +159,12 @@
(count (get selected :colors))
(count (get selected :typographies)))
has-term? (not ^boolean (str/empty? filters-term))
force-open-components? (when ^boolean has-term? (> 60 (count components)))
force-open-colors? (when ^boolean has-term? (> 60 (count colors)))
force-open-graphics? (when ^boolean has-term? (> 60 (count media)))
force-open-typographies? (when ^boolean has-term? (> 60 (count typographies)))
extend-selected
(fn [type asset-groups asset-id]
(letfn [(flatten-groups [groups]
@ -248,7 +253,9 @@
:local? local?
:components components
:listing-thumbs? listing-thumbs?
:open? (get open-status :components true)
:open? (or ^boolean force-open-components?
^boolean (get open-status :components false))
:force-open? force-open-components?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -263,7 +270,9 @@
:local? local?
:objects media
:listing-thumbs? listing-thumbs?
:open? (get open-status :graphics true)
:open? (or ^boolean force-open-graphics?
^boolean (get open-status :graphics false))
:force-open? force-open-graphics?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -276,7 +285,9 @@
{:file-id file-id
:local? local?
:colors colors
:open? (get open-status :colors true)
:open? (or ^boolean force-open-colors?
^boolean (get open-status :colors false))
:force-open? force-open-colors?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -290,7 +301,9 @@
:file-id (:id file)
:local? local?
:typographies typographies
:open? (get open-status :typographies true)
:open? (or ^boolean force-open-typographies?
^boolean (get open-status :typographies false))
:force-open? force-open-typographies?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -327,7 +340,9 @@
:local? local?
:components components
:listing-thumbs? listing-thumbs?
:open? (get open-status :components true)
:open? (or ^boolean force-open-components?
^boolean (get open-status :components false))
:force-open? force-open-components?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -342,7 +357,9 @@
:local? local?
:objects media
:listing-thumbs? listing-thumbs?
:open? (get open-status :graphics true)
:open? (or ^boolean force-open-graphics?
^boolean (get open-status :graphics false))
:force-open? force-open-graphics?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -355,7 +372,9 @@
{:file-id file-id
:local? local?
:colors colors
:open? (get open-status :colors true)
:open? (or ^boolean force-open-colors?
^boolean (get open-status :colors false))
:force-open? force-open-colors?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected
@ -369,7 +388,9 @@
:file-id (:id file)
:local? local?
:typographies typographies
:open? (get open-status :typographies true)
:open? (or ^boolean force-open-typographies?
^boolean (get open-status :typographies false))
:force-open? force-open-typographies?
:open-status-ref open-status-ref
:reverse-sort? reverse-sort?
:selected selected

View file

@ -161,7 +161,7 @@
[:div.dragging])])])])))
(mf/defc graphics-group
[{:keys [file-id prefix groups open-groups renaming listing-thumbs? selected-objects on-asset-click
[{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected-objects on-asset-click
on-drag-start do-rename cancel-rename on-rename-group on-ungroup
on-context-menu selected-full]}]
(let [group-open? (get open-groups prefix true)
@ -249,6 +249,7 @@
:prefix (cph/merge-path-item prefix path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:renaming renaming
:listing-thumbs? listing-thumbs?
:selected-objects selected-objects
@ -315,6 +316,7 @@
:prefix (cph/merge-path-item prefix path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:renaming renaming
:listing-thumbs? listing-thumbs?
:selected-objects selected-objects
@ -330,7 +332,7 @@
(mf/defc graphics-section
{::mf/wrap-props false}
[{:keys [file-id project-id local? objects listing-thumbs? open? open-status-ref selected reverse-sort?
[{:keys [file-id project-id local? objects listing-thumbs? open? force-open? open-status-ref selected reverse-sort?
on-asset-click on-assets-delete on-clear-selection]}]
(let [input-ref (mf/use-ref nil)
state (mf/use-state {:renaming nil :object-id nil})
@ -518,6 +520,7 @@
:prefix ""
:groups groups
:open-groups open-groups
:force-open? force-open?
:renaming (:renaming @state)
:listing-thumbs? listing-thumbs?
:selected selected

View file

@ -149,7 +149,7 @@
(mf/defc typographies-group
{::mf/wrap-props false}
[{:keys [file-id prefix groups open-groups file local? selected local-data
[{:keys [file-id prefix groups open-groups force-open? file local? selected local-data
editing-id renaming-id on-asset-click handle-change apply-typography on-rename-group
on-ungroup on-context-menu selected-full]}]
(let [group-open? (get open-groups prefix true)
@ -236,6 +236,7 @@
:key (dm/str "group-" path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:file file
:local? local?
:selected selected
@ -297,6 +298,7 @@
:key (dm/str "group-" path-item)
:groups content
:open-groups open-groups
:force-open? force-open?
:file file
:local? local?
:selected selected
@ -312,7 +314,7 @@
(mf/defc typographies-section
{::mf/wrap-props false}
[{:keys [file file-id local? typographies open? open-status-ref selected reverse-sort?
[{:keys [file file-id local? typographies open? force-open? open-status-ref selected reverse-sort?
on-asset-click on-assets-delete on-clear-selection]}]
(let [state (mf/use-state {:detail-open? false :id nil})
local-data (mf/deref lens:typography-section-state)
@ -506,6 +508,7 @@
:prefix ""
:groups groups
:open-groups open-groups
:force-open? force-open?
:state state
:file file
:local? local?

View file

@ -141,7 +141,7 @@
(fn []
(let [parent-id
(->> @hover-ids
(d/seek (partial cph/is-direct-child-of-root? base-objects)))]
(d/seek (partial cph/root-frame? base-objects)))]
(when (some? parent-id)
(get base-objects parent-id)))))
@ -244,7 +244,7 @@
first-selected-shape (first selected-shapes)
selecting-first-level-frame? (and one-selected-shape?
(cph/is-direct-child-of-root? first-selected-shape))
(cph/root-frame? first-selected-shape))
offset-x (if selecting-first-level-frame?
(:x first-selected-shape)

View file

@ -293,7 +293,7 @@
(not (is-guide-inside-frame? (assoc guide :position pos) frame)))]
(when (or (nil? frame)
(and (cph/is-direct-child-of-root? frame)
(and (cph/root-frame? frame)
(not (ctst/rotated-frame? frame))))
[:g.guide-area {:opacity (when frame-guide-outside? 0)}
(when-not disabled-guides?

View file

@ -217,7 +217,7 @@
root-frame-with-data?
#(as-> (get objects %) obj
(and (cph/is-direct-child-of-root? obj)
(and (cph/root-frame? obj)
(d/not-empty? (:shapes obj))
(not (ctk/instance-head? obj))
(not (ctk/main-instance? obj))))
@ -240,9 +240,10 @@
no-fill-nested-frames?
(fn [id]
(and (cph/frame-shape? objects id)
(not (cph/is-direct-child-of-root? objects id))
(empty? (dm/get-in objects [id :fills]))))
(let [shape (get objects id)]
(and (cph/frame-shape? shape)
(not (cph/is-direct-child-of-root? shape))
(empty? (get shape :fills)))))
hover-shape
(->> ids
@ -276,7 +277,7 @@
(let [all-frames (mf/use-memo (mf/deps objects) #(ctt/get-root-frames-ids objects))
selected-frames (mf/use-memo (mf/deps selected) #(->> all-frames (filter selected)))
xf-selected-frame (comp (remove cph/is-direct-child-of-root?)
xf-selected-frame (comp (remove cph/root-frame?)
(map #(cph/get-shape-id-root-frame objects %)))
selected-shapes-frames (mf/use-memo (mf/deps selected) #(into #{} xf-selected-frame selected))

View file

@ -30,7 +30,7 @@
(not (ctl/layout-absolute? shape))
(or (cph/group-shape? shape)
(cph/frame-shape? shape)))
(cph/is-direct-child-of-root? shape))
(cph/root-frame? shape))
:relative
(and (ctl/any-layout-immediate-child? objects shape)
@ -54,14 +54,14 @@
;;shape (gsh/transform-shape)
shape-value (get selrect coord)
]
(when (and (not (cph/is-direct-child-of-root? shape))
(when (and (not (cph/root-frame? shape))
(or (not (ctl/any-layout-immediate-child? objects shape))
(ctl/layout-absolute? shape)))
(- shape-value parent-value))))
#_(defn get-shape-position
[shape objects coord]
(when-not (or (cph/is-direct-child-of-root? shape)
(when-not (or (cph/root-frame? shape)
(and (ctl/any-layout-immediate-child? objects shape)
(not (ctl/layout-absolute? shape))))
(let [parent (get objects (:parent-id shape))