diff --git a/common/src/app/common/types/interactions.cljc b/common/src/app/common/types/interactions.cljc index 781a16ac9..2c5fa6c1e 100644 --- a/common/src/app/common/types/interactions.cljc +++ b/common/src/app/common/types/interactions.cljc @@ -109,16 +109,18 @@ :action-type :navigate :destination nil}) -(def default-delay 100) +(def default-delay 600) ;; -- Helpers for interaction (declare calc-overlay-position) (defn set-event-type - [interaction event-type] + [interaction event-type shape] (us/verify ::interaction interaction) (us/verify ::event-type event-type) + (assert (or (not= event-type :after-delay) + (= (:type shape) :frame))) (if (= (:event-type interaction) event-type) interaction (case event-type @@ -176,6 +178,13 @@ :action-type action-type :url (get interaction :url ""))))) +(defn set-delay + [interaction delay] + (us/verify ::interaction interaction) + (us/verify ::delay delay) + (assert (= (:event-type interaction) :after-delay)) + (assoc interaction :delay delay)) + (defn set-destination [interaction destination shape objects] (us/verify ::interaction interaction) diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index 5a36e748f..4bfe3b369 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -185,6 +185,7 @@ display: flex; flex-direction: column; padding: $x-small; + width: 100%; .input-text { background-color: $color-gray-50; @@ -219,6 +220,10 @@ color: $color-gray-60; background: $color-white; font-size: $fs12; + + &:disabled { + color: $color-gray-20; + } } } @@ -253,7 +258,7 @@ width: 64px; &.wide { - width: 110px; + min-width: 75px; } } @@ -441,6 +446,10 @@ color: $color-gray-60; background: $color-white; font-size: $fs12; + + &:disabled { + color: $color-gray-20; + } } } diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 1e328cc89..d4884ac8f 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -26,6 +26,7 @@ [app.main.ui.shapes.text :as text] [app.util.dom :as dom] [app.util.object :as obj] + [app.util.timers :as tm] [rumext.alpha :as mf])) (defn activate-interaction @@ -142,6 +143,19 @@ (doseq [interaction interactions-inv] (deactivate-interaction interaction shape))))) +(defn on-load + [shape] + (let [interactions (->> (:interactions shape) + (filter #(= (:event-type %) :after-delay)))] + (loop [interactions (seq interactions) + sems []] + (if-let [interaction (first interactions)] + (let [sem (tm/schedule (:delay interaction) + #(activate-interaction interaction shape))] + (recur (next interactions) + (conj sems sem))) + sems)))) + (mf/defc interaction [{:keys [shape interactions show-interactions?]}] (let [{:keys [x y width height]} (:selrect shape) @@ -173,6 +187,11 @@ svg-element? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag])))] + (mf/use-effect + (fn [] + (let [sems (on-load shape)] + #(run! tm/dispose! sems)))) + (if-not svg-element? [:> shape-container {:shape shape :cursor (when (cti/actionable? interactions) "pointer") 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 73d0040ea..d0054dbc7 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 @@ -13,6 +13,7 @@ [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.components.numeric-input :refer [numeric-input]] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -21,10 +22,12 @@ (defn- event-type-names [] {:click (tr "workspace.options.interaction-on-click") - :mouse-over (tr "workspace.options.interaction-while-hovering") - :mouse-press (tr "workspace.options.interaction-while-pressing") + ; TODO: need more UX research + ;; :mouse-over (tr "workspace.options.interaction-while-hovering") + ;; :mouse-press (tr "workspace.options.interaction-while-pressing") :mouse-enter (tr "workspace.options.interaction-mouse-enter") - :mouse-leave (tr "workspace.options.interaction-mouse-leave")}) + :mouse-leave (tr "workspace.options.interaction-mouse-leave") + :after-delay (tr "workspace.options.interaction-after-delay")}) (defn- event-type-name [interaction] @@ -69,6 +72,7 @@ frames (mf/use-memo (mf/deps objects) #(cp/select-frames objects)) + event-type (:event-type interaction) action-type (:action-type interaction) overlay-pos-type (:overlay-pos-type interaction) close-click-outside? (:close-click-outside interaction false) @@ -76,16 +80,25 @@ extended-open? (mf/use-state false) + ext-delay-ref (mf/use-ref nil) + + select-text + (fn [ref] (fn [_] (dom/select-text! (mf/ref-val ref)))) + change-event-type (fn [event] (let [value (-> event dom/get-target dom/get-value d/read-string)] - (update-interaction index #(cti/set-event-type % value)))) + (update-interaction index #(cti/set-event-type % value shape)))) change-action-type (fn [event] (let [value (-> event dom/get-target dom/get-value d/read-string)] (update-interaction index #(cti/set-action-type % value shape objects)))) + change-delay + (fn [value] + (update-interaction index #(cti/set-delay % value))) + change-destination (fn [event] (let [value (-> event dom/get-target dom/get-value) @@ -114,6 +127,8 @@ [:* [:div.element-set-options-group {:class (dom/classnames :open @extended-open?)} + + ; Summary [:div.element-set-actions-button {:on-click #(swap! extended-open? not)} i/actions] [:div.interactions-summary {:on-click #(swap! extended-open? not)} @@ -121,15 +136,34 @@ [:div.action-summary (action-summary interaction destination)]] [:div.elemen-set-actions {:on-click #(remove-interaction index)} [:div.element-set-actions-button i/minus]] + (when @extended-open? [:div.element-set-content + + ; Trigger select [:div.interactions-element.separator [:span.element-set-subtitle.wide (tr "workspace.options.interaction-trigger")] [:select.input-select {:value (str (:event-type interaction)) :on-change change-event-type} (for [[value name] (event-type-names)] - [:option {:value (str value)} name])]] + [:option {:value (str value) + :disabled (and (= value :after-delay) + (not= (:type shape) :frame))} + name])]] + + ; Delay + (when (= event-type :after-delay) + [:div.interactions-element + [:span.element-set-subtitle.wide (tr "workspace.options.interaction-delay")] + [:div.input-element + [:> numeric-input {:ref ext-delay-ref + :on-click (select-text ext-delay-ref) + :on-change change-delay + :value (:delay interaction)}] + [:span.after (tr "workspace.options.interaction-ms")]]]) + + ; Action select [:div.interactions-element.separator [:span.element-set-subtitle.wide (tr "workspace.options.interaction-action")] [:select.input-select @@ -137,6 +171,8 @@ :on-change change-action-type} (for [[value name] (action-type-names)] [:option {:value (str value)} name])]] + + ; Destination (when (#{:navigate :open-overlay :toggle-overlay :close-overlay} action-type) [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-destination")] @@ -148,9 +184,11 @@ (when (and (not= (:id frame) (:id shape)) ; A frame cannot navigate to itself (not= (:id frame) (:frame-id shape))) ; nor a shape to its container frame [:option {:value (str (:id frame))} (:name frame)]))]]) + (when (or (= action-type :open-overlay) (= action-type :toggle-overlay)) [:* + ; Overlay position (select) [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-position")] [:select.input-select @@ -158,6 +196,8 @@ :on-change change-overlay-pos-type} (for [[value name] (overlay-pos-type-names)] [:option {:value (str value)} name])]] + + ; Overlay position (buttons) [:div.interactions-element.interactions-pos-buttons [:div.element-set-actions-button {:class (dom/classnames :active (= overlay-pos-type :center)) @@ -187,6 +227,8 @@ {:class (dom/classnames :active (= overlay-pos-type :bottom-center)) :on-click #(toggle-overlay-pos-type :bottom-center)} i/position-bottom-center]] + + ; Overlay click outside [:div.interactions-element [:div.input-checkbox [:input {:type "checkbox" @@ -195,6 +237,8 @@ :on-change change-close-click-outside}] [:label {:for (str "close-" index)} (tr "workspace.options.interaction-close-outside")]]] + + ; Overlay background [:div.interactions-element [:div.input-checkbox [:input {:type "checkbox" diff --git a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs index 80a4f0a5e..8641c1726 100644 --- a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs @@ -128,7 +128,7 @@ (connect-to-point orig-shape {:x (+ (:x2 (:selrect orig-shape)) 100) :y (+ (- (:y1 (:selrect orig-shape)) 50) - (* level 32))})) + (/ (* level 32) zoom))})) orig-dx (if (= orig-pos :right) 100 -100) dest-dx (if (= dest-pos :right) 100 -100) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 43b367fea..6dce8ee4d 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2405,6 +2405,10 @@ msgstr "Click the + button to add interactions." msgid "workspace.options.interaction-action" msgstr "Action" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-after-delay" +msgstr "After delay" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-background" msgstr "Add background overlay" @@ -2425,6 +2429,10 @@ msgstr "Close overlay: %s" msgid "workspace.options.interaction-destination" msgstr "Destination" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-delay" +msgstr "Delay" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-mouse-enter" msgstr "Mouse enter" @@ -2433,6 +2441,10 @@ msgstr "Mouse enter" msgid "workspace.options.interaction-mouse-leave" msgstr "Mouse leave" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-ms" +msgstr "ms" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-navigate-to" msgstr "Navigate to" @@ -2443,7 +2455,7 @@ msgstr "Navigate to: %s" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-none" -msgstr "none" +msgstr "(not set)" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-on-click" @@ -2453,6 +2465,10 @@ msgstr "On Click" msgid "workspace.options.interaction-open-overlay" msgstr "Open overlay" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-prev-screen" +msgstr "Previous screen" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-toggle-overlay" msgstr "Toggle overlay" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 62a513061..bb6765b50 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -2288,6 +2288,10 @@ msgstr "Pulsa el botón + para añadir interacciones." msgid "workspace.options.interaction-action" msgstr "Acción" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-after-delay" +msgstr "Tiempo" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-background" msgstr "Añadir sombreado de fondo" @@ -2298,55 +2302,67 @@ msgstr "Cerrar al pulsar fuera" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-close-overlay" -msgstr "Close overlay" +msgstr "Cerrar superposición" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-close-overlay-dest" -msgstr "Close overlay: %s" +msgstr "Cerrar superposición: %s" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-destination" msgstr "Destino" +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-delay" +msgstr "Tiempo" + #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-mouse-enter" -msgstr "Mouse enter" +msgstr "Pasar encima" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-mouse-leave" -msgstr "Mouse leave" +msgstr "Retirar encima" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-ms" +msgstr "ms" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-navigate-to" -msgstr "Navigate to" +msgstr "Navegar a" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-navigate-to-dest" -msgstr "Navigate to: %s" +msgstr "Navegar a: %s" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-none" -msgstr "none" +msgstr "(sin definir)" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-on-click" -msgstr "On Click" +msgstr "En click" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-open-overlay" -msgstr "Open overlay" +msgstr "Superposición" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +msgid "workspace.options.interaction-prev-screen" +msgstr "Pantalla anterior" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-toggle-overlay" -msgstr "Toggle overlay" +msgstr "Alternar superpos." #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-open-overlay-dest" -msgstr "Open overlay: %s" +msgstr "Superposición: %s" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-toggle-overlay-dest" -msgstr "Toggle overlay: %s" +msgstr "Alternar superpos.: %s" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-pos-manual" @@ -2386,19 +2402,19 @@ msgstr "Posición" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-self" -msgstr "self" +msgstr "mismo" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-trigger" -msgstr "Trigger" +msgstr "Disparador" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-while-hovering" -msgstr "While Hovering" +msgstr "Mientras pasa encima" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interaction-while-pressing" -msgstr "While Pressing" +msgstr "Mientras pulsa" #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs msgid "workspace.options.interactions"