From 38952b6734607f2d26da11b0f1a6014042c7c4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Fri, 8 Oct 2021 14:13:19 +0200 Subject: [PATCH] :tada: Enable auto-flows --- common/src/app/common/pages/helpers.cljc | 8 ++ common/src/app/common/types/interactions.cljc | 28 +++++ common/src/app/common/types/page_options.cljc | 4 +- .../app/main/data/workspace/interactions.cljs | 102 +++++++++++++----- .../sidebar/options/menus/interactions.cljs | 18 ++-- .../ui/workspace/viewport/interactions.cljs | 4 +- 6 files changed, 122 insertions(+), 42 deletions(-) diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index d170b45f1..596e5a9f4 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -9,6 +9,7 @@ [app.common.data :as d] [app.common.geom.shapes :as gsh] [app.common.spec :as us] + [app.common.types.interactions :as cti] [app.common.uuid :as uuid] [cuerdas.core :as str])) @@ -476,3 +477,10 @@ (let [path-split (split-path path)] (merge-path-item (first path-split) name))) +(defn connected-frame? + "Check if some frame is origin or destination of any navigate interaction + in the page" + [frame-id objects] + (let [children (get-object-with-children frame-id objects)] + (or (some cti/flow-origin? (map :interactions children)) + (some #(cti/flow-to? % frame-id) (map :interactions (vals objects)))))) diff --git a/common/src/app/common/types/interactions.cljc b/common/src/app/common/types/interactions.cljc index f186abb16..15f1a15c3 100644 --- a/common/src/app/common/types/interactions.cljc +++ b/common/src/app/common/types/interactions.cljc @@ -326,7 +326,35 @@ ;; -- Helpers for interactions +(defn add-interaction + [interactions interaction] + (conj (or interactions []) interaction)) + +(defn remove-interaction + [interactions index] + (let [interactions (or interactions [])] + (into (subvec interactions 0 index) + (subvec interactions (inc index))))) + +(defn update-interaction + [interactions index update-fn] + (update interactions index update-fn)) + (defn actionable? + "Check if there is any interaction that is clickable by the user" [interactions] (some #(= (:event-type %) :click) interactions)) +(defn flow-origin? + "Check if there is any interaction of type :navigate that goes outside" + [interactions] + (some #(and (= (:action-type %) :navigate) + (some? (:destination %))) + interactions)) + +(defn flow-to? + "Check if there is any interaction of type :navigate that goes to the given frame" + [interactions frame-id] + (some #(and (= (:action-type %) :navigate) + (= (:destination %) frame-id)) + interactions)) diff --git a/common/src/app/common/types/page_options.cljc b/common/src/app/common/types/page_options.cljc index 2fbdcd394..c15258eda 100644 --- a/common/src/app/common/types/page_options.cljc +++ b/common/src/app/common/types/page_options.cljc @@ -77,11 +77,11 @@ (defn add-flow [flows flow] - (conj flows flow)) + (conj (or flows []) flow)) (defn remove-flow [flows flow-id] - (vec (remove #(= (:id %) flow-id) flows))) + (d/removev #(= (:id %) flow-id) flows)) (defn update-flow [flows flow-id update-fn] diff --git a/frontend/src/app/main/data/workspace/interactions.cljs b/frontend/src/app/main/data/workspace/interactions.cljs index 179cc03df..bf7ba200f 100644 --- a/frontend/src/app/main/data/workspace/interactions.cljs +++ b/frontend/src/app/main/data/workspace/interactions.cljs @@ -22,9 +22,9 @@ ;; --- Flows -(defn add-flow-selected-frame - [] - (ptk/reify ::add-flow-selected-frame +(defn add-flow + [starting-frame] + (ptk/reify ::add-flow ptk/WatchEvent (watch [it state _] (let [page-id (:current-page-id state) @@ -34,14 +34,12 @@ :options :flows] []) - selected (wsh/lookup-selected state) - unames (into #{} (map :name flows)) name (dwc/generate-unique-name unames "Flow-1") new-flow {:id (uuid/next) :name name - :starting-frame (first selected)}] + :starting-frame starting-frame}] (rx/of (dch/commit-changes {:redo-changes [{:type :set-option @@ -54,6 +52,14 @@ :value flows}] :origin it})))))) +(defn add-flow-selected-frame + [] + (ptk/reify ::add-flow-selected-frame + ptk/WatchEvent + (watch [_ state _] + (let [selected (wsh/lookup-selected state)] + (rx/of (add-flow (first selected))))))) + (defn remove-flow [flow-id] (us/verify ::us/uuid flow-id) @@ -120,6 +126,53 @@ ;; --- Interactions +(defn add-new-interaction + ([shape] (add-new-interaction shape nil)) + ([shape destination] + (ptk/reify ::add-new-interaction + ptk/WatchEvent + (watch [_ state _] + (let [page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + frame (cph/get-frame shape objects) + flows (get-in state [:workspace-data + :pages-index + page-id + :options + :flows] []) + flow (cto/get-frame-flow flows (:id frame))] + (rx/concat + (rx/of (dch/update-shapes [(:id shape)] + (fn [shape] + (let [new-interaction (cti/set-destination + cti/default-interaction + destination)] + (update shape :interactions + cti/add-interaction new-interaction))))) + (when (and (not (cph/connected-frame? (:id frame) objects)) + (nil? flow)) + (rx/of (add-flow (:id frame)))))))))) + +(defn remove-interaction + [shape index] + (ptk/reify ::remove-interaction + ptk/WatchEvent + (watch [_ _ _] + (rx/of (dch/update-shapes [(:id shape)] + (fn [shape] + (update shape :interactions + cti/remove-interaction index))))))) + +(defn update-interaction + [shape index update-fn] + (ptk/reify ::update-interaction + ptk/WatchEvent + (watch [_ _ _] + (rx/of (dch/update-shapes [(:id shape)] + (fn [shape] + (update shape :interactions + cti/update-interaction index update-fn))))))) + (declare move-edit-interaction) (declare finish-edit-interaction) @@ -179,28 +232,23 @@ shape (get objects shape-id)] (when (and shape (not (= position initial-pos))) - (rx/of (dch/update-shapes [shape-id] - (fn [shape] - (update shape :interactions - (fn [interactions] - (if-not frame - ;; Drop in an empty space -> remove interaction - (if index - (into (subvec interactions 0 index) - (subvec interactions (inc index))) - interactions) - (let [frame (if (or (= (:id frame) (:id shape)) - (= (:id frame) (:frame-id shape))) - nil ;; Drop onto self frame -> set destination to none - frame)] - ;; Update or create interaction - (if (and index (cti/has-destination (get interactions index))) - (update interactions index - #(cti/set-destination % (:id frame))) - (conj (or interactions []) - (cti/set-destination cti/default-interaction - (:id frame)))))))))))))))) + (if (nil? frame) + (when index + (rx/of (remove-interaction shape index))) + (let [frame (if (or (= (:id frame) (:id shape)) + (= (:id frame) (:frame-id shape))) + nil ;; Drop onto self frame -> set destination to none + frame)] + (if (nil? index) + (rx/of (add-new-interaction shape (:id frame))) + (rx/of (update-interaction shape index + (fn [interaction] + (cond-> interaction + (not (cti/has-destination interaction)) + (cti/set-action-type :navigate) + :always + (cti/set-destination (:id frame)))))))))))))) ;; --- Overlays (declare move-overlay-pos) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs index 74360b849..74a2d08c9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs @@ -360,22 +360,16 @@ flows (:flows options) add-interaction - (fn [_] - (let [new-interactions (conj interactions cti/default-interaction)] - (st/emit! (dw/update-shape (:id shape) {:interactions new-interactions})))) + (fn [] + (st/emit! (dwi/add-new-interaction shape))) remove-interaction (fn [index] - (let [new-interactions - (into (subvec interactions 0 index) - (subvec interactions (inc index)))] - (st/emit! (dw/update-shape (:id shape) {:interactions new-interactions})))) + (st/emit! (dwi/remove-interaction shape index))) update-interaction (fn [index update-fn] - (let [new-interactions (update interactions index update-fn)] - (st/emit! (dw/update-shape (:id shape) {:interactions new-interactions})))) ] - + (st/emit! (dwi/update-interaction shape index update-fn)))] [:* (if shape [:& shape-flows {:flows flows @@ -383,7 +377,7 @@ [:& page-flows {:flows flows}]) [:div.element-set.interactions-options - (when shape + (when (and shape (not= (:frame-id shape) uuid/zero)) [:div.element-set-title [:span (tr "workspace.options.interactions")] [:div.add-page {:on-click add-interaction} @@ -391,7 +385,7 @@ [:div.element-set-content (when (= (count interactions) 0) [:* - (when shape + (when (and shape (not= (:frame-id shape) uuid/zero)) [:* [:div.interactions-help-icon i/plus] [:div.interactions-help.separator (tr "workspace.options.add-interaction")]]) diff --git a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs index 99454dce1..3072bc40a 100644 --- a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.pages.helpers :as cph] [app.common.types.interactions :as cti] + [app.common.uuid :as uuid] [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] @@ -319,7 +320,8 @@ :position (:overlay-position interaction) :objects objects :hover-disabled? hover-disabled?}]))]))) - (when (not (#{:move :rotate} current-transform)) + (when (and (not= (:frame-id shape) uuid/zero) + (not (#{:move :rotate} current-transform))) [:& interaction-handle {:key (:id shape) :index nil :shape shape