From 86e4826e4845a494f869ae24497ce46ebf702c1c Mon Sep 17 00:00:00 2001 From: Eva Date: Fri, 4 Feb 2022 10:32:37 +0100 Subject: [PATCH] :sparkles: Add configurable nudge amount --- CHANGES.md | 1 + .../styles/common/dependencies/colors.scss | 2 +- .../resources/styles/main/partials/modal.scss | 80 +++++++++++++++++++ frontend/src/app/main/data/users.cljs | 14 ++++ .../app/main/data/workspace/transforms.cljs | 3 +- frontend/src/app/main/ui/workspace.cljs | 1 + .../src/app/main/ui/workspace/header.cljs | 5 +- frontend/src/app/main/ui/workspace/nudge.cljs | 62 ++++++++++++++ frontend/translations/en.po | 12 +++ frontend/translations/es.po | 12 +++ 10 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 frontend/src/app/main/ui/workspace/nudge.cljs diff --git a/CHANGES.md b/CHANGES.md index df3edd087a..da63fa5a07 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ ### :sparkles: New features +- Add configurable nudge amount [Taiga #910](https://tree.taiga.io/project/penpot/us/910) - Add stroke properties for image shapes [Taiga #497](https://tree.taiga.io/project/penpot/us/497) - On user settings, hide the theme selector as long as we only have one theme [Taiga #2610](https://tree.taiga.io/project/penpot/us/2610) - Automatically open comments from dashboard notifications [Taiga #2605](https://tree.taiga.io/project/penpot/us/2605) diff --git a/frontend/resources/styles/common/dependencies/colors.scss b/frontend/resources/styles/common/dependencies/colors.scss index 57b538061d..8ca5bbb8a7 100644 --- a/frontend/resources/styles/common/dependencies/colors.scss +++ b/frontend/resources/styles/common/dependencies/colors.scss @@ -15,7 +15,7 @@ $color-dashboard: #f6f6f6; $color-primary: #31efb8; // Secondary colors -$color-success: #58c35c; +$color-success: #49d793; $color-complete: #a599c6; $color-warning: #fc8802; $color-danger: #e65244; diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss index e48eb161d3..44ebe2550b 100644 --- a/frontend/resources/styles/main/partials/modal.scss +++ b/frontend/resources/styles/main/partials/modal.scss @@ -1226,3 +1226,83 @@ background-color: rgba(0, 0, 0, 0.9); } } + +// Nudge modal + +.nudge-modal-overlay { + display: flex; + align-items: center; + justify-content: center; + position: fixed; + left: calc(50vw - 107px); + top: calc(50vh - 57px); + height: 110px; + width: 215px; + padding: 8px 20px; + background-color: $color-white; + box-shadow: 0px 2px 8px 0px rgb(0 0 0 / 20%); + z-index: 1000; + + &.transparent { + background-color: rgba($color-white, 0); + } + + .nudge-modal-container { + display: flex; + flex-direction: column; + justify-content: space-around; + height: 100%; + width: 100%; + + .nudge-modal-header { + display: flex; + justify-content: space-between; + margin-bottom: 7px; + + .modal-close-button { + display: flex; + justify-content: center; + align-items: center; + background-color: transparent; + border: none; + cursor: pointer; + + svg { + height: 12px; + width: 12px; + transform: rotate(45deg); + } + } + + .nudge-modal-title { + padding: 0; + margin: 0; + color: $color-black; + font-size: $fs12; + } + } + + .nudge-modal-body { + display: flex; + justify-content: space-between; + + .nudge-subtitle { + margin: 0; + } + + input { + width: 72px; + background-color: transparent; + border: none; + border-bottom: 1px solid $color-black; + margin-bottom: 12px; + + &:active, + &:focus, + &:hover { + border-bottom: 1px solid $color-primary; + } + } + } + } +} diff --git a/frontend/src/app/main/data/users.cljs b/frontend/src/app/main/data/users.cljs index fcf19fc542..b4eae4da6c 100644 --- a/frontend/src/app/main/data/users.cljs +++ b/frontend/src/app/main/data/users.cljs @@ -447,6 +447,20 @@ (->> (rp/query :team-users {:team-id team-id}) (rx/map #(partial fetched %))))))) +;; --- Update Nudge + +(defn update-nudge + [value] + (ptk/reify ::update-nudge + ptk/UpdateEvent + (update [_ state] + (update-in state [:profile :props] assoc :nudge value)) + ptk/WatchEvent + (watch [_ _ _] + (let [props {:nudge value}] + (->> (rp/mutation :update-profile-props {:props props}) + (rx/map (constantly (fetch-profile)))))))) + ;; --- EVENT: request-account-deletion (defn request-account-deletion diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 5edec0efb3..559895ddd2 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -606,13 +606,14 @@ (watch [_ state stream] (if (= same-event (get-in state [:workspace-local :current-move-selected])) (let [selected (wsh/lookup-selected state {:omit-blocked? true}) + nudge (get-in state [:profile :props :nudge] {:big 10 :small 1}) move-events (->> stream (rx/filter (ptk/type? ::move-selected)) (rx/filter #(= direction (deref %)))) stopper (->> move-events (rx/debounce 100) (rx/first)) - scale (if shift? (gpt/point 10) (gpt/point 1)) + scale (if shift? (gpt/point (:big nudge)) (gpt/point (:small nudge))) mov-vec (gpt/multiply (get-displacement direction) scale)] (rx/concat diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 88d74fbfd9..e9d06b920b 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -21,6 +21,7 @@ [app.main.ui.workspace.header :refer [header]] [app.main.ui.workspace.left-toolbar :refer [left-toolbar]] [app.main.ui.workspace.libraries] + [app.main.ui.workspace.nudge] [app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] [app.main.ui.workspace.textpalette :refer [textpalette]] [app.main.ui.workspace.viewport :refer [viewport]] diff --git a/frontend/src/app/main/ui/workspace/header.cljs b/frontend/src/app/main/ui/workspace/header.cljs index 038143f176..17a40500d9 100644 --- a/frontend/src/app/main/ui/workspace/header.cljs +++ b/frontend/src/app/main/ui/workspace/header.cljs @@ -353,7 +353,10 @@ (if (contains? layout :dynamic-alignment) (tr "workspace.header.menu.disable-dynamic-alignment") (tr "workspace.header.menu.enable-dynamic-alignment"))] - [:span.shortcut (sc/get-tooltip :toggle-alignment)]]]]])) + [:span.shortcut (sc/get-tooltip :toggle-alignment)]] + + [:li {:on-click #(st/emit! (modal/show {:type :nudge-option}))} + [:span (tr "modals.nudge-title")]]]]])) ;; --- Header Component diff --git a/frontend/src/app/main/ui/workspace/nudge.cljs b/frontend/src/app/main/ui/workspace/nudge.cljs new file mode 100644 index 0000000000..c479a00bac --- /dev/null +++ b/frontend/src/app/main/ui/workspace/nudge.cljs @@ -0,0 +1,62 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.main.ui.workspace.nudge + (:require + [app.main.data.modal :as modal] + [app.main.data.users :as du] + [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]] + [app.util.keyboard :as k] + [goog.events :as events] + [rumext.alpha :as mf]) + (:import goog.events.EventType)) + + +(mf/defc nudge-modal + {::mf/register modal/components + ::mf/register-as :nudge-option} + [] + (let [profile (mf/deref refs/profile) + nudge (get-in profile [:props :nudge] {:big 10 :small 1}) + update-nudge (fn [value size] (let [update-nudge (if (= :big size) + {:big value :small (:small nudge)} + {:small value :big (:big nudge)})] + (st/emit! (du/update-nudge update-nudge)))) + update-big (fn [value] (update-nudge value :big)) + update-small (fn [value] (update-nudge value :small)) + close #(modal/hide!)] + (mf/with-effect + (letfn [(on-keydown [event] + (when (k/enter? event) + (dom/prevent-default event) + (dom/stop-propagation event) + (close)))] + (->> (events/listen js/document EventType.KEYDOWN on-keydown) + (partial events/unlistenByKey)))) + + [:div.nudge-modal-overlay + [:div.nudge-modal-container + [:div.nudge-modal-header + [:p.nudge-modal-title (tr "modals.nudge-title")] + [:button.modal-close-button {:on-click close} i/close]] + [:div.nudge-modal-body + [:div.input-wrapper + [:span + [:p.nudge-subtitle (tr "modals.small-nudge")] + [:> numeric-input {:min 1 + :value (:small nudge) + :on-change update-small}]]] + [:div.input-wrapper + [:span + [:p.nudge-subtitle (tr "modals.big-nudge")] + [:> numeric-input {:min 1 + :value (:big nudge) + :on-change update-big}]]]]]])) \ No newline at end of file diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 7dbf326b7e..4cd2704dc9 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1580,6 +1580,18 @@ msgstr "Update a component in a shared library" msgid "modals.update-remote-component-in-bulk.message" msgstr "Update components in a shared library" +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.nudge-title" +msgstr "Nudge amount" + +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.small-nudge" +msgstr "Small nudge" + +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.big-nudge" +msgstr "Big nudge" + #: src/app/main/ui/dashboard/team.cljs msgid "notifications.invitation-email-sent" msgstr "Invitation sent successfully" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index ba784e4056..76bac95871 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -1582,6 +1582,18 @@ msgstr "Actualizar un componente en librería" msgid "modals.update-remote-component-in-bulk.message" msgstr "Actualizar componentes en librería" +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.nudge-title" +msgstr "Desplazamiento" + +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.small-nudge" +msgstr "Mínimo" + +#: src/app/main/ui/workspace/nudge.cljs +msgid "modals.big-nudge" +msgstr "Máximo" + #: src/app/main/ui/dashboard/team.cljs msgid "notifications.invitation-email-sent" msgstr "Invitación enviada con éxito"