From 8c3c9a8ca4f8dbc2418d68b5dea3d44edd3069a8 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 31 Jan 2022 17:50:33 +0100 Subject: [PATCH] :sparkles: Refactor workspace header --- CHANGES.md | 1 + .../styles/main/partials/sidebar.scss | 52 +++++++++++------- .../main/partials/workspace-header.scss | 51 ++++++++++++++++-- .../app/main/data/workspace/shortcuts.cljs | 12 +++-- frontend/src/app/main/refs.cljs | 3 ++ frontend/src/app/main/ui/hooks/resize.cljs | 13 +++-- frontend/src/app/main/ui/workspace.cljs | 13 +++-- .../app/main/ui/workspace/colorpalette.cljs | 2 +- .../app/main/ui/workspace/context_menu.cljs | 13 +++-- .../src/app/main/ui/workspace/header.cljs | 53 +++++++++++-------- .../src/app/main/ui/workspace/sidebar.cljs | 39 ++++++++------ .../main/ui/workspace/sidebar/sitemap.cljs | 7 ++- .../ui/workspace/viewport/scroll_bars.cljs | 26 ++++++--- frontend/translations/en.po | 5 +- frontend/translations/es.po | 5 +- 15 files changed, 207 insertions(+), 88 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8f5fb32ed..df9e39e4c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ - Improve file menu by adding semantically groups [Github #1203](https://github.com/penpot/penpot/issues/1203) - Add update components in bulk option in context menu [Taiga #1975](https://tree.taiga.io/project/penpot/us/1975) - Create first E2E tests [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608), [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608) +- Refactor of workspace toolbars [Taiga #2319](https://tree.taiga.io/project/penpot/us/2319) ### :bug: Bugs fixed ### :arrow_up: Deps updates diff --git a/frontend/resources/styles/main/partials/sidebar.scss b/frontend/resources/styles/main/partials/sidebar.scss index dcb069feb..b76009325 100644 --- a/frontend/resources/styles/main/partials/sidebar.scss +++ b/frontend/resources/styles/main/partials/sidebar.scss @@ -17,23 +17,6 @@ & .tab-container-tabs { padding-left: 1.5rem; } - - & button.collapse-sidebar { - background: none; - border: none; - cursor: pointer; - height: 2.5rem; - padding-top: 0.75rem; - position: absolute; - width: 1rem; - - & svg { - width: 12px; - height: 12px; - fill: $color-gray-20; - transform: rotate(180deg); - } - } } .settings-bar-inside { @@ -181,7 +164,7 @@ } &.settings-bar-right > .resize-area { - left: -8px; + left: -4px; } } @@ -243,3 +226,36 @@ width: 100%; } } + +button.collapse-sidebar { + background: none; + border: none; + cursor: pointer; + height: 2.5rem; + padding-top: 0.75rem; + position: absolute; + width: 1rem; + + & svg { + width: 12px; + height: 12px; + fill: $color-gray-20; + transform: rotate(180deg); + } + + &.collapsed { + background: $color-black; + left: 48px; + top: 48px; + width: 18px; + height: 24px; + padding: 0; + border-radius: 0px 4px 4px 0px; + + & svg { + width: 8px; + height: 8px; + transform: rotate(0deg); + } + } +} diff --git a/frontend/resources/styles/main/partials/workspace-header.scss b/frontend/resources/styles/main/partials/workspace-header.scss index 691ee2c6d..f2e20d65d 100644 --- a/frontend/resources/styles/main/partials/workspace-header.scss +++ b/frontend/resources/styles/main/partials/workspace-header.scss @@ -13,6 +13,28 @@ padding: $size-1 $size-4 $size-1 55px; justify-content: space-between; + display: grid; + grid-template-areas: "left center right"; + grid-template-columns: auto 1fr auto; + grid-template-rows: 100%; + padding: 0; + + .left-area { + grid-area: left; + display: flex; + height: 100%; + } + + .center-area { + grid-area: center; + } + + .right-area { + grid-area: right; + display: flex; + height: 100%; + } + .main-icon { align-items: center; background-color: $color-gray-60; @@ -21,9 +43,6 @@ display: flex; height: 100%; justify-content: center; - left: 0; - position: absolute; - top: 0; width: 48px; a { @@ -44,6 +63,7 @@ } .menu-section { + margin-left: 1rem; display: flex; justify-content: flex-start; align-items: center; @@ -73,6 +93,8 @@ justify-content: flex-end; align-items: center; position: relative; + padding-right: 1rem; + border-right: 1px solid black; > * { margin-left: $size-5; @@ -216,7 +238,8 @@ } .active-users { - align-items: center; + flex: 1; + justify-content: center; display: flex; margin: 0; @@ -233,6 +256,26 @@ } } } + + & button.document-history { + background: $color-gray-60; + border-radius: 3px; + border: none; + cursor: pointer; + height: 24px; + padding: 3px; + width: 24px; + + & svg { + width: 18px; + fill: $color-gray-20; + height: 18px; + } + + &.selected svg { + fill: $color-primary; + } + } } .persistence-status-widget { diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index 7c6cc2212..eafc00e19 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -338,9 +338,15 @@ :command (ds/c-mod "alt+l") :fn #(st/emit! (dw/toggle-proportion-lock))} - :create-artboard-from-selection {:tooltip (ds/meta (ds/alt "G")) - :command (ds/c-mod "alt+g") - :fn #(st/emit! (dw/create-artboard-from-selection))}}) + :create-artboard-from-selection {:tooltip (ds/meta (ds/alt "G")) + :command (ds/c-mod "alt+g") + :fn #(st/emit! (dw/create-artboard-from-selection))} + + :hide-ui {:tooltip "\\" + :command "\\" + :fn #(st/emit! (dw/toggle-layout-flags :hide-ui))} + + }) (def opacity-shortcuts (into {} (->> diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index c2efd50d8..7478edc3f 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -167,6 +167,9 @@ (def workspace-layout (l/derived :workspace-layout st/state)) +(def current-file-id + (l/derived :current-file-id st/state)) + (def workspace-file (l/derived (fn [state] (let [file (:workspace-file state) diff --git a/frontend/src/app/main/ui/hooks/resize.cljs b/frontend/src/app/main/ui/hooks/resize.cljs index 79b8600e1..b4ba927be 100644 --- a/frontend/src/app/main/ui/hooks/resize.cljs +++ b/frontend/src/app/main/ui/hooks/resize.cljs @@ -8,7 +8,9 @@ (:require [app.common.geom.point :as gpt] [app.common.logging :as log] + [app.main.refs :as refs] [app.util.dom :as dom] + [app.util.storage :refer [storage]] [rumext.alpha :as mf])) (log/set-level! :warn) @@ -19,8 +21,10 @@ (set! last-resize-type type)) (defn use-resize-hook - [initial min-val max-val axis negate? resize-type] - (let [size-state (mf/use-state initial) + [key initial min-val max-val axis negate? resize-type] + + (let [current-file-id (mf/deref refs/current-file-id) + size-state (mf/use-state (or (get-in @storage [::saved-resize current-file-id key]) initial)) parent-ref (mf/use-ref nil) dragging-ref (mf/use-ref false) @@ -54,7 +58,8 @@ start-size (mf/ref-val start-size-ref) new-size (-> (+ start-size delta) (max min-val) (min max-val))] - (reset! size-state new-size))))] + (reset! size-state new-size) + (swap! storage assoc-in [::saved-resize current-file-id key] new-size))))] {:on-pointer-down on-pointer-down :on-lost-pointer-capture on-lost-pointer-capture :on-mouse-move on-mouse-move @@ -86,7 +91,7 @@ (let [size (dom/get-client-size node)] (when callback (callback last-resize-type size)))))] (mf/set-ref-val! current-observer-ref observer) - (log/debug :action "observe" :js/node node) + (log/debug :action "observe" :js/node node :js/observer observer) (.observe observer node)))) (mf/set-ref-val! prev-val-ref node)))] diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index b8ba83f55..eba5fe8d2 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -26,6 +26,7 @@ [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.object :as obj] + [debug :refer [debug?]] [okulary.core :as l] [rumext.alpha :as mf])) @@ -44,6 +45,7 @@ on-resize (mf/use-callback + (mf/deps (:vport local)) (fn [resize-type size] (when (:vport local) (st/emit! (dw/update-viewport-size resize-type size))))) @@ -54,7 +56,8 @@ [:section.workspace-content {:ref node-ref} [:section.workspace-viewport - [:& coordinates/coordinates {:colorpalette? colorpalette?}] + (when (debug? :coordinates) + [:& coordinates/coordinates {:colorpalette? colorpalette?}]) [:& viewport {:file file :local local @@ -64,9 +67,13 @@ (when-not (:hide-ui layout) [:* [:& left-toolbar {:layout layout}] - [:& left-sidebar {:layout layout}] + (if (:collapse-left-sidebar layout) + [:button.collapse-sidebar.collapsed {:on-click #(st/emit! (dw/toggle-layout-flags :collapse-left-sidebar))} + i/arrow-slide] + [:& left-sidebar {:layout layout}]) [:& right-sidebar {:section options-mode - :selected selected}]])])) + :selected selected + :layout layout}]])])) (def trimmed-page-ref (l/derived :trimmed-page st/state =)) diff --git a/frontend/src/app/main/ui/workspace/colorpalette.cljs b/frontend/src/app/main/ui/workspace/colorpalette.cljs index 45efa13f1..40383d526 100644 --- a/frontend/src/app/main/ui/workspace/colorpalette.cljs +++ b/frontend/src/app/main/ui/workspace/colorpalette.cljs @@ -66,7 +66,7 @@ container (mf/use-ref nil) {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} - (use-resize-hook 72 54 80 :y true :bottom) + (use-resize-hook :palette 72 54 80 :y true :bottom) on-left-arrow-click (mf/use-callback diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 0406b9dfb..5f07b7dc9 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -436,10 +436,15 @@ (mf/defc viewport-context-menu [] - (let [do-paste (st/emitf dw/paste)] - [:& menu-entry {:title (tr "workspace.shape.menu.paste") - :shortcut (sc/get-tooltip :paste) - :on-click do-paste}])) + (let [do-paste (st/emitf dw/paste) + do-hide-ui (st/emitf (dw/toggle-layout-flags :hide-ui))] + [:* + [:& menu-entry {:title (tr "workspace.shape.menu.paste") + :shortcut (sc/get-tooltip :paste) + :on-click do-paste}] + [:& menu-entry {:title (tr "workspace.shape.menu.hide-ui") + :shortcut (sc/get-tooltip :hide-ui) + :on-click do-hide-ui}]])) (mf/defc context-menu [] diff --git a/frontend/src/app/main/ui/workspace/header.cljs b/frontend/src/app/main/ui/workspace/header.cljs index f400f2f7b..7e9129ce9 100644 --- a/frontend/src/app/main/ui/workspace/header.cljs +++ b/frontend/src/app/main/ui/workspace/header.cljs @@ -360,31 +360,40 @@ (st/emitf (dw/go-to-viewer params)))] [:header.workspace-header - [:div.main-icon - [:a {:on-click go-back} i/logo-icon]] + [:div.left-area + [:div.main-icon + [:a {:on-click go-back} i/logo-icon]] - [:& menu {:layout layout - :project project - :file file - :team-id team-id - :page-id page-id}] + [:& menu {:layout layout + :project project + :file file + :team-id team-id + :page-id page-id}]] - [:div.users-section - [:& active-sessions]] + [:div.center-area + [:div.users-section + [:& active-sessions]]] - [:div.options-section - [:& persistence-state-widget] + [:div.right-area + [:div.options-section + [:& persistence-state-widget] + [:button.document-history + {:alt (tr "workspace.sidebar.history" (sc/get-tooltip :toggle-history)) + :class (when (contains? layout :document-history) "selected") + :on-click (st/emitf (dw/toggle-layout-flags :document-history))} + i/recent]] - [:& zoom-widget-workspace - {:zoom zoom - :on-increase #(st/emit! (dw/increase-zoom nil)) - :on-decrease #(st/emit! (dw/decrease-zoom nil)) - :on-zoom-reset #(st/emit! dw/reset-zoom) - :on-zoom-fit #(st/emit! dw/zoom-to-fit-all) - :on-zoom-selected #(st/emit! dw/zoom-to-selected-shape)}] + [:div.options-section + [:& zoom-widget-workspace + {:zoom zoom + :on-increase #(st/emit! (dw/increase-zoom nil)) + :on-decrease #(st/emit! (dw/decrease-zoom nil)) + :on-zoom-reset #(st/emit! dw/reset-zoom) + :on-zoom-fit #(st/emit! dw/zoom-to-fit-all) + :on-zoom-selected #(st/emit! dw/zoom-to-selected-shape)}] - [:a.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left - {:alt (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) - :on-click go-viewer} - i/play]]])) + [:a.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left + {:alt (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) + :on-click go-viewer} + i/play]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index dec3a6feb..3c506f61e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -6,21 +6,20 @@ (ns app.main.ui.workspace.sidebar (:require - [app.main.ui.components.tab-container :refer [tab-container tab-element]] [app.main.data.workspace :as dw] [app.main.refs :as refs] + [app.main.store :as st] + [app.main.ui.components.tab-container :refer [tab-container tab-element]] [app.main.ui.hooks.resize :refer [use-resize-hook]] + [app.main.ui.icons :as i] [app.main.ui.workspace.comments :refer [comments-sidebar]] [app.main.ui.workspace.sidebar.assets :refer [assets-toolbox]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox]] [app.main.ui.workspace.sidebar.layers :refer [layers-toolbox]] [app.main.ui.workspace.sidebar.options :refer [options-toolbox]] [app.main.ui.workspace.sidebar.sitemap :refer [sitemap]] - [cuerdas.core :as str] - [rumext.alpha :as mf] - [app.main.store :as st] - [app.main.ui.icons :as i] - )) + [app.util.object :as obj] + [rumext.alpha :as mf])) ;; --- Left Sidebar (Component) @@ -31,7 +30,11 @@ (contains? layout :assets) :assets) {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} - (use-resize-hook 255 255 500 :x false :left)] + (use-resize-hook :left-sidebar 255 255 500 :x false :left) + + handle-collapse + (fn [] + (st/emit! (dw/toggle-layout-flags :collapse-left-sidebar)))] [:aside.settings-bar.settings-bar-left {:ref parent-ref :style #js {"--width" (str size "px")}} @@ -39,9 +42,10 @@ :on-lost-pointer-capture on-lost-pointer-capture :on-mouse-move on-mouse-move}] - [:div.settings-bar-inside - [:button.collapse-sidebar i/arrow-slide] + [:button.collapse-sidebar + {:on-click handle-collapse} + i/arrow-slide] [:& tab-container {:on-change-tab #(st/emit! (dw/go-to-layout %)) :selected section} @@ -50,9 +54,7 @@ [:& layers-toolbox]] [:& tab-element {:id :assets :title "Library"} - [:& assets-toolbox]]]] - - ])) + [:& assets-toolbox]]]]])) ;; --- Right Sidebar (Component) @@ -60,8 +62,9 @@ {::mf/wrap-props false ::mf/wrap [mf/memo]} [props] - (let [{:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} - (use-resize-hook 255 255 500 :x true :right) + (let [layout (obj/get props "layout") + {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} + (use-resize-hook :right-sidebar 255 255 500 :x true :right) drawing-tool (:tool (mf/deref refs/workspace-drawing))] [:aside.settings-bar.settings-bar-right {:ref parent-ref @@ -70,7 +73,13 @@ :on-lost-pointer-capture on-lost-pointer-capture :on-mouse-move on-mouse-move}] [:div.settings-bar-inside - (if (= drawing-tool :comments) + (cond + (= drawing-tool :comments) [:& comments-sidebar] + + (contains? layout :document-history) + [:& history-toolbox] + + :else [:> options-toolbox props])]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index a08eee391..e60ef6601 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -14,15 +14,14 @@ [app.main.ui.components.context-menu :refer [context-menu]] [app.main.ui.context :as ctx] [app.main.ui.hooks :as hooks] + [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] [cuerdas.core :as str] [okulary.core :as l] - [rumext.alpha :as mf] - [app.main.ui.hooks.resize :refer [use-resize-hook]] - )) + [rumext.alpha :as mf])) ;; --- Page Item @@ -208,7 +207,7 @@ show-pages? (mf/use-state true) {:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]} - (use-resize-hook 200 38 400 :y false nil) + (use-resize-hook :sitemap 200 38 400 :y false nil) toggle-pages (mf/use-callback #(reset! show-pages? not))] diff --git a/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs b/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs index be47a40cf..70aa9746c 100644 --- a/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/scroll_bars.cljs @@ -15,6 +15,16 @@ [app.util.dom :as dom] [rumext.alpha :as mf])) +(def scroll-x 10) +(def scroll-y 10) +(def scroll-height (+ scroll-x 4)) +(def scroll-width (+ scroll-y 4)) +(def other-x 26) +(def other-y 26) +(def other-width 100) +(def other-height 100) + + (mf/defc viewport-scrollbars {::mf/wrap [mf/memo]} [{:keys [objects viewport-ref zoom vbox]}] @@ -49,8 +59,8 @@ (gsh/selection-rect shapes)))) inv-zoom (/ 1 zoom) - vbox-height (- (:height vbox) (* inv-zoom 44)) - vbox-width (- (:width vbox) (* inv-zoom 34)) + vbox-height (- (:height vbox) (* inv-zoom scroll-height)) + vbox-width (- (:width vbox) (* inv-zoom scroll-width)) ;; top space hidden because of the scroll top-offset (-> (- vbox-y (:y base-objects-rect)) @@ -78,28 +88,28 @@ show-v-scroll? (or @v-scrolling? (> top-offset 0) (> bottom-offset 0)) show-h-scroll? (or @h-scrolling? (> left-offset 0) (> right-offset 0)) - v-scrollbar-x (+ vbox-x (:width vbox) (* inv-zoom -32)) + v-scrollbar-x (+ vbox-x (:width vbox) (* inv-zoom (- scroll-x))) v-scrollbar-y (+ vbox-y top-offset) h-scrollbar-x (+ vbox-x left-offset) - h-scrollbar-y (+ vbox-y (:height vbox) (* inv-zoom -40)) + h-scrollbar-y (+ vbox-y (:height vbox) (* inv-zoom (- scroll-y))) scrollbar-height (-> (- (+ vbox-y vbox-height) bottom-offset v-scrollbar-y)) scrollbar-height (-> (cond @v-scrolling? scrollbar-height-stored :else scrollbar-height) - (max (* inv-zoom 100))) + (max (* inv-zoom other-height))) scrollbar-width (-> (- (+ vbox-x vbox-width) right-offset h-scrollbar-x)) scrollbar-width (-> (cond @h-scrolling? scrollbar-width-stored :else scrollbar-width) - (max (* inv-zoom 100))) + (max (* inv-zoom other-width))) v-scrollbar-y (-> (cond @v-scrolling? (- v-scrollbar-y-stored (- (- vbox-y (mf/ref-val vbox-y-ref)))) :else v-scrollbar-y) - (max (+ vbox-y (* inv-zoom 26)))) + (max (+ vbox-y (* inv-zoom other-y)))) v-scrollbar-y (if (> (+ v-scrollbar-y scrollbar-height) (+ vbox-y vbox-height)) ;; the scroll bar is stick to the bottom (-> (+ vbox-y vbox-height) @@ -109,7 +119,7 @@ h-scrollbar-x (-> (cond @h-scrolling? (- h-scrollbar-x-stored (- (- vbox-x (mf/ref-val vbox-x-ref)))) :else h-scrollbar-x) - (max (+ vbox-x (* inv-zoom 26)))) + (max (+ vbox-x (* inv-zoom other-x)))) h-scrollbar-x (if (> (+ h-scrollbar-x scrollbar-width) (+ vbox-x vbox-width)) ;; the scroll bar is stick to the right (-> (+ vbox-x vbox-width) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 1f575ac6e..7d62a8244 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -3430,4 +3430,7 @@ msgid "workspace.updates.update" msgstr "Update" msgid "workspace.viewport.click-to-close-path" -msgstr "Click to close the path" \ No newline at end of file +msgstr "Click to close the path" + +msgid "workspace.shape.menu.hide-ui" +msgstr "Show/Hide UI" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 477b30094..512bae548 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -3443,4 +3443,7 @@ msgid "workspace.updates.update" msgstr "Actualizar" msgid "workspace.viewport.click-to-close-path" -msgstr "Pulsar para cerrar la ruta" \ No newline at end of file +msgstr "Pulsar para cerrar la ruta" + +msgid "workspace.shape.menu.hide-ui" +msgstr "Mostrar/Ocultar Interfaz"