mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Fix path editor crash on shortcut (#11996)
This commit is contained in:
parent
0d8bcf9637
commit
29072e4c6b
@ -37,13 +37,16 @@
|
||||
(declare change-edit-mode)
|
||||
|
||||
(defn start-created-path-edition
|
||||
[id]
|
||||
(ptk/reify ::start-created-path-edition
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (dwe/start-edition-mode id)
|
||||
(edition/start-path-edit id)
|
||||
(change-edit-mode :draw)))))
|
||||
"Edits a just created path in `edit-mode` (`:draw` by default)."
|
||||
([id]
|
||||
(start-created-path-edition id :draw))
|
||||
([id edit-mode]
|
||||
(ptk/reify ::start-created-path-edition
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (dwe/start-edition-mode id)
|
||||
(edition/start-path-edit id)
|
||||
(change-edit-mode edit-mode))))))
|
||||
|
||||
;; Draw-loop stop signals either restart the same path or exit drawing.
|
||||
|
||||
@ -434,11 +437,12 @@
|
||||
(when-let [content (dm/get-in state [:workspace-drawing :object :content])]
|
||||
(cond
|
||||
(and (> (count content) 1) restart?)
|
||||
(rx/of (common/finish-path)
|
||||
(clean-drawn-content)
|
||||
(setup-frame)
|
||||
(dwdc/handle-finish-drawing)
|
||||
(start-created-path-edition shape-id))
|
||||
(let [edit-mode (dm/get-in state [:workspace-local :edit-path shape-id :edit-mode])]
|
||||
(rx/of (common/finish-path)
|
||||
(clean-drawn-content)
|
||||
(setup-frame)
|
||||
(dwdc/handle-finish-drawing)
|
||||
(start-created-path-edition shape-id (d/nilv edit-mode :draw))))
|
||||
|
||||
(> (count content) 1)
|
||||
(rx/of (clean-drawn-content)
|
||||
@ -545,6 +549,10 @@
|
||||
state)))
|
||||
|
||||
(defn change-edit-mode
|
||||
"Switches the active path between `:draw` and `:move`.
|
||||
|
||||
A new path being drawn has no edition yet; switching it to `:move`
|
||||
finishes the drawing, which then reenters edition in `:move`."
|
||||
[mode]
|
||||
(ptk/reify ::change-edit-mode
|
||||
ptk/UpdateEvent
|
||||
@ -552,16 +560,20 @@
|
||||
(if-let [id (dm/get-in state [:workspace-local :edition])]
|
||||
(cond-> (d/update-in-when state [:workspace-local :edit-path id] assoc :edit-mode mode)
|
||||
(= mode :draw) (enter-draw-from-selected-node id))
|
||||
state))
|
||||
(cond-> state
|
||||
(and (= mode :move) (st/drawing? state))
|
||||
(assoc-in [:workspace-local :edit-path (st/get-path-id state) :edit-mode] :move))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(when-let [id (dm/get-in state [:workspace-local :edition])]
|
||||
(if-let [id (dm/get-in state [:workspace-local :edition])]
|
||||
(let [mode (dm/get-in state [:workspace-local :edit-path id :edit-mode])]
|
||||
(case mode
|
||||
:move (rx/of (common/finish-path))
|
||||
:draw (rx/of (start-draw-mode))
|
||||
(rx/empty)))))))
|
||||
(rx/empty)))
|
||||
(when (and (= mode :move) (st/drawing? state))
|
||||
(rx/of (common/finish-path)))))))
|
||||
|
||||
(defn reset-last-handler
|
||||
[]
|
||||
|
||||
@ -157,6 +157,7 @@
|
||||
:label (fn [] (tr "shortcuts.deselect-all"))
|
||||
:command (ds/c-mod "shift+a")
|
||||
:subsections [:path-editor]
|
||||
:overwrite true
|
||||
:fn #(st/emit! (drp/deselect-all))}
|
||||
|
||||
:flip-horizontal {:tooltip (ds/shift "H")
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
[app.main.data.workspace.path.streams :as path.streams]
|
||||
[app.main.data.workspace.path.tools :as path.tools]
|
||||
[app.main.data.workspace.path.undo :as path.undo]
|
||||
[app.main.data.workspace.shortcuts :as wsc]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.state :as ths]
|
||||
@ -138,22 +139,23 @@
|
||||
|
||||
(defn- run-handle-drawing-end
|
||||
"Runs the draw-ending flow and passes its events to `callback`."
|
||||
[restart? callback]
|
||||
(let [state (pth/drawing-path-state)
|
||||
stream (rx/subject)
|
||||
emissions (atom [])]
|
||||
(->> (ptk/watch (path.drawing/handle-drawing) state stream)
|
||||
(rx/subs! #(swap! emissions conj %)))
|
||||
(rx/push! stream (ptk/data-event ::path.drawing/end-edition
|
||||
{:restart? restart?}))
|
||||
;; Wait for the asynchronous drawing-end event.
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(let [end-event (last @emissions)
|
||||
end-emissions (atom [])]
|
||||
(->> (ptk/watch end-event state stream)
|
||||
(rx/subs! #(swap! end-emissions conj %)))
|
||||
(callback @end-emissions))))))
|
||||
([restart? callback]
|
||||
(run-handle-drawing-end (pth/drawing-path-state) restart? callback))
|
||||
([state restart? callback]
|
||||
(let [stream (rx/subject)
|
||||
emissions (atom [])]
|
||||
(->> (ptk/watch (path.drawing/handle-drawing) state stream)
|
||||
(rx/subs! #(swap! emissions conj %)))
|
||||
(rx/push! stream (ptk/data-event ::path.drawing/end-edition
|
||||
{:restart? restart?}))
|
||||
;; Wait for the asynchronous drawing-end event.
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(let [end-event (last @emissions)
|
||||
end-emissions (atom [])]
|
||||
(->> (ptk/watch end-event state stream)
|
||||
(rx/subs! #(swap! end-emissions conj %)))
|
||||
(callback @end-emissions)))))))
|
||||
|
||||
(t/deftest escape-ending-new-path-draw-does-not-reenter-edition
|
||||
(t/async
|
||||
@ -182,6 +184,43 @@
|
||||
(mapv ptk/type emissions)))
|
||||
(done)))))
|
||||
|
||||
(t/deftest finishing-new-path-draw-in-move-mode-reenters-edition-in-move-mode
|
||||
(t/async
|
||||
done
|
||||
(let [state (pth/drawing-path-state)
|
||||
id (get-in state [:workspace-drawing :object :id])
|
||||
state (assoc-in state [:workspace-local :edit-path id :edit-mode] :move)]
|
||||
(run-handle-drawing-end
|
||||
state
|
||||
true
|
||||
(fn [emissions]
|
||||
(let [edition-emissions (atom [])]
|
||||
(->> (ptk/watch (last emissions) state nil)
|
||||
(rx/subs! #(swap! edition-emissions conj %)))
|
||||
(let [change-mode (last @edition-emissions)
|
||||
edited {:workspace-local {:edition id
|
||||
:edit-path {id {:edit-mode :draw}}}}]
|
||||
(t/is (= ::path.drawing/change-edit-mode (ptk/type change-mode)))
|
||||
(t/is (= :move (get-in (ptk/update change-mode edited)
|
||||
[:workspace-local :edit-path id :edit-mode])))))
|
||||
(done))))))
|
||||
|
||||
(t/deftest move-mode-while-creating-path-finishes-it
|
||||
(let [id (random-uuid)
|
||||
state {:workspace-local
|
||||
{:edit-path {id {:edit-mode :draw
|
||||
:last-point (gpt/point 10 10)}}}
|
||||
:workspace-drawing {:tool :path
|
||||
:object {:id id :type :path}}}
|
||||
event (path.drawing/change-edit-mode :move)
|
||||
state' (ptk/update event state)
|
||||
emissions (atom [])]
|
||||
(t/is (= :move (get-in state' [:workspace-local :edit-path id :edit-mode])))
|
||||
(->> (ptk/watch event state' nil)
|
||||
(rx/subs! #(swap! emissions conj %)))
|
||||
(t/is (= [::path.common/finish-path]
|
||||
(mapv ptk/type @emissions)))))
|
||||
|
||||
(t/deftest ending-a-draw-collapses-the-nodes-drawn-on-top-of-each-other
|
||||
(t/async
|
||||
done
|
||||
@ -237,6 +276,12 @@
|
||||
(t/is (= [::path.common/finish-path]
|
||||
(mapv ptk/type @emissions)))))
|
||||
|
||||
(t/deftest deselect-all-shortcut-replaces-the-grid-layout-toggle
|
||||
(let [deselect-all (:deselect-all path.shortcuts/shortcuts)
|
||||
grid-toggle (:toggle-layout-grid wsc/shortcuts)]
|
||||
(t/is (= (:command grid-toggle) (:command deselect-all)))
|
||||
(t/is (true? (:overwrite deselect-all)))))
|
||||
|
||||
(t/deftest escape-without-pending-segment-interrupts-edition
|
||||
(let [id (random-uuid)
|
||||
state {:workspace-local
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user