From 895f649ef1c02eb1477d44acb0ffb7da096c4e37 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 14:01:37 +0100 Subject: [PATCH 1/7] :bug: Stop drag events when the user focus out the application --- .../app/main/data/workspace/drawing/box.cljs | 8 +------ .../main/data/workspace/drawing/curve.cljs | 19 ++++++---------- .../app/main/data/workspace/interactions.cljs | 8 ++----- .../app/main/data/workspace/path/drawing.cljs | 12 +++------- .../app/main/data/workspace/path/edition.cljs | 8 ++----- .../main/data/workspace/path/selection.cljs | 13 +++-------- .../app/main/data/workspace/path/streams.cljs | 4 +--- .../app/main/data/workspace/selection.cljs | 13 ++++------- .../app/main/data/workspace/transforms.cljs | 19 ++++------------ .../app/main/ui/workspace/viewport/hooks.cljs | 7 ++++-- frontend/src/app/util/mouse.cljs | 22 ++++++++++++++++++- 11 files changed, 53 insertions(+), 80 deletions(-) diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index 76a6c3ce8..a595a8c3f 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -78,13 +78,7 @@ (ptk/reify ::handle-drawing ptk/WatchEvent (watch [_ state stream] - (let [stopper (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - (->> stream - (rx/filter #(= % :interrupt)))) - + (let [stopper (mse/drag-stopper stream) layout (get state :workspace-layout) zoom (dm/get-in state [:workspace-local :zoom] 1) diff --git a/frontend/src/app/main/data/workspace/drawing/curve.cljs b/frontend/src/app/main/data/workspace/drawing/curve.cljs index 8a2194962..5c0d98898 100644 --- a/frontend/src/app/main/data/workspace/drawing/curve.cljs +++ b/frontend/src/app/main/data/workspace/drawing/curve.cljs @@ -28,11 +28,6 @@ (def simplify-tolerance 0.3) -(defn stopper-event? - [{:keys [type] :as event}] - (and (mse/mouse-event? event) - (= type :up))) - (defn- insert-point [point] (ptk/reify ::insert-point @@ -104,13 +99,13 @@ (ptk/reify ::handle-drawing ptk/WatchEvent (watch [_ _ stream] - (let [stopper (rx/filter stopper-event? stream) - mouse (rx/sample 10 ms/mouse-position) - shape (cts/setup-shape {:type :path - :initialized? true - :frame-id uuid/zero - :parent-id uuid/zero - :segments []})] + (let [stopper (mse/drag-stopper stream) + mouse (rx/sample 10 ms/mouse-position) + shape (cts/setup-shape {:type :path + :initialized? true + :frame-id uuid/zero + :parent-id uuid/zero + :segments []})] (rx/concat (rx/of #(update % :workspace-drawing assoc :object shape)) (->> mouse diff --git a/frontend/src/app/main/data/workspace/interactions.cljs b/frontend/src/app/main/data/workspace/interactions.cljs index 5708ca3c4..1aad31f2f 100644 --- a/frontend/src/app/main/data/workspace/interactions.cljs +++ b/frontend/src/app/main/data/workspace/interactions.cljs @@ -193,9 +193,7 @@ (watch [_ state stream] (let [initial-pos @ms/mouse-position selected (wsh/lookup-selected state) - stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?))] + stopper (mse/drag-stopper stream)] (when (= 1 (count selected)) (rx/concat (->> ms/mouse-position @@ -305,9 +303,7 @@ (watch [_ state stream] (let [initial-pos @ms/mouse-position selected (wsh/lookup-selected state) - stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?))] + stopper (mse/drag-stopper stream)] (when (= 1 (count selected)) (let [page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index af492bc0f..f536f3369 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -139,9 +139,7 @@ (rx/map #(drag-handler position idx prefix %)) (rx/take-until (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (mse/drag-stopper stream) (->> stream (rx/filter helpers/end-path-event?)))))] @@ -166,9 +164,7 @@ ptk/WatchEvent (watch [_ state stream] (let [stopper (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (mse/drag-stopper stream) (->> stream (rx/filter helpers/end-path-event?))) @@ -197,9 +193,7 @@ (gpt/point? down-event)) (let [stopper (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (mse/drag-stopper stream) (->> stream (rx/filter helpers/end-path-event?))) diff --git a/frontend/src/app/main/data/workspace/path/edition.cljs b/frontend/src/app/main/data/workspace/path/edition.cljs index 51d688707..164e37acb 100644 --- a/frontend/src/app/main/data/workspace/path/edition.cljs +++ b/frontend/src/app/main/data/workspace/path/edition.cljs @@ -150,9 +150,7 @@ (ptk/reify ::drag-selected-points ptk/WatchEvent (watch [_ state stream] - (let [stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (let [stopper (mse/drag-stopper stream) id (dm/get-in state [:workspace-local :edition]) @@ -279,9 +277,7 @@ (not alt?))))) (rx/take-until (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (mse/drag-stopper stream) (->> stream (rx/filter streams/finish-edition?))))) diff --git a/frontend/src/app/main/data/workspace/path/selection.cljs b/frontend/src/app/main/data/workspace/path/selection.cljs index 028a6ec3b..b2256b3c9 100644 --- a/frontend/src/app/main/data/workspace/path/selection.cljs +++ b/frontend/src/app/main/data/workspace/path/selection.cljs @@ -10,7 +10,6 @@ [app.common.geom.point :as gpt] [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] - [app.main.data.workspace.common :as dwc] [app.main.data.workspace.path.state :as st] [app.main.streams :as ms] [app.util.mouse :as mse] @@ -119,15 +118,9 @@ (ptk/reify ::handle-area-selection ptk/WatchEvent (watch [_ state stream] - (let [zoom (get-in state [:workspace-local :zoom] 1) - stopper (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - (->> stream - (rx/filter dwc/interrupt?))) - - from-p @ms/mouse-position] + (let [zoom (get-in state [:workspace-local :zoom] 1) + stopper (mse/drag-stopper stream) + from-p @ms/mouse-position] (rx/concat (->> ms/mouse-position (rx/map #(grc/points->rect [from-p %])) diff --git a/frontend/src/app/main/data/workspace/path/streams.cljs b/frontend/src/app/main/data/workspace/path/streams.cljs index 9f55e92a0..38d0efd50 100644 --- a/frontend/src/app/main/data/workspace/path/streams.cljs +++ b/frontend/src/app/main/data/workspace/path/streams.cljs @@ -53,9 +53,7 @@ start (-> @ms/mouse-position to-pixel-snap) stopper (rx/merge - (->> st/stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + (mse/drag-stopper st/stream) (->> st/stream (rx/filter finish-edition?))) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 3f22275b9..ca4200c11 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -27,6 +27,7 @@ [app.main.data.modal :as md] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.collapse :as dwc] + [app.main.data.workspace.edition :as dwe] [app.main.data.workspace.libraries-helpers :as dwlh] [app.main.data.workspace.specialized-panel :as-alias dwsp] [app.main.data.workspace.state-helpers :as wsh] @@ -63,14 +64,8 @@ (ptk/reify ::handle-area-selection ptk/WatchEvent (watch [_ state stream] - (let [zoom (dm/get-in state [:workspace-local :zoom] 1) - stopper (rx/merge - (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - (->> stream - (rx/filter interrupt?))) - + (let [zoom (dm/get-in state [:workspace-local :zoom] 1) + stopper (mse/drag-stopper stream) init-position @ms/mouse-position init-selrect (grc/make-rect @@ -155,7 +150,7 @@ objects (wsh/lookup-page-objects state page-id)] (rx/of (dwc/expand-all-parents [id] objects) - :interrupt + (dwe/clear-edition-mode) ::dwsp/interrupt)))))) (defn select-prev-shape diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index fc8ee350d..c52cd2fbb 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -257,9 +257,7 @@ (watch [_ state stream] (let [initial-position @ms/mouse-position - stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) + stopper (mse/drag-stopper stream) layout (:workspace-layout state) page-id (:current-page-id state) focus (:workspace-focus-selected state) @@ -370,10 +368,7 @@ ptk/WatchEvent (watch [_ _ stream] - (let [stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - + (let [stopper (mse/drag-stopper stream) group (gsh/shapes->rect shapes) group-center (grc/rect->center group) initial-angle (gpt/angle @ms/mouse-position group-center) @@ -436,10 +431,7 @@ (watch [_ state stream] (let [initial (deref ms/mouse-position) - stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - + stopper (mse/drag-stopper stream) zoom (get-in state [:workspace-local :zoom] 1) ;; We toggle the selection so we don't have to wait for the event @@ -518,10 +510,7 @@ duplicate-move-started? (get-in state [:workspace-local :duplicate-move-started?] false) - stopper (->> stream - (rx/filter mse/mouse-event?) - (rx/filter mse/mouse-up-event?)) - + stopper (mse/drag-stopper stream) layout (get state :workspace-layout) zoom (get-in state [:workspace-local :zoom] 1) focus (:workspace-focus-selected state) diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 1a8c45567..c2d4ab55b 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -32,6 +32,7 @@ [app.util.dom :as dom] [app.util.globals :as globals] [app.util.keyboard :as kbd] + [app.util.mouse :as mse] [beicon.v2.core :as rx] [beicon.v2.operators :as rxo] [goog.events :as events] @@ -42,7 +43,8 @@ (let [on-key-down (actions/on-key-down) on-key-up (actions/on-key-up) on-mouse-wheel (actions/on-mouse-wheel zoom) - on-paste (actions/on-paste disable-paste in-viewport? workspace-read-only?)] + on-paste (actions/on-paste disable-paste in-viewport? workspace-read-only?) + on-blur (mf/use-fn #(st/emit! (mse/->BlurEvent)))] (mf/use-layout-effect (mf/deps on-key-down on-key-up on-mouse-wheel on-paste workspace-read-only?) @@ -52,7 +54,8 @@ ;; bind with passive=false to allow the event to be cancelled ;; https://stackoverflow.com/a/57582286/3219895 (events/listen js/window EventType.WHEEL on-mouse-wheel #js {:passive false}) - (events/listen js/window EventType.PASTE on-paste)]] + (events/listen js/window EventType.PASTE on-paste) + (events/listen js/window EventType.BLUR on-blur)]] (fn [] (doseq [key keys] (events/unlistenByKey key)))))))) diff --git a/frontend/src/app/util/mouse.cljs b/frontend/src/app/util/mouse.cljs index b7771eba2..4576ed325 100644 --- a/frontend/src/app/util/mouse.cljs +++ b/frontend/src/app/util/mouse.cljs @@ -4,11 +4,14 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns app.util.mouse) +(ns app.util.mouse + (:require + [beicon.v2.core :as rx])) (defrecord MouseEvent [type ctrl shift alt meta]) (defrecord PointerEvent [source pt ctrl shift alt meta]) (defrecord ScrollEvent [point]) +(defrecord BlurEvent []) (defn mouse-event? [v] @@ -22,6 +25,10 @@ [v] (instance? ScrollEvent v)) +(defn blur-event? + [v] + (instance? BlurEvent v)) + (defn mouse-down-event? [^MouseEvent v] (= :down (.-type v))) @@ -61,3 +68,16 @@ (defn get-pointer-shift-mod [^PointerEvent ev] (.-shift ev)) + +(defn drag-stopper + "Creates a stream to stop drag events. Takes into account the mouse and also + if the window loses focus or the esc key is pressed." + [stream] + (rx/merge + (->> stream + (rx/filter blur-event?)) + (->> stream + (rx/filter mouse-event?) + (rx/filter mouse-up-event?)) + (->> stream + (rx/filter #(= % :interrupt))))) From b097f73b135e937ace9b4e7b24148cc5b6515f74 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 14:18:17 +0100 Subject: [PATCH 2/7] :bug: Fix problem with snap to frame guides --- frontend/src/app/worker/snaps.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/worker/snaps.cljs b/frontend/src/app/worker/snaps.cljs index ceecc5b89..77bf5d8f5 100644 --- a/frontend/src/app/worker/snaps.cljs +++ b/frontend/src/app/worker/snaps.cljs @@ -29,6 +29,7 @@ (let [match-bounds? (fn [[_ data]] (some #(or (= :guide (:type %)) + (= :layout (:type %)) (grc/contains-point? bounds (:pt %))) data))] (->> (into [] (comp (mapcat #(sd/query @state page-id frame-id axis %)) From 8850fd88948ce7aa622ee6bd707adbd740abfa10 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 14:52:38 +0100 Subject: [PATCH 3/7] :bug: Fix problem dragging in draft/projects screen --- frontend/src/app/main/ui/dashboard/grid.cljs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 6f5565611..276fa7ce4 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -419,8 +419,9 @@ on-drag-enter (mf/use-fn (fn [e] - (when (or (dnd/has-type? e "Files") - (dnd/has-type? e "application/x-moz-file")) + (when (and (not (dnd/has-type? e "penpot/files")) + (or (dnd/has-type? e "Files") + (dnd/has-type? e "application/x-moz-file"))) (dom/prevent-default e) (reset! dragging? true)))) @@ -440,8 +441,9 @@ on-drop (mf/use-fn (fn [e] - (when (or (dnd/has-type? e "Files") - (dnd/has-type? e "application/x-moz-file")) + (when (and (not (dnd/has-type? e "penpot/files")) + (or (dnd/has-type? e "Files") + (dnd/has-type? e "application/x-moz-file"))) (dom/prevent-default e) (reset! dragging? false) (import-files (.-files (.-dataTransfer e))))))] From db7ed75a91cedf12009d9b634c905fa2421d4e3c Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 15:02:29 +0100 Subject: [PATCH 4/7] :bug: Add mime-type otf to color picker --- common/src/app/common/media.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/app/common/media.cljc b/common/src/app/common/media.cljc index 212d43f2a..a342a227f 100644 --- a/common/src/app/common/media.cljc +++ b/common/src/app/common/media.cljc @@ -10,7 +10,7 @@ [cuerdas.core :as str])) ;; We have added ".ttf" as string to solve a problem with chrome input selector -(def valid-font-types #{"font/ttf", ".ttf", "font/woff", "application/font-woff", "font/otf"}) +(def valid-font-types #{"font/ttf" ".ttf" "font/woff", "application/font-woff" "woff" "font/otf" ".otf" "font/opentype"}) (def valid-image-types #{"image/jpeg", "image/png", "image/webp", "image/gif", "image/svg+xml"}) (def str-image-types (str/join "," valid-image-types)) (def str-font-types (str/join "," valid-font-types)) From dd69762b311b6c4d3e918966f6f7d491da7a68e1 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 15:13:57 +0100 Subject: [PATCH 5/7] :bug: Fix problem with dismiss fonts --- frontend/src/app/main/ui/dashboard/fonts.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index 17aa4a8d4..be6cd908f 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -161,7 +161,7 @@ (mf/use-fn (mf/deps fonts) (fn [_] - (run! on-delete (vals fonts))))] + (run! #(swap! fonts* dissoc (:id %)) (vals fonts))))] [:div {:class (stl/css :dashboard-fonts-upload)} [:div {:class (stl/css :dashboard-fonts-hero)} From dc7d279e9dd803cd580270e66caa2ac298c59eb4 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 15:33:51 +0100 Subject: [PATCH 6/7] :bug: Fix problem with interactions over frames --- frontend/src/app/main/ui/viewer/shapes.cljs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 6a739d320..5832f28ce 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -265,8 +265,7 @@ (mf/defc interaction [{:keys [shape interactions interactions-show?]}] - (let [{:keys [x y width height]} (:selrect shape) - frame? (= :frame (:type shape))] + (let [{:keys [x y width height]} (:selrect shape)] (when-not (empty? interactions) [:rect {:x (- x 1) :y (- y 1) @@ -276,7 +275,6 @@ :stroke "var(--color-accent-tertiary)" :stroke-width (if interactions-show? 1 0) :fill-opacity (if interactions-show? 0.2 0) - :style {:pointer-events (when frame? "none")} :transform (gsh/transform-str shape)}]))) From 8e7471509cb4c267e23d15089bd70f8e074ede63 Mon Sep 17 00:00:00 2001 From: "alonso.torres" <alonso.torres@kaleidos.net> Date: Fri, 15 Mar 2024 15:54:40 +0100 Subject: [PATCH 7/7] :bug: Fix problem on modal transfer owner --- frontend/src/app/main/ui/dashboard/change_owner.cljs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/dashboard/change_owner.cljs b/frontend/src/app/main/ui/dashboard/change_owner.cljs index 0af37045d..b3a8e04d2 100644 --- a/frontend/src/app/main/ui/dashboard/change_owner.cljs +++ b/frontend/src/app/main/ui/dashboard/change_owner.cljs @@ -29,10 +29,13 @@ members-map (mf/deref refs/dashboard-team-members) members (vals members-map) - options (into [{:value "" - :label (tr "modals.leave-and-reassign.select-member-to-promote")}] - (filter #(not= (:label %) (:fullname profile)) - (map #(hash-map :label (:name %) :value (str (:id %))) members))) + options + (into [{:value "" + :label (tr "modals.leave-and-reassign.select-member-to-promote")}] + (comp + (filter #(not= (:email %) (:email profile))) + (map #(hash-map :label (:name %) :value (str (:id %))))) + members) on-cancel #(st/emit! (modal/hide)) on-accept