🎉 Add workspace read-only setting

This commit is contained in:
Pablo Alba 2022-11-22 16:52:31 +01:00
parent 6b7adec617
commit cd47c0356a
22 changed files with 567 additions and 460 deletions

View file

@ -39,6 +39,7 @@
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.data.workspace.collapse :as dwco] [app.main.data.workspace.collapse :as dwco]
[app.main.data.workspace.drawing :as dwd] [app.main.data.workspace.drawing :as dwd]
[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.groups :as dwg] [app.main.data.workspace.groups :as dwg]
@ -1769,6 +1770,28 @@
(rx/of (modal/hide) (rx/of (modal/hide)
(complete-remove-graphics))))))) (complete-remove-graphics)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Read only
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn set-workspace-read-only
[read-only?]
(ptk/reify ::set-workspace-read-only
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-global :read-only?] read-only?))
ptk/WatchEvent
(watch [_ _ _]
(if read-only?
(rx/of :interrupt
(dwdc/clear-drawing)
(remove-layout-flag :colorpalette)
(remove-layout-flag :textpalette))
(rx/empty)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Exports ;; Exports
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -20,6 +20,7 @@
[app.main.data.workspace.texts :as dwtxt] [app.main.data.workspace.texts :as dwtxt]
[app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.transforms :as dwt]
[app.main.data.workspace.undo :as dwu] [app.main.data.workspace.undo :as dwu]
[app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
[app.util.dom :as dom])) [app.util.dom :as dom]))
@ -33,6 +34,11 @@
(-> (dw/toggle-layout-flag flag) (-> (dw/toggle-layout-flag flag)
(vary-meta assoc ::ev/origin "workspace-shortcuts"))) (vary-meta assoc ::ev/origin "workspace-shortcuts")))
(defn emit-when-no-readonly
[& events]
(when-not (deref refs/workspace-read-only?)
(run! st/emit! events)))
;; Shortcuts format https://github.com/ccampbell/mousetrap ;; Shortcuts format https://github.com/ccampbell/mousetrap
(def base-shortcuts (def base-shortcuts
@ -40,17 +46,17 @@
:undo {:tooltip (ds/meta "Z") :undo {:tooltip (ds/meta "Z")
:command (ds/c-mod "z") :command (ds/c-mod "z")
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! dwc/undo)} :fn #(emit-when-no-readonly dwc/undo)}
:redo {:tooltip (ds/meta "Y") :redo {:tooltip (ds/meta "Y")
:command [(ds/c-mod "shift+z") (ds/c-mod "y")] :command [(ds/c-mod "shift+z") (ds/c-mod "y")]
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! dwc/redo)} :fn #(emit-when-no-readonly dwc/redo)}
:clear-undo {:tooltip (ds/alt "Z") :clear-undo {:tooltip (ds/alt "Z")
:command "alt+z" :command "alt+z"
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! dwu/reinitialize-undo)} :fn #(emit-when-no-readonly dwu/reinitialize-undo)}
:copy {:tooltip (ds/meta "C") :copy {:tooltip (ds/meta "C")
:command (ds/c-mod "c") :command (ds/c-mod "c")
@ -60,8 +66,8 @@
:cut {:tooltip (ds/meta "X") :cut {:tooltip (ds/meta "X")
:command (ds/c-mod "x") :command (ds/c-mod "x")
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/copy-selected) :fn #(emit-when-no-readonly (dw/copy-selected)
(dw/delete-selected))} (dw/delete-selected))}
:paste {:tooltip (ds/meta "V") :paste {:tooltip (ds/meta "V")
:disabled true :disabled true
@ -72,29 +78,29 @@
:delete {:tooltip (ds/supr) :delete {:tooltip (ds/supr)
:command ["del" "backspace"] :command ["del" "backspace"]
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/delete-selected))} :fn #(emit-when-no-readonly (dw/delete-selected))}
:duplicate {:tooltip (ds/meta "D") :duplicate {:tooltip (ds/meta "D")
:command (ds/c-mod "d") :command (ds/c-mod "d")
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/duplicate-selected true))} :fn #(emit-when-no-readonly (dw/duplicate-selected true))}
:start-editing {:tooltip (ds/enter) :start-editing {:tooltip (ds/enter)
:command "enter" :command "enter"
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/start-editing-selected))} :fn #(emit-when-no-readonly (dw/start-editing-selected))}
:start-measure {:tooltip (ds/alt "") :start-measure {:tooltip (ds/alt "")
:command ["alt" "."] :command ["alt" "."]
:type "keydown" :type "keydown"
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/toggle-distances-display true))} :fn #(emit-when-no-readonly (dw/toggle-distances-display true))}
:stop-measure {:tooltip (ds/alt "") :stop-measure {:tooltip (ds/alt "")
:command ["alt" "."] :command ["alt" "."]
:type "keyup" :type "keyup"
:subsections [:edit] :subsections [:edit]
:fn #(st/emit! (dw/toggle-distances-display false))} :fn #(emit-when-no-readonly (dw/toggle-distances-display false))}
:escape {:tooltip (ds/esc) :escape {:tooltip (ds/esc)
:command "escape" :command "escape"
@ -107,149 +113,149 @@
:group {:tooltip (ds/meta "G") :group {:tooltip (ds/meta "G")
:command (ds/c-mod "g") :command (ds/c-mod "g")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! dw/group-selected)} :fn #(emit-when-no-readonly dw/group-selected)}
:ungroup {:tooltip (ds/shift "G") :ungroup {:tooltip (ds/shift "G")
:command "shift+g" :command "shift+g"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! dw/ungroup-selected)} :fn #(emit-when-no-readonly dw/ungroup-selected)}
:mask {:tooltip (ds/meta "M") :mask {:tooltip (ds/meta "M")
:command (ds/c-mod "m") :command (ds/c-mod "m")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! dw/mask-group)} :fn #(emit-when-no-readonly dw/mask-group)}
:unmask {:tooltip (ds/meta-shift "M") :unmask {:tooltip (ds/meta-shift "M")
:command (ds/c-mod "shift+m") :command (ds/c-mod "shift+m")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! dw/unmask-group)} :fn #(emit-when-no-readonly dw/unmask-group)}
:create-component {:tooltip (ds/meta "K") :create-component {:tooltip (ds/meta "K")
:command (ds/c-mod "k") :command (ds/c-mod "k")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwl/add-component))} :fn #(emit-when-no-readonly (dwl/add-component))}
:detach-component {:tooltip (ds/meta-shift "K") :detach-component {:tooltip (ds/meta-shift "K")
:command (ds/c-mod "shift+k") :command (ds/c-mod "shift+k")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! dwl/detach-selected-components)} :fn #(emit-when-no-readonly dwl/detach-selected-components)}
:flip-vertical {:tooltip (ds/shift "V") :flip-vertical {:tooltip (ds/shift "V")
:command "shift+v" :command "shift+v"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/flip-vertical-selected))} :fn #(emit-when-no-readonly (dw/flip-vertical-selected))}
:flip-horizontal {:tooltip (ds/shift "H") :flip-horizontal {:tooltip (ds/shift "H")
:command "shift+h" :command "shift+h"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/flip-horizontal-selected))} :fn #(emit-when-no-readonly (dw/flip-horizontal-selected))}
:bring-forward {:tooltip (ds/meta ds/up-arrow) :bring-forward {:tooltip (ds/meta ds/up-arrow)
:command (ds/c-mod "up") :command (ds/c-mod "up")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/vertical-order-selected :up))} :fn #(emit-when-no-readonly (dw/vertical-order-selected :up))}
:bring-backward {:tooltip (ds/meta ds/down-arrow) :bring-backward {:tooltip (ds/meta ds/down-arrow)
:command (ds/c-mod "down") :command (ds/c-mod "down")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/vertical-order-selected :down))} :fn #(emit-when-no-readonly (dw/vertical-order-selected :down))}
:bring-front {:tooltip (ds/meta-shift ds/up-arrow) :bring-front {:tooltip (ds/meta-shift ds/up-arrow)
:command (ds/c-mod "shift+up") :command (ds/c-mod "shift+up")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/vertical-order-selected :top))} :fn #(emit-when-no-readonly (dw/vertical-order-selected :top))}
:bring-back {:tooltip (ds/meta-shift ds/down-arrow) :bring-back {:tooltip (ds/meta-shift ds/down-arrow)
:command (ds/c-mod "shift+down") :command (ds/c-mod "shift+down")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dw/vertical-order-selected :bottom))} :fn #(emit-when-no-readonly (dw/vertical-order-selected :bottom))}
:move-fast-up {:tooltip (ds/shift ds/up-arrow) :move-fast-up {:tooltip (ds/shift ds/up-arrow)
:command "shift+up" :command "shift+up"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :up true))} :fn #(emit-when-no-readonly (dwt/move-selected :up true))}
:move-fast-down {:tooltip (ds/shift ds/down-arrow) :move-fast-down {:tooltip (ds/shift ds/down-arrow)
:command "shift+down" :command "shift+down"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :down true))} :fn #(emit-when-no-readonly (dwt/move-selected :down true))}
:move-fast-right {:tooltip (ds/shift ds/right-arrow) :move-fast-right {:tooltip (ds/shift ds/right-arrow)
:command "shift+right" :command "shift+right"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :right true))} :fn #(emit-when-no-readonly (dwt/move-selected :right true))}
:move-fast-left {:tooltip (ds/shift ds/left-arrow) :move-fast-left {:tooltip (ds/shift ds/left-arrow)
:command "shift+left" :command "shift+left"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :left true))} :fn #(emit-when-no-readonly (dwt/move-selected :left true))}
:move-unit-up {:tooltip ds/up-arrow :move-unit-up {:tooltip ds/up-arrow
:command "up" :command "up"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :up false))} :fn #(emit-when-no-readonly (dwt/move-selected :up false))}
:move-unit-down {:tooltip ds/down-arrow :move-unit-down {:tooltip ds/down-arrow
:command "down" :command "down"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :down false))} :fn #(emit-when-no-readonly (dwt/move-selected :down false))}
:move-unit-left {:tooltip ds/right-arrow :move-unit-left {:tooltip ds/right-arrow
:command "right" :command "right"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :right false))} :fn #(emit-when-no-readonly (dwt/move-selected :right false))}
:move-unit-right {:tooltip ds/left-arrow :move-unit-right {:tooltip ds/left-arrow
:command "left" :command "left"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwt/move-selected :left false))} :fn #(emit-when-no-readonly (dwt/move-selected :left false))}
:artboard-selection {:tooltip (ds/meta (ds/alt "G")) :artboard-selection {:tooltip (ds/meta (ds/alt "G"))
:command (ds/c-mod "alt+g") :command (ds/c-mod "alt+g")
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dws/create-artboard-from-selection))} :fn #(emit-when-no-readonly (dws/create-artboard-from-selection))}
:toogle-layout-flex {:tooltip (ds/shift "F") :toogle-layout-flex {:tooltip (ds/shift "F")
:command "shift+f" :command "shift+f"
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwsl/toogle-layout-flex))} :fn #(emit-when-no-readonly (dwsl/toogle-layout-flex))}
;; TOOLS ;; TOOLS
:draw-frame {:tooltip "B" :draw-frame {:tooltip "B"
:command ["b" "a"] :command ["b" "a"]
:subsections [:tools :basics] :subsections [:tools :basics]
:fn #(st/emit! (dwd/select-for-drawing :frame))} :fn #(emit-when-no-readonly (dwd/select-for-drawing :frame))}
:move {:tooltip "V" :move {:tooltip "V"
:command "v" :command "v"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! :interrupt)} :fn #(emit-when-no-readonly :interrupt)}
:draw-rect {:tooltip "R" :draw-rect {:tooltip "R"
:command "r" :command "r"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dwd/select-for-drawing :rect))} :fn #(emit-when-no-readonly (dwd/select-for-drawing :rect))}
:draw-ellipse {:tooltip "E" :draw-ellipse {:tooltip "E"
:command "e" :command "e"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dwd/select-for-drawing :circle))} :fn #(emit-when-no-readonly (dwd/select-for-drawing :circle))}
:draw-text {:tooltip "T" :draw-text {:tooltip "T"
:command "t" :command "t"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! dwtxt/start-edit-if-selected :fn #(emit-when-no-readonly dwtxt/start-edit-if-selected
(dwd/select-for-drawing :text))} (dwd/select-for-drawing :text))}
:draw-path {:tooltip "P" :draw-path {:tooltip "P"
:command "p" :command "p"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dwd/select-for-drawing :path))} :fn #(emit-when-no-readonly (dwd/select-for-drawing :path))}
:draw-curve {:tooltip (ds/shift "C") :draw-curve {:tooltip (ds/shift "C")
:command "shift+c" :command "shift+c"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dwd/select-for-drawing :curve))} :fn #(emit-when-no-readonly (dwd/select-for-drawing :curve))}
:add-comment {:tooltip "C" :add-comment {:tooltip "C"
:command "c" :command "c"
@ -264,74 +270,74 @@
:toggle-visibility {:tooltip (ds/meta-shift "H") :toggle-visibility {:tooltip (ds/meta-shift "H")
:command (ds/c-mod "shift+h") :command (ds/c-mod "shift+h")
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dw/toggle-visibility-selected))} :fn #(emit-when-no-readonly (dw/toggle-visibility-selected))}
:toggle-lock {:tooltip (ds/meta-shift "L") :toggle-lock {:tooltip (ds/meta-shift "L")
:command (ds/c-mod "shift+l") :command (ds/c-mod "shift+l")
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dw/toggle-lock-selected))} :fn #(emit-when-no-readonly (dw/toggle-lock-selected))}
:toggle-lock-size {:tooltip (ds/meta (ds/alt "L")) :toggle-lock-size {:tooltip (ds/meta (ds/alt "L"))
:command (ds/c-mod "alt+l") :command (ds/c-mod "alt+l")
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (dw/toggle-proportion-lock))} :fn #(emit-when-no-readonly (dw/toggle-proportion-lock))}
:toggle-scale-text {:tooltip "K" :toggle-scale-text {:tooltip "K"
:command "k" :command "k"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (toggle-layout-flag :scale-text))} :fn #(emit-when-no-readonly (toggle-layout-flag :scale-text))}
:open-color-picker {:tooltip "I" :open-color-picker {:tooltip "I"
:command "i" :command "i"
:subsections [:tools] :subsections [:tools]
:fn #(st/emit! (mdc/picker-for-selected-shape))} :fn #(emit-when-no-readonly (mdc/picker-for-selected-shape))}
:toggle-focus-mode {:command "f" :toggle-focus-mode {:command "f"
:tooltip "F" :tooltip "F"
:subsections [:basics :tools] :subsections [:basics :tools]
:fn #(st/emit! (dw/toggle-focus-mode))} :fn #(emit-when-no-readonly (dw/toggle-focus-mode))}
;; ITEM ALIGNMENT ;; ITEM ALIGNMENT
:align-left {:tooltip (ds/alt "A") :align-left {:tooltip (ds/alt "A")
:command "alt+a" :command "alt+a"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :hleft))} :fn #(emit-when-no-readonly (dw/align-objects :hleft))}
:align-right {:tooltip (ds/alt "D") :align-right {:tooltip (ds/alt "D")
:command "alt+d" :command "alt+d"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :hright))} :fn #(emit-when-no-readonly (dw/align-objects :hright))}
:align-top {:tooltip (ds/alt "W") :align-top {:tooltip (ds/alt "W")
:command "alt+w" :command "alt+w"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :vtop))} :fn #(emit-when-no-readonly (dw/align-objects :vtop))}
:align-hcenter {:tooltip (ds/alt "H") :align-hcenter {:tooltip (ds/alt "H")
:command "alt+h" :command "alt+h"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :hcenter))} :fn #(emit-when-no-readonly (dw/align-objects :hcenter))}
:align-vcenter {:tooltip (ds/alt "V") :align-vcenter {:tooltip (ds/alt "V")
:command "alt+v" :command "alt+v"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :vcenter))} :fn #(emit-when-no-readonly (dw/align-objects :vcenter))}
:align-bottom {:tooltip (ds/alt "S") :align-bottom {:tooltip (ds/alt "S")
:command "alt+s" :command "alt+s"
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/align-objects :vbottom))} :fn #(emit-when-no-readonly (dw/align-objects :vbottom))}
:h-distribute {:tooltip (ds/meta-shift (ds/alt "H")) :h-distribute {:tooltip (ds/meta-shift (ds/alt "H"))
:command (ds/c-mod "shift+alt+h") :command (ds/c-mod "shift+alt+h")
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/distribute-objects :horizontal))} :fn #(emit-when-no-readonly (dw/distribute-objects :horizontal))}
:v-distribute {:tooltip (ds/meta-shift (ds/alt "V")) :v-distribute {:tooltip (ds/meta-shift (ds/alt "V"))
:command (ds/c-mod "shift+alt+v") :command (ds/c-mod "shift+alt+v")
:subsections [:alignment] :subsections [:alignment]
:fn #(st/emit! (dw/distribute-objects :vertical))} :fn #(emit-when-no-readonly (dw/distribute-objects :vertical))}
;; MAIN MENU ;; MAIN MENU
@ -406,20 +412,20 @@
:toggle-history {:tooltip (ds/alt "H") :toggle-history {:tooltip (ds/alt "H")
:command (ds/a-mod "h") :command (ds/a-mod "h")
:subsections [:panels] :subsections [:panels]
:fn #(st/emit! (dw/go-to-layout :document-history))} :fn #(emit-when-no-readonly (dw/go-to-layout :document-history))}
:toggle-colorpalette {:tooltip (ds/alt "P") :toggle-colorpalette {:tooltip (ds/alt "P")
:command (ds/a-mod "p") :command (ds/a-mod "p")
:subsections [:panels] :subsections [:panels]
:fn #(do (r/set-resize-type! :bottom) :fn #(do (r/set-resize-type! :bottom)
(st/emit! (dw/remove-layout-flag :textpalette) (emit-when-no-readonly (dw/remove-layout-flag :textpalette)
(toggle-layout-flag :colorpalette)))} (toggle-layout-flag :colorpalette)))}
:toggle-textpalette {:tooltip (ds/alt "T") :toggle-textpalette {:tooltip (ds/alt "T")
:command (ds/a-mod "t") :command (ds/a-mod "t")
:subsections [:panels] :subsections [:panels]
:fn #(do (r/set-resize-type! :bottom) :fn #(do (r/set-resize-type! :bottom)
(st/emit! (dw/remove-layout-flag :colorpalette) (emit-when-no-readonly (dw/remove-layout-flag :colorpalette)
(toggle-layout-flag :textpalette)))} (toggle-layout-flag :textpalette)))}
:hide-ui {:tooltip "\\" :hide-ui {:tooltip "\\"
@ -482,22 +488,22 @@
:bool-union {:tooltip (ds/meta (ds/alt "U")) :bool-union {:tooltip (ds/meta (ds/alt "U"))
:command (ds/c-mod "alt+u") :command (ds/c-mod "alt+u")
:subsections [:shape] :subsections [:shape]
:fn #(st/emit! (dw/create-bool :union))} :fn #(emit-when-no-readonly (dw/create-bool :union))}
:bool-difference {:tooltip (ds/meta (ds/alt "D")) :bool-difference {:tooltip (ds/meta (ds/alt "D"))
:command (ds/c-mod "alt+d") :command (ds/c-mod "alt+d")
:subsections [:shape] :subsections [:shape]
:fn #(st/emit! (dw/create-bool :difference))} :fn #(emit-when-no-readonly (dw/create-bool :difference))}
:bool-intersection {:tooltip (ds/meta (ds/alt "I")) :bool-intersection {:tooltip (ds/meta (ds/alt "I"))
:command (ds/c-mod "alt+i") :command (ds/c-mod "alt+i")
:subsections [:shape] :subsections [:shape]
:fn #(st/emit! (dw/create-bool :intersection))} :fn #(emit-when-no-readonly (dw/create-bool :intersection))}
:bool-exclude {:tooltip (ds/meta (ds/alt "E")) :bool-exclude {:tooltip (ds/meta (ds/alt "E"))
:command (ds/c-mod "alt+e") :command (ds/c-mod "alt+e")
:subsections [:shape] :subsections [:shape]
:fn #(st/emit! (dw/create-bool :exclude))}} :fn #(emit-when-no-readonly (dw/create-bool :exclude))}}
) )
(def opacity-shortcuts (def opacity-shortcuts
@ -507,7 +513,7 @@
{:tooltip (str n) {:tooltip (str n)
:command (str n) :command (str n)
:subsections [:modify-layers] :subsections [:modify-layers]
:fn #(st/emit! (dwly/pressed-opacity n))}]))))) :fn #(emit-when-no-readonly (dwly/pressed-opacity n))}])))))
(def shortcuts (def shortcuts
(merge base-shortcuts opacity-shortcuts)) (merge base-shortcuts opacity-shortcuts))

View file

@ -146,3 +146,4 @@
(let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])] (let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
(gpt/point (+ x (/ width 2)) (+ y (/ height 2))))) (gpt/point (+ x (/ width 2)) (+ y (/ height 2)))))

View file

@ -261,6 +261,9 @@
(def workspace-page-objects (def workspace-page-objects
(l/derived wsh/lookup-page-objects st/state =)) (l/derived wsh/lookup-page-objects st/state =))
(def workspace-read-only?
(l/derived :read-only? workspace-global))
(defn object-by-id (defn object-by-id
[id] [id]
(l/derived #(get % id) workspace-page-objects)) (l/derived #(get % id) workspace-page-objects))

View file

@ -20,7 +20,9 @@
(mf/defc tab-container (mf/defc tab-container
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [children (unchecked-get props "children") (let [children (->>
(unchecked-get props "children")
(filter some?))
selected (unchecked-get props "selected") selected (unchecked-get props "selected")
on-change (unchecked-get props "on-change-tab") on-change (unchecked-get props "on-change-tab")

View file

@ -8,20 +8,22 @@
(:require (:require
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def render-id (mf/create-context nil)) (def render-id (mf/create-context nil))
(def current-route (mf/create-context nil)) (def current-route (mf/create-context nil))
(def current-profile (mf/create-context nil)) (def current-profile (mf/create-context nil))
(def current-team-id (mf/create-context nil)) (def current-team-id (mf/create-context nil))
(def current-project-id (mf/create-context nil)) (def current-project-id (mf/create-context nil))
(def current-page-id (mf/create-context nil)) (def current-page-id (mf/create-context nil))
(def current-file-id (mf/create-context nil)) (def current-file-id (mf/create-context nil))
(def active-frames (mf/create-context nil)) (def active-frames (mf/create-context nil))
(def render-thumbnails (mf/create-context nil)) (def render-thumbnails (mf/create-context nil))
(def libraries (mf/create-context nil)) (def libraries (mf/create-context nil))
(def components-v2 (mf/create-context nil)) (def components-v2 (mf/create-context nil))
(def current-scroll (mf/create-context nil)) (def current-scroll (mf/create-context nil))
(def current-zoom (mf/create-context nil)) (def current-zoom (mf/create-context nil))
(def workspace-read-only? (mf/create-context nil))

View file

@ -84,7 +84,9 @@
;; things go weird. ;; things go weird.
(defn use-sortable (defn use-sortable
[& {:keys [data-type data on-drop on-drag on-hold disabled detect-center?] :as opts}] [& {:keys [data-type data on-drop on-drag on-hold disabled detect-center? draggable?]
:or {draggable? true}
:as opts}]
(let [ref (mf/use-ref) (let [ref (mf/use-ref)
state (mf/use-state {:over nil state (mf/use-state {:over nil
:timer nil :timer nil
@ -169,7 +171,7 @@
on-mount on-mount
(fn [] (fn []
(let [dom (mf/ref-val ref)] (let [dom (mf/ref-val ref)]
(.setAttribute dom "draggable" true) (.setAttribute dom "draggable" draggable?)
;; Register all events in the (default) bubble mode, so that they ;; Register all events in the (default) bubble mode, so that they
;; are captured by the most leaf item. The handler will stop ;; are captured by the most leaf item. The handler will stop
@ -189,7 +191,7 @@
(.removeEventListener dom "dragend" on-drag-end))))] (.removeEventListener dom "dragend" on-drag-end))))]
(mf/use-effect (mf/use-effect
(mf/deps data on-drop) (mf/deps data on-drop draggable?)
on-mount) on-mount)
[(deref state) ref])) [(deref state) ref]))

View file

@ -117,11 +117,12 @@
(mf/defc workspace (mf/defc workspace
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [project-id file-id page-id layout-name] :as props}] [{:keys [project-id file-id page-id layout-name] :as props}]
(let [file (mf/deref refs/workspace-file) (let [file (mf/deref refs/workspace-file)
project (mf/deref refs/workspace-project) project (mf/deref refs/workspace-project)
layout (mf/deref refs/workspace-layout) layout (mf/deref refs/workspace-layout)
wglobal (mf/deref refs/workspace-global) wglobal (mf/deref refs/workspace-global)
ready? (mf/deref refs/workspace-ready?) ready? (mf/deref refs/workspace-ready?)
workspace-read-only? (mf/deref refs/workspace-read-only?)
components-v2 (features/use-feature :components-v2) components-v2 (features/use-feature :components-v2)
@ -152,22 +153,23 @@
[:& (mf/provider ctx/current-project-id) {:value (:id project)} [:& (mf/provider ctx/current-project-id) {:value (:id project)}
[:& (mf/provider ctx/current-page-id) {:value page-id} [:& (mf/provider ctx/current-page-id) {:value page-id}
[:& (mf/provider ctx/components-v2) {:value components-v2} [:& (mf/provider ctx/components-v2) {:value components-v2}
[:section#workspace {:style {:background-color background-color}} [:& (mf/provider ctx/workspace-read-only?) {:value workspace-read-only?}
(when (not (:hide-ui layout)) [:section#workspace {:style {:background-color background-color}}
[:& header {:file file (when (not (:hide-ui layout))
:page-id page-id [:& header {:file file
:project project :page-id page-id
:layout layout}]) :project project
:layout layout}])
[:& context-menu] [:& context-menu]
(if ready? (if ready?
[:& workspace-page {:key (dm/str "page-" page-id) [:& workspace-page {:key (dm/str "page-" page-id)
:page-id page-id :page-id page-id
:file file :file file
:wglobal wglobal :wglobal wglobal
:layout layout}] :layout layout}]
[:& workspace-loader])]]]]]])) [:& workspace-loader])]]]]]]]))
(mf/defc remove-graphics-dialog (mf/defc remove-graphics-dialog
{::mf/register modal/components {::mf/register modal/components

View file

@ -21,6 +21,7 @@
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.context :as ctx]
[app.main.ui.export :refer [export-progress-widget]] [app.main.ui.export :refer [export-progress-widget]]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
@ -107,13 +108,14 @@
(mf/defc menu (mf/defc menu
[{:keys [layout project file team-id] :as props}] [{:keys [layout project file team-id] :as props}]
(let [show-menu? (mf/use-state false) (let [show-menu? (mf/use-state false)
show-sub-menu? (mf/use-state false) show-sub-menu? (mf/use-state false)
editing? (mf/use-state false) editing? (mf/use-state false)
edit-input-ref (mf/use-ref nil) edit-input-ref (mf/use-ref nil)
objects (mf/deref refs/workspace-page-objects) objects (mf/deref refs/workspace-page-objects)
frames (->> (cph/get-immediate-children objects uuid/zero) frames (->> (cph/get-immediate-children objects uuid/zero)
(filterv cph/frame-shape?)) (filterv cph/frame-shape?))
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
add-shared-fn add-shared-fn
#(st/emit! (dwl/set-file-shared (:id file) true)) #(st/emit! (dwl/set-file-shared (:id file) true))
@ -328,25 +330,27 @@
(tr "workspace.header.menu.show-grid"))] (tr "workspace.header.menu.show-grid"))]
[:span.shortcut (sc/get-tooltip :toggle-grid)]] [:span.shortcut (sc/get-tooltip :toggle-grid)]]
[:li {:on-click (fn [] (when-not workspace-read-only?
(r/set-resize-type! :bottom) [:*
(st/emit! (dw/remove-layout-flag :textpalette) [:li {:on-click (fn []
(toggle-flag :colorpalette)))} (r/set-resize-type! :bottom)
[:span (st/emit! (dw/remove-layout-flag :textpalette)
(if (contains? layout :colorpalette) (toggle-flag :colorpalette)))}
(tr "workspace.header.menu.hide-palette") [:span
(tr "workspace.header.menu.show-palette"))] (if (contains? layout :colorpalette)
[:span.shortcut (sc/get-tooltip :toggle-colorpalette)]] (tr "workspace.header.menu.hide-palette")
(tr "workspace.header.menu.show-palette"))]
[:span.shortcut (sc/get-tooltip :toggle-colorpalette)]]
[:li {:on-click (fn [] [:li {:on-click (fn []
(r/set-resize-type! :bottom) (r/set-resize-type! :bottom)
(st/emit! (dw/remove-layout-flag :colorpalette) (st/emit! (dw/remove-layout-flag :colorpalette)
(toggle-flag :textpalette)))} (toggle-flag :textpalette)))}
[:span [:span
(if (contains? layout :textpalette) (if (contains? layout :textpalette)
(tr "workspace.header.menu.hide-textpalette") (tr "workspace.header.menu.hide-textpalette")
(tr "workspace.header.menu.show-textpalette"))] (tr "workspace.header.menu.show-textpalette"))]
[:span.shortcut (sc/get-tooltip :toggle-textpalette)]] [:span.shortcut (sc/get-tooltip :toggle-textpalette)]]])
[:li {:on-click #(st/emit! (toggle-flag :display-artboard-names))} [:li {:on-click #(st/emit! (toggle-flag :display-artboard-names))}
[:span [:span
@ -436,6 +440,7 @@
(let [team-id (:team-id project) (let [team-id (:team-id project)
zoom (mf/deref refs/selected-zoom) zoom (mf/deref refs/selected-zoom)
params {:page-id page-id :file-id (:id file) :section "interactions"} params {:page-id page-id :file-id (:id file) :section "interactions"}
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
close-modals close-modals
(mf/use-callback (mf/use-callback
@ -474,13 +479,14 @@
[:div.options-section [:div.options-section
[:& persistence-state-widget] [:& persistence-state-widget]
[:& export-progress-widget] [:& export-progress-widget]
[:button.document-history (when-not workspace-read-only?
{:alt (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history)) [:button.document-history
:aria-label (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history)) {:alt (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history))
:class (when (contains? layout :document-history) "selected") :aria-label (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history))
:on-click #(st/emit! (-> (dw/toggle-layout-flag :document-history) :class (when (contains? layout :document-history) "selected")
(vary-meta assoc ::ev/origin "workspace-header")))} :on-click #(st/emit! (-> (dw/toggle-layout-flag :document-history)
i/recent]] (vary-meta assoc ::ev/origin "workspace-header")))}
i/recent])]
[:div.options-section [:div.options-section
[:& zoom-widget-workspace [:& zoom-widget-workspace

View file

@ -15,6 +15,7 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -64,10 +65,11 @@
{::mf/wrap [mf/memo] {::mf/wrap [mf/memo]
::mf/wrap-props false} ::mf/wrap-props false}
[props] [props]
(let [layout (obj/get props "layout") (let [layout (obj/get props "layout")
selected-drawtool (mf/deref refs/selected-drawing-tool) selected-drawtool (mf/deref refs/selected-drawing-tool)
select-drawtool #(st/emit! :interrupt (dw/select-for-drawing %)) select-drawtool #(st/emit! :interrupt (dw/select-for-drawing %))
edition (mf/deref refs/selected-edition)] edition (mf/deref refs/selected-edition)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)]
[:aside.left-toolbar [:aside.left-toolbar
[:ul.left-toolbar-options [:ul.left-toolbar-options
[:li [:li
@ -78,56 +80,58 @@
(not edition)) "selected") (not edition)) "selected")
:on-click #(st/emit! :interrupt)} :on-click #(st/emit! :interrupt)}
i/pointer-inner]] i/pointer-inner]]
[:li (when-not workspace-read-only?
[:button.tooltip.tooltip-right [:*
{:alt (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame)) [:li
:aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame)) [:button.tooltip.tooltip-right
:class (when (= selected-drawtool :frame) "selected") {:alt (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
:on-click (partial select-drawtool :frame) :aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
:data-test "artboard-btn"} :class (when (= selected-drawtool :frame) "selected")
i/artboard]] :on-click (partial select-drawtool :frame)
[:li :data-test "artboard-btn"}
[:button.tooltip.tooltip-right i/artboard]]
{:alt (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) [:li
:aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) [:button.tooltip.tooltip-right
:class (when (= selected-drawtool :rect) "selected") {:alt (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
:on-click (partial select-drawtool :rect) :aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
:data-test "rect-btn"} :class (when (= selected-drawtool :rect) "selected")
i/box]] :on-click (partial select-drawtool :rect)
[:li :data-test "rect-btn"}
[:button.tooltip.tooltip-right i/box]]
{:alt (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) [:li
:aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) [:button.tooltip.tooltip-right
:class (when (= selected-drawtool :circle) "selected") {:alt (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
:on-click (partial select-drawtool :circle) :aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
:data-test "ellipse-btn"} :class (when (= selected-drawtool :circle) "selected")
i/circle]] :on-click (partial select-drawtool :circle)
[:li :data-test "ellipse-btn"}
[:button.tooltip.tooltip-right i/circle]]
{:alt (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) [:li
:aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) [:button.tooltip.tooltip-right
:class (when (= selected-drawtool :text) "selected") {:alt (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
:on-click (partial select-drawtool :text)} :aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
i/text]] :class (when (= selected-drawtool :text) "selected")
:on-click (partial select-drawtool :text)}
i/text]]
[:& image-upload] [:& image-upload]
[:li [:li
[:button.tooltip.tooltip-right [:button.tooltip.tooltip-right
{:alt (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) {:alt (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
:aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) :aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
:class (when (= selected-drawtool :curve) "selected") :class (when (= selected-drawtool :curve) "selected")
:on-click (partial select-drawtool :curve) :on-click (partial select-drawtool :curve)
:data-test "curve-btn"} :data-test "curve-btn"}
i/pencil]] i/pencil]]
[:li [:li
[:button.tooltip.tooltip-right [:button.tooltip.tooltip-right
{:alt (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) {:alt (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
:aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) :aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
:class (when (= selected-drawtool :path) "selected") :class (when (= selected-drawtool :path) "selected")
:on-click (partial select-drawtool :path) :on-click (partial select-drawtool :path)
:data-test "path-btn"} :data-test "path-btn"}
i/pen]] i/pen]]])
[:li [:li
[:button.tooltip.tooltip-right [:button.tooltip.tooltip-right
@ -138,31 +142,33 @@
i/chat]]] i/chat]]]
[:ul.left-toolbar-options.panels [:ul.left-toolbar-options.panels
[:li (when-not workspace-read-only?
[:button.tooltip.tooltip-right [:*
{:alt (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) [:li
:aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) [:button.tooltip.tooltip-right
:class (when (contains? layout :textpalette) "selected") {:alt (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:on-click (fn [] :aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
(r/set-resize-type! :bottom) :class (when (contains? layout :textpalette) "selected")
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") :on-click (fn []
(ts/schedule 300 #(st/emit! (dw/remove-layout-flag :colorpalette) (r/set-resize-type! :bottom)
(-> (dw/toggle-layout-flag :textpalette) (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
(vary-meta assoc ::ev/origin "workspace-left-toolbar")))))} (ts/schedule 300 #(st/emit! (dw/remove-layout-flag :colorpalette)
"Ag"]] (-> (dw/toggle-layout-flag :textpalette)
(vary-meta assoc ::ev/origin "workspace-left-toolbar")))))}
"Ag"]]
[:li [:li
[:button.tooltip.tooltip-right [:button.tooltip.tooltip-right
{:alt (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) {:alt (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) :aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:class (when (contains? layout :colorpalette) "selected") :class (when (contains? layout :colorpalette) "selected")
:on-click (fn [] :on-click (fn []
(r/set-resize-type! :bottom) (r/set-resize-type! :bottom)
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
(ts/schedule 300 #(st/emit! (dw/remove-layout-flag :textpalette) (ts/schedule 300 #(st/emit! (dw/remove-layout-flag :textpalette)
(-> (dw/toggle-layout-flag :colorpalette) (-> (dw/toggle-layout-flag :colorpalette)
(vary-meta assoc ::ev/origin "workspace-left-toolbar")))))} (vary-meta assoc ::ev/origin "workspace-left-toolbar")))))}
i/palette]] i/palette]]])
[:li [:li
[:button.tooltip.tooltip-right.separator [:button.tooltip.tooltip-right.separator
{:alt (tr "workspace.toolbar.shortcuts" (sc/get-tooltip :show-shortcuts)) {:alt (tr "workspace.toolbar.shortcuts" (sc/get-tooltip :show-shortcuts))

View file

@ -364,11 +364,11 @@
(mf/defc components-item (mf/defc components-item
[{:keys [component renaming listing-thumbs? selected-components [{:keys [component renaming listing-thumbs? selected-components
on-asset-click on-context-menu on-drag-start do-rename on-asset-click on-context-menu on-drag-start do-rename cancel-rename
cancel-rename selected-components-full selected-components-paths]}] selected-components-full selected-components-paths]}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
dragging? (mf/use-state false)
dragging? (mf/use-state false) workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
unselect-all unselect-all
(mf/use-fn (mf/use-fn
@ -422,7 +422,7 @@
:grid-cell @listing-thumbs? :grid-cell @listing-thumbs?
:enum-item (not @listing-thumbs?)) :enum-item (not @listing-thumbs?))
:id (str "component-shape-id-" (:id component)) :id (str "component-shape-id-" (:id component))
:draggable true :draggable (not workspace-read-only?)
:on-click on-component-click :on-click on-component-click
:on-context-menu (on-context-menu (:id component)) :on-context-menu (on-context-menu (:id component))
:on-drag-start on-component-drag-start :on-drag-start on-component-drag-start
@ -552,11 +552,12 @@
(mf/defc components-box (mf/defc components-box
[{:keys [file-id local? components listing-thumbs? open? reverse-sort? open-groups selected-assets [{:keys [file-id local? components listing-thumbs? open? reverse-sort? open-groups selected-assets
on-asset-click on-assets-delete on-clear-selection] :as props}] on-asset-click on-assets-delete on-clear-selection] :as props}]
(let [input-ref (mf/use-ref nil) (let [input-ref (mf/use-ref nil)
state (mf/use-state {:renaming nil state (mf/use-state {:renaming nil
:component-id nil}) :component-id nil})
menu-state (mf/use-state auto-pos-menu-state) menu-state (mf/use-state auto-pos-menu-state)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
selected-components (:components selected-assets) selected-components (:components selected-assets)
selected-components-full (filter #(contains? selected-components (:id %)) components) selected-components-full (filter #(contains? selected-components (:id %)) components)
@ -627,10 +628,10 @@
on-context-menu on-context-menu
(mf/use-fn (mf/use-fn
(mf/deps selected-components on-clear-selection) (mf/deps selected-components on-clear-selection workspace-read-only?)
(fn [component-id] (fn [component-id]
(fn [event] (fn [event]
(when local? (when (and local? (not workspace-read-only?))
(when-not (contains? selected-components component-id) (when-not (contains? selected-components component-id)
(on-clear-selection)) (on-clear-selection))
(swap! state assoc :component-id component-id) (swap! state assoc :component-id component-id)
@ -715,7 +716,7 @@
:open? open?} :open? open?}
(when local? (when local?
[:& asset-section-block {:role :title-button} [:& asset-section-block {:role :title-button}
(when components-v2 (when (and components-v2 (not workspace-read-only?))
[:div.assets-button {:on-click add-component} [:div.assets-button {:on-click add-component}
i/plus i/plus
[:& file-uploader {:accept cm/str-image-types [:& file-uploader {:accept cm/str-image-types
@ -759,9 +760,10 @@
[{:keys [object renaming listing-thumbs? selected-objects [{:keys [object renaming listing-thumbs? selected-objects
on-asset-click on-context-menu on-drag-start do-rename cancel-rename on-asset-click on-context-menu on-drag-start do-rename cancel-rename
selected-graphics-full selected-graphics-paths]}] selected-graphics-full selected-graphics-paths]}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
visible? (h/use-visible item-ref :once? true) visible? (h/use-visible item-ref :once? true)
dragging? (mf/use-state false) dragging? (mf/use-state false)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-drop on-drop
(mf/use-fn (mf/use-fn
@ -795,7 +797,7 @@
:selected (contains? selected-objects (:id object)) :selected (contains? selected-objects (:id object))
:grid-cell @listing-thumbs? :grid-cell @listing-thumbs?
:enum-item (not @listing-thumbs?)) :enum-item (not @listing-thumbs?))
:draggable true :draggable (not workspace-read-only?)
:on-click #(on-asset-click % (:id object) nil) :on-click #(on-asset-click % (:id object) nil)
:on-context-menu (on-context-menu (:id object)) :on-context-menu (on-context-menu (:id object))
:on-drag-start on-grahic-drag-start :on-drag-start on-grahic-drag-start
@ -928,18 +930,19 @@
(mf/defc graphics-box (mf/defc graphics-box
[{:keys [file-id project-id local? objects listing-thumbs? open? open-groups selected-assets reverse-sort? [{:keys [file-id project-id local? objects listing-thumbs? open? open-groups selected-assets reverse-sort?
on-asset-click on-assets-delete on-clear-selection] :as props}] on-asset-click on-assets-delete on-clear-selection] :as props}]
(let [input-ref (mf/use-ref nil) (let [input-ref (mf/use-ref nil)
state (mf/use-state {:renaming nil state (mf/use-state {:renaming nil
:object-id nil}) :object-id nil})
menu-state (mf/use-state auto-pos-menu-state) menu-state (mf/use-state auto-pos-menu-state)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
selected-objects (:graphics selected-assets) selected-objects (:graphics selected-assets)
selected-graphics-full (filter #(contains? selected-objects (:id %)) objects) selected-graphics-full (filter #(contains? selected-objects (:id %)) objects)
multi-objects? (> (count selected-objects) 1) multi-objects? (> (count selected-objects) 1)
multi-assets? (or (seq (:components selected-assets)) multi-assets? (or (seq (:components selected-assets))
(seq (:colors selected-assets)) (seq (:colors selected-assets))
(seq (:typographies selected-assets))) (seq (:typographies selected-assets)))
objects (->> objects objects (->> objects
(map dwl/extract-path-if-missing)) (map dwl/extract-path-if-missing))
@ -996,10 +999,10 @@
on-context-menu on-context-menu
(mf/use-fn (mf/use-fn
(mf/deps selected-objects on-clear-selection) (mf/deps selected-objects on-clear-selection workspace-read-only?)
(fn [object-id] (fn [object-id]
(fn [event] (fn [event]
(when local? (when (and local? (not workspace-read-only?))
(when-not (contains? selected-objects object-id) (when-not (contains? selected-objects object-id)
(on-clear-selection)) (on-clear-selection))
(swap! state assoc :object-id object-id) (swap! state assoc :object-id object-id)
@ -1084,7 +1087,7 @@
:open? open?} :open? open?}
(when local? (when local?
[:& asset-section-block {:role :title-button} [:& asset-section-block {:role :title-button}
(when-not components-v2 (when (and (not components-v2) (not workspace-read-only?))
[:div.assets-button {:on-click add-graphic} [:div.assets-button {:on-click add-graphic}
i/plus i/plus
[:& file-uploader {:accept cm/str-image-types [:& file-uploader {:accept cm/str-image-types
@ -1125,13 +1128,14 @@
[{:keys [color local? file-id selected-colors multi-colors? multi-assets? [{:keys [color local? file-id selected-colors multi-colors? multi-assets?
on-asset-click on-assets-delete on-clear-selection on-group on-asset-click on-assets-delete on-clear-selection on-group
selected-colors-full selected-colors-paths move-color] :as props}] selected-colors-full selected-colors-paths move-color] :as props}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
dragging? (mf/use-state false) dragging? (mf/use-state false)
rename? (= (:color-for-rename @refs/workspace-local) (:id color)) rename? (= (:color-for-rename @refs/workspace-local) (:id color))
input-ref (mf/use-ref) input-ref (mf/use-ref)
state (mf/use-state {:editing rename?}) state (mf/use-state {:editing rename?})
menu-state (mf/use-state auto-pos-menu-state) menu-state (mf/use-state auto-pos-menu-state)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
default-name (cond default-name (cond
(:gradient color) (bc/gradient-type->string (get-in color [:gradient :type])) (:gradient color) (bc/gradient-type->string (get-in color [:gradient :type]))
@ -1182,7 +1186,7 @@
rename-color-clicked rename-color-clicked
(fn [event] (fn [event]
(when local? (when (and local? (not workspace-read-only?))
(dom/prevent-default event) (dom/prevent-default event)
(swap! state assoc :editing true))) (swap! state assoc :editing true)))
@ -1213,9 +1217,9 @@
on-context-menu on-context-menu
(mf/use-fn (mf/use-fn
(mf/deps color selected-colors on-clear-selection) (mf/deps color selected-colors on-clear-selection workspace-read-only?)
(fn [event] (fn [event]
(when local? (when (and local? (not workspace-read-only?))
(when-not (contains? selected-colors (:id color)) (when-not (contains? selected-colors (:id color))
(on-clear-selection)) (on-clear-selection))
(swap! menu-state #(open-auto-pos-menu % event))))) (swap! menu-state #(open-auto-pos-menu % event)))))
@ -1265,7 +1269,7 @@
#(on-asset-click % (:id color) #(on-asset-click % (:id color)
(partial apply-color (:id color)))) (partial apply-color (:id color))))
:ref item-ref :ref item-ref
:draggable true :draggable (not workspace-read-only?)
:on-drag-start on-color-drag-start :on-drag-start on-color-drag-start
:on-drag-enter on-drag-enter :on-drag-enter on-drag-enter
:on-drag-leave on-drag-leave :on-drag-leave on-drag-leave
@ -1400,14 +1404,15 @@
(mf/defc colors-box (mf/defc colors-box
[{:keys [file-id local? colors open? open-groups selected-assets reverse-sort? [{:keys [file-id local? colors open? open-groups selected-assets reverse-sort?
on-asset-click on-assets-delete on-clear-selection] :as props}] on-asset-click on-assets-delete on-clear-selection] :as props}]
(let [selected-colors (:colors selected-assets) (let [selected-colors (:colors selected-assets)
selected-colors-full (filter #(contains? selected-colors (:id %)) colors) selected-colors-full (filter #(contains? selected-colors (:id %)) colors)
multi-colors? (> (count selected-colors) 1) multi-colors? (> (count selected-colors) 1)
multi-assets? (or (seq (:components selected-assets)) multi-assets? (or (seq (:components selected-assets))
(seq (:graphics selected-assets)) (seq (:graphics selected-assets))
(seq (:typographies selected-assets))) (seq (:typographies selected-assets)))
groups (group-assets colors reverse-sort?) groups (group-assets colors reverse-sort?)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
add-color add-color
(mf/use-fn (mf/use-fn
@ -1501,8 +1506,9 @@
:open? open?} :open? open?}
(when local? (when local?
[:& asset-section-block {:role :title-button} [:& asset-section-block {:role :title-button}
[:div.assets-button {:on-click add-color-clicked} (when-not workspace-read-only?
i/plus]]) [:div.assets-button {:on-click add-color-clicked}
i/plus])])
[:& asset-section-block {:role :content} [:& asset-section-block {:role :content}
[:& colors-group {:file-id file-id [:& colors-group {:file-id file-id
@ -1526,10 +1532,11 @@
(mf/defc typography-item (mf/defc typography-item
[{:keys [typography file local? handle-change selected-typographies apply-typography [{:keys [typography file local? handle-change selected-typographies apply-typography
editing-id local-data on-asset-click on-context-menu editing-id local-data on-asset-click on-context-menu selected-typographies-full
selected-typographies-full selected-typographies-paths move-typography] :as props}] selected-typographies-paths move-typography] :as props}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
dragging? (mf/use-state false) dragging? (mf/use-state false)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-drop on-drop
(mf/use-fn (mf/use-fn
(mf/deps typography dragging? selected-typographies selected-typographies-full selected-typographies-paths move-typography) (mf/deps typography dragging? selected-typographies selected-typographies-full selected-typographies-paths move-typography)
@ -1558,7 +1565,7 @@
(on-asset-drag-start event typography selected-typographies item-ref :typographies identity)))] (on-asset-drag-start event typography selected-typographies item-ref :typographies identity)))]
[:div.typography-container {:ref item-ref [:div.typography-container {:ref item-ref
:draggable true :draggable (not workspace-read-only?)
:on-drag-start on-typography-drag-start :on-drag-start on-typography-drag-start
:on-drag-enter on-drag-enter :on-drag-enter on-drag-enter
:on-drag-leave on-drag-leave :on-drag-leave on-drag-leave
@ -1568,7 +1575,7 @@
{:key (:id typography) {:key (:id typography)
:typography typography :typography typography
:file file :file file
:read-only? (not local?) :local? local?
:on-context-menu #(on-context-menu (:id typography) %) :on-context-menu #(on-context-menu (:id typography) %)
:on-change #(handle-change typography %) :on-change #(handle-change typography %)
:selected? (contains? selected-typographies (:id typography)) :selected? (contains? selected-typographies (:id typography))
@ -1581,8 +1588,8 @@
(mf/defc typographies-group (mf/defc typographies-group
[{:keys [file-id prefix groups open-groups file local? selected-typographies local-data [{:keys [file-id prefix groups open-groups file local? selected-typographies local-data
editing-id on-asset-click handle-change apply-typography editing-id on-asset-click handle-change apply-typography on-rename-group
on-rename-group on-ungroup on-context-menu selected-typographies-full]}] on-ungroup on-context-menu selected-typographies-full]}]
(let [group-open? (get open-groups prefix true) (let [group-open? (get open-groups prefix true)
dragging? (mf/use-state false) dragging? (mf/use-state false)
@ -1690,6 +1697,7 @@
multi-assets? (or (seq (:components selected-assets)) multi-assets? (or (seq (:components selected-assets))
(seq (:graphics selected-assets)) (seq (:graphics selected-assets))
(seq (:colors selected-assets))) (seq (:colors selected-assets)))
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
add-typography add-typography
(mf/use-fn (mf/use-fn
@ -1783,9 +1791,9 @@
on-context-menu on-context-menu
(mf/use-fn (mf/use-fn
(mf/deps selected-typographies on-clear-selection) (mf/deps selected-typographies on-clear-selection workspace-read-only?)
(fn [id event] (fn [id event]
(when local? (when (and local? (not workspace-read-only?))
(when-not (contains? selected-typographies id) (when-not (contains? selected-typographies id)
(on-clear-selection)) (on-clear-selection))
(swap! state assoc :id id) (swap! state assoc :id id)
@ -1833,8 +1841,9 @@
:open? open?} :open? open?}
(when local? (when local?
[:& asset-section-block {:role :title-button} [:& asset-section-block {:role :title-button}
[:div.assets-button {:on-click add-typography} (when-not workspace-read-only?
i/plus]]) [:div.assets-button {:on-click add-typography}
i/plus])])
[:& asset-section-block {:role :content} [:& asset-section-block {:role :content}
[:& typographies-group {:file-id file-id [:& typographies-group {:file-id file-id
@ -1929,52 +1938,52 @@
(mf/defc file-library (mf/defc file-library
[{:keys [file local? default-open? filters] :as props}] [{:keys [file local? default-open? filters] :as props}]
(let [open-file (mf/deref (make-open-file-ref (:id file))) (let [open-file (mf/deref (make-open-file-ref (:id file)))
open? (-> open-file open? (-> open-file
:library :library
(d/nilv default-open?)) (d/nilv default-open?))
open-box? (fn [box] open-box? (fn [box]
(-> open-file (-> open-file
box box
(d/nilv true))) (d/nilv true)))
open-groups (fn [box] open-groups (fn [box]
(-> open-file (-> open-file
:groups :groups
box box
(d/nilv {}))) (d/nilv {})))
shared? (:is-shared file) shared? (:is-shared file)
router (mf/deref refs/router) router (mf/deref refs/router)
reverse-sort? (mf/use-state false) reverse-sort? (mf/use-state false)
listing-thumbs? (mf/use-state true) listing-thumbs? (mf/use-state true)
selected-assets (mf/deref refs/selected-assets) selected-assets (mf/deref refs/selected-assets)
selected-count (+ (count (:components selected-assets)) selected-count (+ (count (:components selected-assets))
(count (:graphics selected-assets)) (count (:graphics selected-assets))
(count (:colors selected-assets)) (count (:colors selected-assets))
(count (:typographies selected-assets))) (count (:typographies selected-assets)))
components-v2 (mf/use-ctx ctx/components-v2) components-v2 (mf/use-ctx ctx/components-v2)
toggle-open #(st/emit! (dwl/set-assets-box-open (:id file) :library (not open?))) toggle-open #(st/emit! (dwl/set-assets-box-open (:id file) :library (not open?)))
url (rt/resolve router :workspace url (rt/resolve router :workspace
{:project-id (:project-id file) {:project-id (:project-id file)
:file-id (:id file)} :file-id (:id file)}
{:page-id (get-in file [:data :pages 0])}) {:page-id (get-in file [:data :pages 0])})
colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file))) colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file)))
colors (apply-filters (mf/deref colors-ref) filters @reverse-sort?) colors (apply-filters (mf/deref colors-ref) filters @reverse-sort?)
typography-ref (mf/use-memo (mf/deps (:id file)) #(file-typography-ref (:id file))) typography-ref (mf/use-memo (mf/deps (:id file)) #(file-typography-ref (:id file)))
typographies (apply-filters (mf/deref typography-ref) filters @reverse-sort?) typographies (apply-filters (mf/deref typography-ref) filters @reverse-sort?)
media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file))) media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file)))
media (apply-filters (mf/deref media-ref) filters @reverse-sort?) media (apply-filters (mf/deref media-ref) filters @reverse-sort?)
components-ref (mf/use-memo (mf/deps (:id file)) #(file-components-ref (:id file))) components-ref (mf/use-memo (mf/deps (:id file)) #(file-components-ref (:id file)))
components (apply-filters (mf/deref components-ref) filters @reverse-sort?) components (apply-filters (mf/deref components-ref) filters @reverse-sort?)
toggle-sort toggle-sort
(mf/use-fn (mf/use-fn
@ -2171,12 +2180,13 @@
(mf/defc assets-toolbox (mf/defc assets-toolbox
[] []
(let [libraries (->> (mf/deref refs/workspace-libraries) (let [libraries (->> (mf/deref refs/workspace-libraries)
(vals) (vals)
(remove :is-indirect)) (remove :is-indirect))
file (mf/deref refs/workspace-file) file (mf/deref refs/workspace-file)
team-id (mf/use-ctx ctx/current-team-id) team-id (mf/use-ctx ctx/current-team-id)
filters (mf/use-state {:term "" :box :all}) filters (mf/use-state {:term "" :box :all})
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-search-term-change on-search-term-change
(mf/use-fn (mf/use-fn
@ -2205,9 +2215,10 @@
[:div.tool-window-content [:div.tool-window-content
[:div.assets-bar-title [:div.assets-bar-title
(tr "workspace.assets.assets") (tr "workspace.assets.assets")
[:div.libraries-button {:on-click #(modal/show! :libraries-dialog {})} (when-not workspace-read-only?
i/text-align-justify [:div.libraries-button {:on-click #(modal/show! :libraries-dialog {})}
(tr "workspace.assets.libraries")]] i/text-align-justify
(tr "workspace.assets.libraries")])]
[:div.search-block [:div.search-block
[:input.search-input [:input.search-input

View file

@ -87,25 +87,26 @@
(mf/defc layer-item (mf/defc layer-item
[{:keys [index item selected objects sortable? filtered?] :as props}] [{:keys [index item selected objects sortable? filtered?] :as props}]
(let [id (:id item) (let [id (:id item)
blocked? (:blocked item) blocked? (:blocked item)
hidden? (:hidden item) hidden? (:hidden item)
disable-drag (mf/use-state false) disable-drag (mf/use-state false)
scroll-to-middle? (mf/use-var true) scroll-to-middle? (mf/use-var true)
expanded-iref (mf/with-memo [id] expanded-iref (mf/with-memo [id]
(-> (l/in [:expanded id]) (-> (l/in [:expanded id])
(l/derived refs/workspace-local))) (l/derived refs/workspace-local)))
expanded? (mf/deref expanded-iref) expanded? (mf/deref expanded-iref)
selected? (contains? selected id) selected? (contains? selected id)
container? (or (cph/frame-shape? item) container? (or (cph/frame-shape? item)
(cph/group-shape? item)) (cph/group-shape? item))
components-v2 (mf/use-ctx ctx/components-v2) components-v2 (mf/use-ctx ctx/components-v2)
main-instance? (if components-v2 workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
(:main-instance? item) main-instance? (if components-v2
true) (:main-instance? item)
true)
toggle-collapse toggle-collapse
(mf/use-fn (mf/use-fn
@ -170,12 +171,13 @@
on-context-menu on-context-menu
(mf/use-fn (mf/use-fn
(mf/deps item) (mf/deps item workspace-read-only?)
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(let [pos (dom/get-client-position event)] (when-not workspace-read-only?
(st/emit! (dw/show-shape-context-menu {:position pos :shape item}))))) (let [pos (dom/get-client-position event)]
(st/emit! (dw/show-shape-context-menu {:position pos :shape item}))))))
on-drag on-drag
(mf/use-fn (mf/use-fn
@ -192,7 +194,7 @@
(st/emit! (dw/relocate-selected-shapes id 0)) (st/emit! (dw/relocate-selected-shapes id 0))
(let [to-index (if (= side :top) (inc index) index) (let [to-index (if (= side :top) (inc index) index)
parent-id (cph/get-parent-id objects id)] parent-id (cph/get-parent-id objects id)]
(st/emit! (dw/relocate-selected-shapes parent-id to-index)))))) (st/emit! (dw/relocate-selected-shapes parent-id to-index))))))
on-hold on-hold
(mf/use-fn (mf/use-fn
@ -201,17 +203,18 @@
(when-not expanded? (when-not expanded?
(st/emit! (dwc/toggle-collapse id))))) (st/emit! (dwc/toggle-collapse id)))))
[dprops dref] (when sortable? [dprops dref]
(hooks/use-sortable (hooks/use-sortable
:data-type "penpot/layer" :data-type "penpot/layer"
:on-drop on-drop :on-drop on-drop
:on-drag on-drag :on-drag on-drag
:on-hold on-hold :on-hold on-hold
:disabled @disable-drag :disabled @disable-drag
:detect-center? container? :detect-center? container?
:data {:id (:id item) :data {:id (:id item)
:index index :index index
:name (:name item)})) :name (:name item)}
:draggable? (and sortable? (not workspace-read-only?)))
ref (mf/use-ref)] ref (mf/use-ref)]
@ -257,6 +260,7 @@
:main-instance? main-instance?}]] :main-instance? main-instance?}]]
[:& layer-name {:shape item [:& layer-name {:shape item
:name-ref ref :name-ref ref
:disabled-double-click workspace-read-only?
:on-start-edit #(reset! disable-drag true) :on-start-edit #(reset! disable-drag true)
:on-stop-edit #(reset! disable-drag false)}] :on-stop-edit #(reset! disable-drag false)}]

View file

@ -68,7 +68,11 @@
selected-shapes (into [] (keep (d/getf objects)) selected)] selected-shapes (into [] (keep (d/getf objects)) selected)]
[:div.tool-window [:div.tool-window
[:div.tool-window-content [:div.tool-window-content
[:& tab-container {:on-change-tab #(st/emit! (udw/set-options-mode %)) [:& tab-container {:on-change-tab (fn [options-mode]
(st/emit! (udw/set-options-mode options-mode))
(if (= options-mode :prototype) ;;TODO remove, only for test palba
(st/emit! :interrupt (udw/deselect-all true) (udw/set-workspace-read-only true))
(st/emit! :interrupt (udw/set-workspace-read-only false))))
:selected section} :selected section}
[:& tab-element {:id :design [:& tab-element {:id :design
:title (tr "workspace.options.design")} :title (tr "workspace.options.design")}

View file

@ -320,7 +320,7 @@
(cond (cond
typography typography
[:& typography-entry {:typography typography [:& typography-entry {:typography typography
:read-only? (not= (:typography-ref-file values) file-id) :local? (= (:typography-ref-file values) file-id)
:file (get shared-libs (:typography-ref-file values)) :file (get shared-libs (:typography-ref-file values))
:on-detach handle-detach-typography :on-detach handle-detach-typography
:on-change handle-change-typography}] :on-change handle-change-typography}]

View file

@ -18,6 +18,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.editable-select :refer [editable-select]] [app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.components.numeric-input :refer [numeric-input]] [app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] [app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -455,11 +456,13 @@
;; In summary, this need to a good UX/UI/IMPL rework. ;; In summary, this need to a good UX/UI/IMPL rework.
(mf/defc typography-entry (mf/defc typography-entry
[{:keys [typography read-only? selected? on-click on-change on-detach on-context-menu editing? focus-name? file]}] [{:keys [typography local? selected? on-click on-change on-detach on-context-menu editing? focus-name? file]}]
(let [open? (mf/use-state editing?) (let [open? (mf/use-state editing?)
hover-detach (mf/use-state false) hover-detach (mf/use-state false)
name-input-ref (mf/use-ref) name-input-ref (mf/use-ref)
on-change-ref (mf/use-ref nil) on-change-ref (mf/use-ref nil)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
editable? (and local? (not workspace-read-only?))
on-name-blur on-name-blur
(mf/use-callback (mf/use-callback
@ -511,7 +514,7 @@
[:& advanced-options {:visible? @open? [:& advanced-options {:visible? @open?
:on-close #(reset! open? false)} :on-close #(reset! open? false)}
(if read-only? (if (not editable?)
[:div.element-set-content.typography-read-only-data [:div.element-set-content.typography-read-only-data
[:div.row-flex.typography-name [:div.row-flex.typography-name
[:span (:name typography)]] [:span (:name typography)]]
@ -544,13 +547,14 @@
[:span.label (tr "workspace.assets.typography.text-transform")] [:span.label (tr "workspace.assets.typography.text-transform")]
[:span (:text-transform typography)]] [:span (:text-transform typography)]]
[:div.row-flex (when-not local?
[:a.go-to-lib-button [:div.row-flex
{:on-click #(st/emit! (rt/nav-new-window* {:rname :workspace [:a.go-to-lib-button
:path-params {:project-id (:project-id file) {:on-click #(st/emit! (rt/nav-new-window* {:rname :workspace
:file-id (:id file)} :path-params {:project-id (:project-id file)
:query-params {:page-id (get-in file [:data :pages 0])}}))} :file-id (:id file)}
(tr "workspace.assets.typography.go-to-edit")]]] :query-params {:page-id (get-in file [:data :pages 0])}}))}
(tr "workspace.assets.typography.go-to-edit")]])]
[:* [:*
[:div.element-set-content [:div.element-set-content

View file

@ -27,42 +27,46 @@
(mf/defc page-item (mf/defc page-item
[{:keys [page index deletable? selected?] :as props}] [{:keys [page index deletable? selected?] :as props}]
(let [local (mf/use-state {}) (let [local (mf/use-state {})
input-ref (mf/use-ref) input-ref (mf/use-ref)
id (:id page) id (:id page)
state (mf/use-state {:menu-open false}) state (mf/use-state {:menu-open false})
delete-fn (mf/use-callback (mf/deps id) #(st/emit! (dw/delete-page id))) delete-fn (mf/use-callback (mf/deps id) #(st/emit! (dw/delete-page id)))
navigate-fn (mf/use-callback (mf/deps id) #(st/emit! :interrupt (dw/go-to-page id))) navigate-fn (mf/use-callback (mf/deps id) #(st/emit! :interrupt (dw/go-to-page id)))
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-context-menu on-context-menu
(mf/use-callback (mf/use-callback
(mf/deps id) (mf/deps id workspace-read-only?)
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(let [pos (dom/get-client-position event)] (when-not workspace-read-only?
(swap! state assoc (let [pos (dom/get-client-position event)]
:menu-open true (swap! state assoc
:top (:y pos) :menu-open true
:left (:x pos))))) :top (:y pos)
:left (:x pos))))))
on-delete on-delete
(mf/use-callback (mf/use-callback
(mf/deps id) (mf/deps id)
#(st/emit! (modal/show #(st/emit! (modal/show
{:type :confirm {:type :confirm
:title (tr "modals.delete-page.title") :title (tr "modals.delete-page.title")
:message (tr "modals.delete-page.body") :message (tr "modals.delete-page.body")
:on-accept delete-fn}))) :on-accept delete-fn})))
on-double-click on-double-click
(mf/use-callback (mf/use-callback
(mf/deps workspace-read-only?)
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(swap! local assoc :edition true) (when-not workspace-read-only?
(swap! state assoc :menu-open false))) (swap! local assoc :edition true)
(swap! state assoc :menu-open false))))
on-blur on-blur
(mf/use-callback (mf/use-callback
@ -75,13 +79,13 @@
on-key-down on-key-down
(mf/use-callback (mf/use-callback
(fn [event] (fn [event]
(cond (cond
(kbd/enter? event) (kbd/enter? event)
(on-blur event) (on-blur event)
(kbd/esc? event) (kbd/esc? event)
(swap! local assoc :edition false)))) (swap! local assoc :edition false))))
on-drop on-drop
(mf/use-callback (mf/use-callback
@ -100,7 +104,8 @@
:on-drop on-drop :on-drop on-drop
:data {:id id :data {:id id
:index index :index index
:name (:name page)})] :name (:name page)}
:draggable? (not workspace-read-only?))]
(mf/use-effect (mf/use-effect
(mf/deps selected?) (mf/deps selected?)
@ -141,22 +146,23 @@
[:* [:*
[:span (:name page)] [:span (:name page)]
[:div.page-actions [:div.page-actions
(when deletable? (when (and deletable? (not workspace-read-only?))
[:a {:on-click on-delete} i/trash])]])]] [:a {:on-click on-delete} i/trash])]])]]
[:& context-menu (when-not workspace-read-only?
{:selectable false [:& context-menu
:show (:menu-open @state) {:selectable false
:on-close #(swap! state assoc :menu-open false) :show (:menu-open @state)
:top (:top @state) :on-close #(swap! state assoc :menu-open false)
:left (:left @state) :top (:top @state)
:options (cond-> [] :left (:left @state)
deletable? :options (cond-> []
(conj [(tr "workspace.assets.delete") on-delete]) deletable?
(conj [(tr "workspace.assets.delete") on-delete])
:always :always
(-> (conj [(tr "workspace.assets.rename") on-double-click]) (-> (conj [(tr "workspace.assets.rename") on-double-click])
(conj [(tr "workspace.assets.duplicate") on-duplicate])))}]])) (conj [(tr "workspace.assets.duplicate") on-duplicate])))}])]))
;; --- Page Item Wrapper ;; --- Page Item Wrapper
@ -198,26 +204,26 @@
(mf/defc sitemap (mf/defc sitemap
[] []
(let [file (mf/deref refs/workspace-file) (let [{:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]}
create (mf/use-callback
(mf/deps file)
(fn []
(st/emit! (dw/create-page {:file-id (:id file)
:project-id (:project-id file)}))))
show-pages? (mf/use-state true)
{:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]}
(use-resize-hook :sitemap 200 38 400 :y false nil) (use-resize-hook :sitemap 200 38 400 :y false nil)
size (if @show-pages? size 38) file (mf/deref refs/workspace-file)
toggle-pages create (mf/use-callback
(mf/use-callback #(reset! show-pages? not))] (mf/deps file)
(fn []
(st/emit! (dw/create-page {:file-id (:id file)
:project-id (:project-id file)}))))
show-pages? (mf/use-state true)
size (if @show-pages? size 38)
toggle-pages (mf/use-callback #(reset! show-pages? not))
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)]
[:div#sitemap.tool-window {:ref parent-ref [:div#sitemap.tool-window {:ref parent-ref
:style #js {"--height" (str size "px")}} :style #js {"--height" (str size "px")}}
[:div.tool-window-bar [:div.tool-window-bar
[:span (tr "workspace.sidebar.sitemap")] [:span (tr "workspace.sidebar.sitemap")]
[:div.add-page {:on-click create} i/close] (when-not workspace-read-only?
[:div.add-page {:on-click create} i/close])
[:div.collapse-pages {:on-click toggle-pages [:div.collapse-pages {:on-click toggle-pages
:style {:transform (when (not @show-pages?) "rotate(-90deg)")}} i/arrow-slide]] :style {:transform (when (not @show-pages?) "rotate(-90deg)")}} i/arrow-slide]]

View file

@ -130,22 +130,25 @@
node-editing? (and edition (not= :text (get-in base-objects [edition :type]))) node-editing? (and edition (not= :text (get-in base-objects [edition :type])))
text-editing? (and edition (= :text (get-in base-objects [edition :type]))) text-editing? (and edition (= :text (get-in base-objects [edition :type])))
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect) on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect)
on-context-menu (actions/on-context-menu hover hover-ids) on-context-menu (actions/on-context-menu hover hover-ids workspace-read-only?)
on-double-click (actions/on-double-click hover hover-ids drawing-path? base-objects edition) on-double-click (actions/on-double-click hover hover-ids drawing-path? base-objects edition workspace-read-only?)
on-drag-enter (actions/on-drag-enter) on-drag-enter (actions/on-drag-enter)
on-drag-over (actions/on-drag-over) on-drag-over (actions/on-drag-over)
on-drop (actions/on-drop file viewport-ref zoom) on-drop (actions/on-drop file viewport-ref zoom)
on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing? on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing?
drawing-path? create-comment? space? viewport-ref zoom panning) drawing-path? create-comment? space? viewport-ref zoom panning
workspace-read-only?)
on-mouse-up (actions/on-mouse-up disable-paste) on-mouse-up (actions/on-mouse-up disable-paste)
on-pointer-down (actions/on-pointer-down) on-pointer-down (actions/on-pointer-down)
on-pointer-enter (actions/on-pointer-enter in-viewport?) on-pointer-enter (actions/on-pointer-enter in-viewport?)
on-pointer-leave (actions/on-pointer-leave in-viewport?) on-pointer-leave (actions/on-pointer-leave in-viewport?)
on-pointer-move (actions/on-pointer-move viewport-ref zoom move-stream) on-pointer-move (actions/on-pointer-move viewport-ref zoom move-stream)
on-pointer-up (actions/on-pointer-up) on-pointer-up (actions/on-pointer-up)
on-move-selected (actions/on-move-selected hover hover-ids selected space?) on-move-selected (actions/on-move-selected hover hover-ids selected space? workspace-read-only?)
on-menu-selected (actions/on-menu-selected hover hover-ids selected) on-menu-selected (actions/on-menu-selected hover hover-ids selected workspace-read-only?)
on-frame-enter (actions/on-frame-enter frame-hover) on-frame-enter (actions/on-frame-enter frame-hover)
on-frame-leave (actions/on-frame-leave frame-hover) on-frame-leave (actions/on-frame-leave frame-hover)
@ -184,7 +187,7 @@
disabled-guides? (or drawing-tool transform)] disabled-guides? (or drawing-tool transform)]
(hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport?) (hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport? workspace-read-only?)
(hooks/setup-viewport-size viewport-ref) (hooks/setup-viewport-size viewport-ref)
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing?) (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing?)
(hooks/setup-keyboard alt? mod? space?) (hooks/setup-keyboard alt? mod? space?)

View file

@ -34,11 +34,12 @@
(defn on-mouse-down (defn on-mouse-down
[{:keys [id blocked hidden type]} selected edition drawing-tool text-editing? [{:keys [id blocked hidden type]} selected edition drawing-tool text-editing?
node-editing? drawing-path? create-comment? space? viewport-ref zoom panning] node-editing? drawing-path? create-comment? space? viewport-ref zoom panning
workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps id blocked hidden type selected edition drawing-tool text-editing? (mf/deps id blocked hidden type selected edition drawing-tool text-editing?
node-editing? drawing-path? create-comment? @space? viewport-ref zoom node-editing? drawing-path? create-comment? @space? viewport-ref zoom
panning) panning workspace-read-only?)
(fn [bevent] (fn [bevent]
(when (or (dom/class? (dom/get-target bevent) "viewport-controls") (when (or (dom/class? (dom/get-target bevent) "viewport-controls")
(dom/class? (dom/get-target bevent) "viewport-selrect")) (dom/class? (dom/get-target bevent) "viewport-selrect"))
@ -81,7 +82,8 @@
(cond (cond
node-editing? node-editing?
;; Handle path node area selection ;; Handle path node area selection
(st/emit! (dwdp/handle-area-selection shift?)) (when-not workspace-read-only?
(st/emit! (dwdp/handle-area-selection shift?)))
(and @space? mod?) (and @space? mod?)
(let [raw-pt (dom/get-client-position event) (let [raw-pt (dom/get-client-position event)
@ -93,18 +95,20 @@
(st/emit! (dw/start-panning)) (st/emit! (dw/start-panning))
drawing-tool drawing-tool
(st/emit! (dd/start-drawing drawing-tool)) (when-not workspace-read-only?
(st/emit! (dd/start-drawing drawing-tool)))
(or (not id) mod?) (or (not id) mod?)
(st/emit! (dw/handle-area-selection shift? mod?)) (st/emit! (dw/handle-area-selection shift? mod?))
(not drawing-tool) (not drawing-tool)
(st/emit! (dw/start-move-selected id shift?))))))))))) (when-not workspace-read-only?
(st/emit! (dw/start-move-selected id shift?))))))))))))
(defn on-move-selected (defn on-move-selected
[hover hover-ids selected space?] [hover hover-ids selected space? workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps @hover @hover-ids selected @space?) (mf/deps @hover @hover-ids selected @space? workspace-read-only?)
(fn [bevent] (fn [bevent]
(let [event (.-nativeEvent bevent) (let [event (.-nativeEvent bevent)
shift? (kbd/shift? event) shift? (kbd/shift? event)
@ -117,7 +121,8 @@
(not @space?)) (not @space?))
(dom/prevent-default bevent) (dom/prevent-default bevent)
(dom/stop-propagation bevent) (dom/stop-propagation bevent)
(st/emit! (dw/start-move-selected))))))) (when-not workspace-read-only?
(st/emit! (dw/start-move-selected))))))))
(defn on-frame-select (defn on-frame-select
[selected] [selected]
@ -167,10 +172,10 @@
(st/emit! (dw/select-shape (:id @hover) shift?)))))))) (st/emit! (dw/select-shape (:id @hover) shift?))))))))
(defn on-double-click (defn on-double-click
[hover hover-ids drawing-path? objects edition] [hover hover-ids drawing-path? objects edition workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps @hover @hover-ids drawing-path? edition) (mf/deps @hover @hover-ids drawing-path? edition workspace-read-only?)
(fn [event] (fn [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(let [ctrl? (kbd/ctrl? event) (let [ctrl? (kbd/ctrl? event)
@ -189,7 +194,7 @@
(fn [] (fn []
(when (and (not drawing-path?) shape) (when (and (not drawing-path?) shape)
(cond (cond
(and editable? (not= id edition)) (and editable? (not= id edition) (not workspace-read-only?))
(st/emit! (dw/select-shape id) (st/emit! (dw/select-shape id)
(dw/start-editing-selected)) (dw/start-editing-selected))
@ -202,33 +207,37 @@
(st/emit! (dw/select-shape (:id selected))))))))))))) (st/emit! (dw/select-shape (:id selected)))))))))))))
(defn on-context-menu (defn on-context-menu
[hover hover-ids] [hover hover-ids workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps @hover @hover-ids) (mf/deps @hover @hover-ids workspace-read-only?)
(fn [event] (fn [event]
(when (or (dom/class? (dom/get-target event) "viewport-controls") (if workspace-read-only?
(dom/class? (dom/get-target event) "viewport-selrect"))
(dom/prevent-default event) (dom/prevent-default event)
(when (or (dom/class? (dom/get-target event) "viewport-controls")
(dom/class? (dom/get-target event) "viewport-selrect")
(workspace-read-only?))
(dom/prevent-default event)
(let [position (dom/get-client-position event)] (let [position (dom/get-client-position event)]
;; Delayed callback because we need to wait to the previous context menu to be closed ;; Delayed callback because we need to wait to the previous context menu to be closed
(timers/schedule (timers/schedule
#(st/emit! #(st/emit!
(if (some? @hover) (if (some? @hover)
(dw/show-shape-context-menu {:position position (dw/show-shape-context-menu {:position position
:shape @hover :shape @hover
:hover-ids @hover-ids}) :hover-ids @hover-ids})
(dw/show-context-menu {:position position}))))))))) (dw/show-context-menu {:position position}))))))))))
(defn on-menu-selected (defn on-menu-selected
[hover hover-ids selected] [hover hover-ids selected workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps @hover @hover-ids selected) (mf/deps @hover @hover-ids selected workspace-read-only?)
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(let [position (dom/get-client-position event)] (when-not workspace-read-only?
(st/emit! (dw/show-shape-context-menu {:position position :hover-ids @hover-ids})))))) (let [position (dom/get-client-position event)]
(st/emit! (dw/show-shape-context-menu {:position position :hover-ids @hover-ids})))))))
(defn on-mouse-up (defn on-mouse-up
[disable-paste] [disable-paste]
@ -484,12 +493,13 @@
:blobs (seq files)}] :blobs (seq files)}]
(st/emit! (dwm/upload-media-workspace params)))))))) (st/emit! (dwm/upload-media-workspace params))))))))
(defn on-paste [disable-paste in-viewport?] (defn on-paste [disable-paste in-viewport? workspace-read-only?]
(mf/use-callback (mf/use-callback
(mf/deps workspace-read-only?)
(fn [event] (fn [event]
;; We disable the paste just after mouse-up of a middle button so when panning won't ;; We disable the paste just after mouse-up of a middle button so when panning won't
;; paste the content into the workspace ;; paste the content into the workspace
(let [tag-name (-> event dom/get-target dom/get-tag-name)] (let [tag-name (-> event dom/get-target dom/get-tag-name)]
(when (and (not (#{"INPUT" "TEXTAREA"} tag-name)) (not @disable-paste)) (when (and (not (#{"INPUT" "TEXTAREA"} tag-name)) (not @disable-paste) (not workspace-read-only?))
(st/emit! (dw/paste-from-event event @in-viewport?))))))) (st/emit! (dw/paste-from-event event @in-viewport?)))))))

View file

@ -32,14 +32,14 @@
[rumext.v2 :as mf]) [rumext.v2 :as mf])
(:import goog.events.EventType)) (:import goog.events.EventType))
(defn setup-dom-events [viewport-ref zoom disable-paste in-viewport?] (defn setup-dom-events [viewport-ref zoom disable-paste in-viewport? workspace-read-only?]
(let [on-key-down (actions/on-key-down) (let [on-key-down (actions/on-key-down)
on-key-up (actions/on-key-up) on-key-up (actions/on-key-up)
on-mouse-move (actions/on-mouse-move viewport-ref zoom) on-mouse-move (actions/on-mouse-move viewport-ref zoom)
on-mouse-wheel (actions/on-mouse-wheel viewport-ref zoom) on-mouse-wheel (actions/on-mouse-wheel viewport-ref zoom)
on-paste (actions/on-paste disable-paste in-viewport?)] on-paste (actions/on-paste disable-paste in-viewport? workspace-read-only?)]
(mf/use-layout-effect (mf/use-layout-effect
(mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-paste) (mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-paste workspace-read-only?)
(fn [] (fn []
(let [node (mf/ref-val viewport-ref) (let [node (mf/ref-val viewport-ref)
keys [(events/listen js/document EventType.KEYDOWN on-key-down) keys [(events/listen js/document EventType.KEYDOWN on-key-down)

View file

@ -15,6 +15,7 @@
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.cursors :as cur] [app.main.ui.cursors :as cur]
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]] [app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -286,13 +287,14 @@
(mf/defc controls-handlers (mf/defc controls-handlers
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (obj/get props "shape") (let [shape (obj/get props "shape")
zoom (obj/get props "zoom") zoom (obj/get props "zoom")
color (obj/get props "color") color (obj/get props "color")
on-resize (obj/get props "on-resize") on-resize (obj/get props "on-resize")
on-rotate (obj/get props "on-rotate") on-rotate (obj/get props "on-rotate")
disable-handlers (obj/get props "disable-handlers") disable-handlers (obj/get props "disable-handlers")
current-transform (mf/deref refs/current-transform) current-transform (mf/deref refs/current-transform)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
selrect (:selrect shape) selrect (:selrect shape)
transform (gsh/transform-matrix shape {:no-flip true}) transform (gsh/transform-matrix shape {:no-flip true})
@ -302,7 +304,8 @@
(gpt/angle) (gpt/angle)
(mod 360))] (mod 360))]
(when (not (#{:move :rotate} current-transform)) (when (and (not (#{:move :rotate} current-transform))
(not workspace-read-only?))
[:g.controls {:pointer-events (if disable-handlers "none" "visible")} [:g.controls {:pointer-events (if disable-handlers "none" "visible")}
;; Handlers ;; Handlers
(for [{:keys [type position props]} (handlers-for-selection selrect shape zoom)] (for [{:keys [type position props]} (handlers-for-selection selrect shape zoom)]

View file

@ -16,6 +16,7 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.streams :as ms] [app.main.streams :as ms]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]] [app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
@ -87,15 +88,17 @@
(mf/defc frame-title (mf/defc frame-title
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [frame selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}] [{:keys [frame selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}]
(let [on-mouse-down (let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-mouse-down
(mf/use-callback (mf/use-callback
(mf/deps (:id frame) on-frame-select) (mf/deps (:id frame) on-frame-select workspace-read-only?)
(fn [bevent] (fn [bevent]
(let [event (.-nativeEvent bevent)] (let [event (.-nativeEvent bevent)]
(when (= 1 (.-which event)) (when (= 1 (.-which event))
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(on-frame-select event (:id frame)))))) (when-not workspace-read-only?
(on-frame-select event (:id frame)))))))
on-double-click on-double-click
(mf/use-callback (mf/use-callback
@ -105,13 +108,14 @@
on-context-menu on-context-menu
(mf/use-callback (mf/use-callback
(mf/deps frame) (mf/deps frame workspace-read-only?)
(fn [bevent] (fn [bevent]
(let [event (.-nativeEvent bevent) (let [event (.-nativeEvent bevent)
position (dom/get-client-position event)] position (dom/get-client-position event)]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(st/emit! (dw/show-shape-context-menu {:position position :shape frame}))))) (when-not workspace-read-only?
(st/emit! (dw/show-shape-context-menu {:position position :shape frame}))))))
on-pointer-enter on-pointer-enter
(mf/use-callback (mf/use-callback
@ -156,15 +160,15 @@
{::mf/wrap-props false {::mf/wrap-props false
::mf/wrap [mf/memo]} ::mf/wrap [mf/memo]}
[props] [props]
(let [objects (unchecked-get props "objects") (let [objects (unchecked-get props "objects")
zoom (unchecked-get props "zoom") zoom (unchecked-get props "zoom")
selected (or (unchecked-get props "selected") #{}) selected (or (unchecked-get props "selected") #{})
show-artboard-names? (unchecked-get props "show-artboard-names?") show-artboard-names? (unchecked-get props "show-artboard-names?")
on-frame-enter (unchecked-get props "on-frame-enter") on-frame-enter (unchecked-get props "on-frame-enter")
on-frame-leave (unchecked-get props "on-frame-leave") on-frame-leave (unchecked-get props "on-frame-leave")
on-frame-select (unchecked-get props "on-frame-select") on-frame-select (unchecked-get props "on-frame-select")
frames (ctt/get-frames objects) frames (ctt/get-frames objects)
focus (unchecked-get props "focus")] focus (unchecked-get props "focus")]
[:g.frame-titles [:g.frame-titles
(for [frame frames] (for [frame frames]

View file

@ -316,3 +316,8 @@
objects (get-in @st/state [:workspace-data :pages-index page-id :objects])] objects (get-in @st/state [:workspace-data :pages-index page-id :objects])]
(.log js/console (modif->js (:workspace-modifiers @st/state) objects))) (.log js/console (modif->js (:workspace-modifiers @st/state) objects)))
nil) nil)
(defn ^:export set-workspace-read-only
[read-only?]
(st/emit! (dw/set-workspace-read-only read-only?)))