Enhance: Left sidebar (#9880)

* wip: right sidebar

* fix: graph height

* re-enable scrolling on list

* style: indentation

* fix: always expand block when added to sidebar

* fix: show close button on mobile

* wip: right sidebar

* support default and custom icons

* fix whiteboard icon

* fix: header overflow

* remove unneeded dependency

* fix graph icon

* add middle click action and context menu

* add more context menu actions

* add reordering support

* fix dropdown visibility

* dnd fixes and initial state

* varous fixes

* fix event propagation

* enhance accesibility

* area expanded fix

* add translations

* refactoring

* enhance performance

* enhance text overflow

* fix page link

* drag enter fix

* add rounded corners and transition

* add keyboard shortcuts icon

* revert left sidebar change

* left sidebar bg and border

* various left sidebar enhancements

* alignment fixes

* split favorites and recents scrolling

* handle unavailable icon

* handle overflow edge case

* fix and refactor menu shortcuts

* handle zero items

* display nan shortcuts on mouse over

* min height fix

* min height fix

* simplify chevron icon

* minor fixes

* add flashcards shortcut

* revert initial sidebar state changes

* cloud icon fix

* fix border radius

* add missing go-home shortcut

* add clear recent button

* fix typo

* hide scrollbars

* remove transition

* fix: favorites

* fix: border and rounded corners

* fix: dnd delay

* Revert "add clear recent button"

This reverts commit d8c52c35f0.

* fix: keyboard shortcuts

* fix: shortcuts

* remove unused require
pull/10036/head
Konstantinos 2023-08-16 18:39:29 +03:00 committed by GitHub
parent 5cd3bec911
commit caf1d9d1e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 275 additions and 268 deletions

View File

@ -521,6 +521,30 @@
}
}
.color-level-1 {
background-color: var(--color-level-1);
}
.color-level-2 {
background-color: var(--color-level-2);
}
.color-level-3 {
background-color: var(--color-level-3);
}
.color-level-4 {
background-color: var(--color-level-4);
}
.color-level-5 {
background-color: var(--color-level-5);
}
.color-level-6 {
background-color: var(--color-level-6);
}
.bullet-container {
display: flex;
height: 16px;

View File

@ -9,7 +9,6 @@
[frontend.components.repo :as repo]
[frontend.components.right-sidebar :as right-sidebar]
[frontend.components.select :as select]
[frontend.components.svg :as svg]
[frontend.components.theme :as theme]
[frontend.components.widgets :as widgets]
[frontend.config :as config]
@ -44,18 +43,22 @@
[rum.core :as rum]))
(rum/defc nav-content-item < rum/reactive
[name {:keys [class]} child]
[:div.nav-content-item
{:class (util/classnames [class {:is-expand (not (state/sub [:ui/navigation-item-collapsed? class]))}])}
[:div.nav-content-item-inner
[:div.header.items-center.mb-1
{:on-click (fn [^js/MouseEvent _e]
(state/toggle-navigation-item-collapsed! class))}
[:div.font-medium name]
[:span
[:a.more svg/arrow-down-v2]]]
[:div.bd child]]])
[name {:keys [class count]} child]
(let [collapsed? (state/sub [:ui/navigation-item-collapsed? class])
shrink? (and (not collapsed?) (> count 3))
list-item-height 28]
[:div.nav-content-item.mt-3
{:class (util/classnames [class {:is-expand (not collapsed?)
:flex-shrink-0 (not shrink?)
:flex-shrink shrink?}])
:style {:min-height (when-not collapsed? (* (min count 4) list-item-height))}}
[:div.nav-content-item-inner
[:div.header.items-center
{:on-click (fn [^js/MouseEvent _e]
(state/toggle-navigation-item-collapsed! class))}
[:div.font-medium name]
(ui/icon "chevron-left" {:class "more"})]
(when child [:div.bd child])]]))
(defn- delta-y
[e]
@ -88,7 +91,7 @@
(if whiteboard-page?
(route-handler/redirect-to-whiteboard! name)
(route-handler/redirect-to-page! name {:click-from-recent? recent?})))))}
[:span.page-icon (if whiteboard-page? (ui/icon "whiteboard" {:extension? true}) icon)]
[:span.page-icon.ml-3.justify-center (if whiteboard-page? (ui/icon "whiteboard" {:extension? true}) icon)]
[:span.page-title {:class (when untitiled? "opacity-50")}
(if untitiled? (t :untitled)
(pdf-utils/fix-local-asset-pagename original-name))]]))
@ -134,45 +137,47 @@
(rum/defc favorites < rum/reactive
[t]
(nav-content-item
[:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
(ui/icon "star" {:size 16})
[:span.flex-1.ml-2 (string/upper-case (t :left-side-bar/nav-favorites))]]
(let [favorites (->> (:favorites (state/sub-config))
(remove string/blank?)
(filter string?))
favorite-entities (->> favorites
(mapv #(db/entity [:block/name (util/safe-page-name-sanity-lc %)]))
(remove nil?))]
(nav-content-item
[:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
(ui/icon "star" {:size 16})
[:span.flex-1.ml-2 (string/upper-case (t :left-side-bar/nav-favorites))]]
{:class "favorites"
:edit-fn
(fn [e]
(rfe/push-state :page {:name "Favorites"})
(util/stop e))}
(let [favorites (->> (:favorites (state/sub-config))
(remove string/blank?)
(filter string?))]
(when (seq favorites)
{:class "favorites"
:count (count favorite-entities)
:edit-fn
(fn [e]
(rfe/push-state :page {:name "Favorites"})
(util/stop e))}
(when (seq favorite-entities)
[:ul.favorites.text-sm
(for [name favorites]
(when-not (string/blank? name)
(when-let [entity (db/entity [:block/name (util/safe-page-name-sanity-lc name)])]
(let [icon (get-page-icon entity)]
(favorite-item t name icon)))))]))))
(for [entity favorite-entities]
(let [icon (get-page-icon entity)]
(favorite-item t (:block/name entity) icon)))]))))
(rum/defc recent-pages < rum/reactive db-mixins/query
[t]
(nav-content-item
[:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
(ui/icon "history" {:size 16})
[:span.flex-1.ml-2
(string/upper-case (t :left-side-bar/nav-recent-pages))]]
(let [pages (->> (db/sub-key-value :recent/pages)
(remove string/blank?)
(filter string?)
(map (fn [page] {:lowercase (util/safe-page-name-sanity-lc page)
:page page}))
(util/distinct-by :lowercase)
(map :page))]
(nav-content-item
[:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
(ui/icon "history" {:size 16})
[:span.flex-1.ml-2
(string/upper-case (t :left-side-bar/nav-recent-pages))]]
{:class "recent"}
{:class "recent"
:count (count pages)}
(let [pages (->> (db/sub-key-value :recent/pages)
(remove string/blank?)
(filter string?)
(map (fn [page] {:lowercase (util/safe-page-name-sanity-lc page)
:page page}))
(util/distinct-by :lowercase)
(map :page))]
[:ul.text-sm
(for [name pages]
(when-let [entity (db/entity [:block/name (util/safe-page-name-sanity-lc name)])]
@ -197,8 +202,9 @@
(state/pub-event! [:modal/show-cards]))}
(ui/icon "infinity")
[:span.flex-1 (t :right-side-bar/flashcards)]
[:span.ml-1 (ui/render-keyboard-shortcut (ui/keyboard-shortcut-from-config :go/flashcards))]
(when (and num (not (zero? num)))
[:span.ml-3.inline-block.py-0.5.px-3.text-xs.font-medium.rounded-full.fade-in num])]))
[:span.ml-1.inline-block.py-0.5.px-3.text-xs.font-medium.rounded-full.fade-in num])]))
(defn get-default-home-if-valid
[]
@ -212,13 +218,7 @@
(dissoc default-home :page)))))
(defn sidebar-item
[{on-click-handler :on-click-handler
class :class
title :title
icon :icon
icon-extension? :icon-extension?
active :active
href :href}]
[{:keys [on-click-handler class title icon icon-extension? active href shortcut]}]
[:div
{:class class}
[:a.item.group.flex.items-center.text-sm.font-medium.rounded-md
@ -226,7 +226,9 @@
:class (when active "active")
:href href}
(ui/icon (str icon) {:extension? icon-extension?})
[:span.flex-1 title]]])
[:span.flex-1 title]
(when shortcut
[:span.ml-1 (ui/render-keyboard-shortcut (ui/keyboard-shortcut-from-config shortcut))])]])
(defn close-sidebar-on-mobile!
[]
@ -245,17 +247,17 @@
(->>
[{:title (t :left-side-bar/new-page)
:class "new-page-link"
:shortcut (ui/keyboard-shortcut-from-config :go/search)
:options {:on-click #(do (close-sidebar-on-mobile!)
(state/pub-event! [:go/search]))}
(state/pub-event! [:go/search]))
:shortcut (ui/keyboard-shortcut-from-config :go/search)}
:icon (ui/type-icon {:name "new-page"
:class "highlight"
:extension? true})}
{:title (t :left-side-bar/new-whiteboard)
:class "new-whiteboard-link"
:shortcut (ui/keyboard-shortcut-from-config :editor/new-whiteboard)
:options {:on-click #(do (close-sidebar-on-mobile!)
(whiteboard-handler/create-new-whiteboard-and-redirect!))}
(whiteboard-handler/create-new-whiteboard-and-redirect!))
:shortcut (ui/keyboard-shortcut-from-config :editor/new-whiteboard)}
:icon (ui/type-icon {:name "new-whiteboard"
:class "highlight"
:extension? true})}])
@ -345,55 +347,59 @@
{:aria-label "Navigation menu"}
(repo/repos-dropdown)
[:div.nav-header.flex.gap-1.flex-col
[:div.nav-header.flex.gap-1.flex-col.mt-3
(let [page (:page default-home)]
(if (and page (not (state/enable-journals? (state/get-current-repo))))
(sidebar-item
{:class "home-nav"
:title page
{:class "home-nav"
:title page
:on-click-handler route-handler/redirect-to-home!
:active (and (not srs-open?)
(= route-name :page)
(= page (get-in route-match [:path-params :name])))
:icon "home"})
:active (and (not srs-open?)
(= route-name :page)
(= page (get-in route-match [:path-params :name])))
:icon "home"
:shortcut :go/home})
(sidebar-item
{:class "journals-nav"
:active (and (not srs-open?)
(or (= route-name :all-journals) (= route-name :home)))
:title (t :left-side-bar/journals)
{:class "journals-nav"
:active (and (not srs-open?)
(or (= route-name :all-journals) (= route-name :home)))
:title (t :left-side-bar/journals)
:on-click-handler (fn [e]
(if (gobj/get e "shiftKey")
(route-handler/sidebar-journals!)
(route-handler/go-to-journals!)))
:icon "calendar"})))
:icon "calendar"
:shortcut :go/journals})))
(when enable-whiteboards?
(sidebar-item
{:class "whiteboard"
:title (t :right-side-bar/whiteboards)
:href (rfe/href :whiteboards)
{:class "whiteboard"
:title (t :right-side-bar/whiteboards)
:href (rfe/href :whiteboards)
:on-click-handler (fn [_e] (whiteboard-handler/onboarding-show))
:active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
:icon "whiteboard"
:icon-extension? true}))
:active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
:icon "whiteboard"
:icon-extension? true
:shortcut :go/whiteboards}))
(when (state/enable-flashcards? (state/get-current-repo))
[:div.flashcards-nav
(flashcards srs-open?)])
(sidebar-item
{:class "graph-view-nav"
:title (t :right-side-bar/graph-view)
:href (rfe/href :graph)
{:class "graph-view-nav"
:title (t :right-side-bar/graph-view)
:href (rfe/href :graph)
:active (and (not srs-open?) (= route-name :graph))
:icon "hierarchy"})
:icon "hierarchy"
:shortcut :go/graph-view})
(sidebar-item
{:class "all-pages-nav"
:title (t :right-side-bar/all-pages)
:href (rfe/href :all-pages)
{:class "all-pages-nav"
:title (t :right-side-bar/all-pages)
:href (rfe/href :all-pages)
:active (and (not srs-open?) (= route-name :all-pages))
:icon "files"})]]
:icon "files"})]]
[:div.nav-contents-container.flex.flex-col.gap-1.pt-1
{:on-scroll on-contents-scroll}

View File

@ -83,6 +83,7 @@
overflow-y: auto;
overflow-x: hidden;
background-color: var(--ls-primary-background-color);
border-right: 1px solid var(--ls-tertiary-background-color);
transition: transform .3s;
transform: translate3d(-100%, 0, 0);
z-index: 3;
@ -116,14 +117,26 @@
}
}
.nav-header a {
.keyboard-shortcut {
@apply w-0 opacity-0;
transition: opacity 0.3s;
}
&:hover {
.keyboard-shortcut {
width: auto;
opacity: 1;
}
}
}
.page-icon {
@apply flex items-center mr-1 align-baseline;
@apply flex items-center text-center mr-1 align-baseline;
width: 20px;
flex-shrink: 0;
height: 18px;
text-align: center;
display: inline-block;
line-height: 1em;
}
@ -134,28 +147,33 @@
transition: background-color .3s;
.ui__icon {
@apply flex justify-center;
width: 20px;
text-align: center;
font-size: 16px;
margin-right: 8px;
opacity: .9;
opacity: .7;
position: relative;
}
&:hover {
background-color: var(--ls-tertiary-background-color);
.ui__icon {
opacity: .9;
}
}
&.active, &:active {
background-color: var(--ls-quaternary-background-color);
.ui__icon {
opacity: .9;
}
}
}
.nav-contents-container {
@apply h-full flex-grow-0 flex-grow-0
overflow-x-hidden overflow-y-auto;
padding-bottom: 60px;
@apply h-full flex-grow-0 overflow-x-hidden overflow-y-auto;
&.is-scrolled {
border-top: 1px solid var(--ls-tertiary-border-color);
@ -163,8 +181,18 @@
}
.nav-content-item {
&-inner {
border-radius: 8px;
@apply overflow-hidden;
&:not(:hover) {
::-webkit-scrollbar-thumb,
::-webkit-scrollbar,
::-webkit-scrollbar-thumb:active {
background-color: transparent;
}
}
.nav-content-item-inner {
@apply flex flex-col h-full overflow-hidden;
}
.header {
@ -175,18 +203,18 @@
user-select: none;
cursor: pointer;
> span {
> a {
padding-left: 12px;
display: none;
transition: none;
.ui__icon {
@apply flex justify-center;
width: 20px;
}
&:last-child {
transform: translateY(-6px) translateX(2px) rotate(90deg);
transform-origin: center center;
transition: .15s transform;
}
}
a {
opacity: .7;
}
.more {
display: none;
transition: .15s transform;
}
&:hover {
@ -196,15 +224,10 @@
opacity: 1 !important;
}
> span {
> a {
display: block;
.more {
&:last-child {
display: block;
opacity: .6;
}
}
display: block;
opacity: .6;
}
}
@ -217,7 +240,10 @@
}
.bd {
@apply py-1 overflow-y-auto;
display: none;
min-height: 40px;
ul {
list-style: none;
@ -231,7 +257,8 @@
a {
width: 100%;
padding: 4px 24px;
transition: background-color .3s;
opacity: .8;
transition: background-color .3s, opacity .3s;
.page-title {
white-space: nowrap;
@ -246,6 +273,7 @@
}
&:hover {
opacity: 1;
background-color: var(--ls-quaternary-background-color);
}
}
@ -253,12 +281,9 @@
}
&.is-expand {
.header > span > a {
&:last-child {
transform: translateY(2px) translateX(-3px);
}
.header .more {
transform: rotate(-90deg);
}
.bd {
display: block;
}
@ -266,18 +291,11 @@
}
.create {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 14px;
background-image: linear-gradient(transparent, var(--ls-primary-background-color));
user-select: none;
@screen sm {
background-image: linear-gradient(transparent, var(--ls-secondary-background-color));
}
&-link {
background-color: var(--ls-primary-background-color);
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
@ -304,16 +322,7 @@
&:hover,
&:focus {
border-color: var(--ls-border-color);
background-color: var(--ls-primary-background-color) !important;
}
@screen sm {
background-color: var(--ls-primary-background-color) !important;
&:hover,
&:focus {
background-color: var(--ls-secondary-background-color) !important;
}
background-color: var(--ls-tertiary-background-color) !important;
}
}
}
@ -321,7 +330,6 @@
@screen sm {
padding-top: 0;
width: var(--ls-left-sidebar-width);
background-color: var(--ls-secondary-background-color);
> .wrap {
margin-top: 52px;

View File

@ -43,38 +43,35 @@
(ui/menu-link
{:key "cut"
:on-click #(editor-handler/cut-selection-blocks true)}
(t :editor/cut)
(ui/keyboard-shortcut-from-config :editor/cut))
:on-click #(editor-handler/cut-selection-blocks true)
:shortcut (ui/keyboard-shortcut-from-config :editor/cut)}
(t :editor/cut))
(ui/menu-link
{:key "delete"
:on-click #(do (editor-handler/delete-selection %)
(state/hide-custom-context-menu!))}
(t :editor/delete-selection)
(ui/keyboard-shortcut-from-config :editor/delete))
(state/hide-custom-context-menu!))
:shortcut (ui/keyboard-shortcut-from-config :editor/delete)}
(t :editor/delete-selection))
(ui/menu-link
{:key "copy"
:on-click editor-handler/copy-selection-blocks}
(t :editor/copy)
(ui/keyboard-shortcut-from-config :editor/copy))
:on-click editor-handler/copy-selection-blocks
:shortcut (ui/keyboard-shortcut-from-config :editor/copy)}
(t :editor/copy))
(ui/menu-link
{:key "copy as"
:on-click (fn [_]
(let [block-uuids (editor-handler/get-selected-toplevel-block-uuids)]
(state/set-modal!
#(export/export-blocks block-uuids {:whiteboard? false}))))}
(t :content/copy-export-as)
nil)
(t :content/copy-export-as))
(ui/menu-link
{:key "copy block refs"
:on-click editor-handler/copy-block-refs}
(t :content/copy-block-ref)
nil)
(t :content/copy-block-ref))
(ui/menu-link
{:key "copy block embeds"
:on-click editor-handler/copy-block-embeds}
(t :content/copy-block-emebed)
nil)
(t :content/copy-block-emebed))
[:hr.menu-separator]
@ -82,34 +79,32 @@
(ui/menu-link
{:key "Make a Card"
:on-click #(srs/batch-make-cards!)}
(t :context-menu/make-a-flashcard)
nil))
(t :context-menu/make-a-flashcard)))
(ui/menu-link
{:key "Toggle number list"
:on-click #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
(t :context-menu/toggle-number-list)
nil)
(t :context-menu/toggle-number-list))
(ui/menu-link
{:key "cycle todos"
:on-click editor-handler/cycle-todos!}
(t :editor/cycle-todo)
(ui/keyboard-shortcut-from-config :editor/cycle-todo))
:on-click editor-handler/cycle-todos!
:shortcut (ui/keyboard-shortcut-from-config :editor/cycle-todo)}
(t :editor/cycle-todo))
[:hr.menu-separator]
(ui/menu-link
{:key "Expand all"
:on-click editor-handler/expand-all-selection!}
(t :editor/expand-block-children)
(ui/keyboard-shortcut-from-config :editor/expand-block-children))
:on-click editor-handler/expand-all-selection!
:shortcut (ui/keyboard-shortcut-from-config :editor/expand-block-children)}
(t :editor/expand-block-children))
(ui/menu-link
{:key "Collapse all"
:on-click editor-handler/collapse-all-selection!}
(t :editor/collapse-block-children)
(ui/keyboard-shortcut-from-config :editor/collapse-block-children))])
:on-click editor-handler/collapse-all-selection!
:shortcut (ui/keyboard-shortcut-from-config :editor/collapse-block-children)}
(t :editor/collapse-block-children))])
(defonce *template-including-parent? (atom nil))
@ -168,8 +163,7 @@
:on-click (fn [e]
(util/stop e)
(reset! edit? true))}
(t :context-menu/make-a-template)
nil))))
(t :context-menu/make-a-template)))))
(rum/defc ^:large-vars/cleanup-todo block-context-menu-content <
shortcut/disable-all-shortcuts
@ -190,9 +184,9 @@
(ui/menu-link
{:key "Open in sidebar"
:on-click (fn [_e]
(editor-handler/open-block-in-sidebar! block-id))}
(t :content/open-in-sidebar)
["⇧" "click"])
(editor-handler/open-block-in-sidebar! block-id))
:shortcut ["⇧+click"]}
(t :content/open-in-sidebar))
[:hr.menu-separator]
@ -200,15 +194,13 @@
{:key "Copy block ref"
:on-click (fn [_e]
(editor-handler/copy-block-ref! block-id block-ref/->block-ref))}
(t :content/copy-block-ref)
nil)
(t :content/copy-block-ref))
(ui/menu-link
{:key "Copy block embed"
:on-click (fn [_e]
(editor-handler/copy-block-ref! block-id #(util/format "{{embed ((%s))}}" %)))}
(t :content/copy-block-emebed)
nil)
(t :content/copy-block-emebed))
;; TODO Logseq protocol mobile support
(when (util/electron?)
@ -219,28 +211,26 @@
tap-f (fn [block-id]
(url-util/get-logseq-graph-uuid-url nil current-repo block-id))]
(editor-handler/copy-block-ref! block-id tap-f)))}
(t :content/copy-block-url)
nil))
(t :content/copy-block-url)))
(ui/menu-link
{:key "Copy as"
:on-click (fn [_]
(state/set-modal! #(export/export-blocks [block-id] {:whiteboard? false})))}
(t :content/copy-export-as)
nil)
(t :content/copy-export-as))
(ui/menu-link
{:key "Cut"
:on-click (fn [_e]
(editor-handler/cut-block! block-id))}
(t :editor/cut)
(ui/keyboard-shortcut-from-config :editor/cut))
(editor-handler/cut-block! block-id))
:shortcut (ui/keyboard-shortcut-from-config :editor/cut)}
(t :editor/cut))
(ui/menu-link
{:key "delete"
:on-click #(editor-handler/delete-block-aux! block true)}
(t :editor/delete-selection)
(ui/keyboard-shortcut-from-config :editor/delete))
:on-click #(editor-handler/delete-block-aux! block true)
:shortcut (ui/keyboard-shortcut-from-config :editor/delete)}
(t :editor/delete-selection))
[:hr.menu-separator]
@ -251,38 +241,35 @@
(ui/menu-link
{:key "Preview Card"
:on-click #(srs/preview (:db/id block))}
(t :context-menu/preview-flashcard)
nil)
(t :context-menu/preview-flashcard))
(state/enable-flashcards?)
(ui/menu-link
{:key "Make a Card"
:on-click #(srs/make-block-a-card! block-id)}
(t :context-menu/make-a-flashcard)
nil)
(t :context-menu/make-a-flashcard))
:else
nil)
(ui/menu-link
{:key "Toggle number list"
:on-click #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
(t :context-menu/toggle-number-list)
nil)
(t :context-menu/toggle-number-list))
[:hr.menu-separator]
(ui/menu-link
{:key "Expand all"
:on-click (fn [_e]
(editor-handler/expand-all! block-id))}
(t :editor/expand-block-children)
(ui/keyboard-shortcut-from-config :editor/expand-block-children))
(editor-handler/expand-all! block-id))
:shortcut (ui/keyboard-shortcut-from-config :editor/expand-block-children)}
(t :editor/expand-block-children))
(ui/menu-link
{:key "Collapse all"
:on-click (fn [_e]
(editor-handler/collapse-all! block-id {}))}
(t :editor/collapse-block-children)
(ui/keyboard-shortcut-from-config :editor/collapse-block-children))
(editor-handler/collapse-all! block-id {}))
:shortcut (ui/keyboard-shortcut-from-config :editor/collapse-block-children)}
(t :editor/collapse-block-children))
(when (state/sub [:plugin/simple-commands])
(when-let [cmds (state/get-plugins-commands-with-type :block-context-menu-item)]
@ -291,16 +278,14 @@
{:key key
:on-click #(commands/exec-plugin-simple-command!
pid (assoc cmd :uuid block-id) action)}
label
nil))))
label))))
(when (state/sub [:ui/developer-mode?])
(ui/menu-link
{:key "(Dev) Show block data"
:on-click (fn []
(dev-common-handler/show-entity-data [:block/uuid block-id]))}
(t :dev/show-block-data)
nil))
(t :dev/show-block-data)))
(when (state/sub [:ui/developer-mode?])
(ui/menu-link
@ -308,8 +293,7 @@
:on-click (fn []
(let [block (db/pull [:block/uuid block-id])]
(dev-common-handler/show-content-ast (:block/content block) (:block/format block))))}
(t :dev/show-block-ast)
nil))])))
(t :dev/show-block-ast)))])))
(rum/defc block-ref-custom-context-menu-content
[block block-ref-id]
@ -321,29 +305,25 @@
(state/sidebar-add-block!
(state/get-current-repo)
block-ref-id
:block-ref))}
(t :content/open-in-sidebar)
["⇧" "click"])
:block-ref))
:shortcut ["⇧+click"]}
(t :content/open-in-sidebar))
(ui/menu-link
{:key "copy"
:on-click (fn [] (editor-handler/copy-current-ref block-ref-id))}
(t :content/copy-ref)
nil)
(t :content/copy-ref))
(ui/menu-link
{:key "delete"
:on-click (fn [] (editor-handler/delete-current-ref! block block-ref-id))}
(t :content/delete-ref)
nil)
(t :content/delete-ref))
(ui/menu-link
{:key "replace-with-text"
:on-click (fn [] (editor-handler/replace-ref-with-text! block block-ref-id))}
(t :content/replace-with-text)
nil)
(t :content/replace-with-text))
(ui/menu-link
{:key "replace-with-embed"
:on-click (fn [] (editor-handler/replace-ref-with-embed! block block-ref-id))}
(t :content/replace-with-embed)
nil)]))
(t :content/replace-with-embed))]))
(rum/defc page-title-custom-context-menu-content
[page]
@ -352,7 +332,7 @@
[:.menu-links-wrapper
(for [{:keys [title options]} page-menu-options]
(rum/with-key
(ui/menu-link options title nil)
(ui/menu-link options title)
title))])))
;; TODO: content could be changed

View File

@ -1,7 +1,7 @@
.cp__header {
@apply shadow z-10;
-webkit-app-region: drag;
padding-top: calc(var(--ls-headbar-inner-top-padding));
margin-top: var(--ls-win32-title-bar-height);
height: calc(var(--ls-headbar-height) + var(--ls-headbar-inner-top-padding));
@ -173,18 +173,8 @@
}
#repo-name {
display: table-cell;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 20ch;
height: 14px;
.ui__icon {
position: relative;
top: 5px;
right: -1px;
}
@apply inline-flex items-center whitespace-nowrap;
max-width: 16ch;
}
.button {

View File

@ -5,6 +5,7 @@
[frontend.context.i18n :refer [t]]
[frontend.db :as db]
[frontend.handler.repo :as repo-handler]
[frontend.handler.user :as user-handler]
[frontend.handler.web.nfs :as nfs-handler]
[frontend.state :as state]
[frontend.ui :as ui]
@ -205,6 +206,7 @@
repos (if (and (seq remotes) login?)
(repo-handler/combine-local-&-remote-graphs repos remotes) repos)
links (repos-dropdown-links repos current-repo multiple-windows?)
logged-in? (user-handler/logged-in?)
render-content (fn [{:keys [toggle-fn]}]
(let [remote? (:remote? (first (filter #(= current-repo (:url %)) repos)))
repo-name (db/get-repo-name current-repo)
@ -219,11 +221,16 @@
:title repo-name} ;; show full path on hover
[:span.flex.relative
{:style {:top 1}}
(ui/icon "database" {:size 16 :id "database-icon"})]
(ui/icon (if logged-in?
(let [icon (str "letter-" (first (user-handler/email)))]
(if (ui/tabler-icon icon) icon "user"))
"database") {:size (if logged-in? 12 16)
:id "database-icon"
:class (when logged-in? "p-1 rounded color-level-5")})]
[:div.graphs
[:span#repo-switch.block.pr-2.whitespace-nowrap
[:span [:span#repo-name.font-medium
(if (= config/local-repo short-repo-name) "Demo" short-repo-name)
[:span.overflow-hidden.text-ellipsis (if (= config/local-repo short-repo-name) "Demo" short-repo-name)]
(when remote? [:span.pl-1 (ui/icon "cloud")])]]
[:span.dropdown-caret.ml-2 {:style {:border-top-color "#6b7280"}}]]]]))
links-header (cond->

View File

@ -176,24 +176,24 @@
[db-id idx type collapsed? block-count toggle-fn]
[:.menu-links-wrapper.text-left
{:on-click toggle-fn}
(ui/menu-link {:on-click #(state/sidebar-remove-block! idx)} (t :right-side-bar/pane-close) nil)
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-remove-rest! db-id)} (t :right-side-bar/pane-clese-others) nil))
(ui/menu-link {:on-click #(state/sidebar-remove-block! idx)} (t :right-side-bar/pane-close))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-remove-rest! db-id)} (t :right-side-bar/pane-clese-others)))
(when (> block-count 1) (ui/menu-link {:on-click (fn []
(state/clear-sidebar-blocks!)
(state/hide-right-sidebar!))} (t :right-side-bar/pane-clese-all) nil))
(state/hide-right-sidebar!))} (t :right-side-bar/pane-clese-all)))
(when (or (not collapsed?) (> block-count 1)) [:hr.menu-separator])
(when-not collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} (t :right-side-bar/pane-collapse) nil))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-collapse-rest! db-id)} (t :right-side-bar/pane-collapse-others) nil))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! true)} (t :right-side-bar/pane-collapse-all) nil))
(when-not collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} (t :right-side-bar/pane-collapse)))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-collapse-rest! db-id)} (t :right-side-bar/pane-collapse-others)))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! true)} (t :right-side-bar/pane-collapse-all)))
(when (or collapsed? (> block-count 1)) [:hr.menu-separator])
(when collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} (t :right-side-bar/pane-expand) nil))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! false)} (t :right-side-bar/pane-expand-all) nil))
(when collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} (t :right-side-bar/pane-expand)))
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! false)} (t :right-side-bar/pane-expand-all)))
(when (= type :page) [:hr.menu-separator])
(when (= type :page)
(let [name (:block/name (db/entity db-id))]
(ui/menu-link {:href (if (db-model/whiteboard-page? name)
(rfe/href :whiteboard {:name name})
(rfe/href :page {:name name}))} (t :right-side-bar/pane-open-as-page) nil)))])
(rfe/href :page {:name name}))} (t :right-side-bar/pane-open-as-page))))])
(rum/defc drop-indicator
[idx drag-to]

View File

@ -12,18 +12,6 @@
{:d
"M99.069 64.173c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z"}]])
(defonce arrow-down-v2
[:svg.h-3.w-3
{:version "1.1"
:view-box "0 0 128 128"
:fill "currentColor"
:display "inline-block"
:style {:margin-top -3}}
[:path
{:d
"M64.177 100.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.086 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z"}]])
(defn loader-fn [opts]
[:svg.animate-spin
(merge {:version "1.1"

View File

@ -12,7 +12,6 @@
[frontend.handler.route :as route-handler]
[frontend.handler.whiteboard :as whiteboard-handler]
[frontend.handler.history :as history]
[frontend.modules.shortcut.data-helper :as shortcut-helper]
[frontend.rum :as r]
[frontend.search :as search]
[frontend.state :as state]
@ -80,8 +79,10 @@
(rum/defc keyboard-shortcut
[props]
(let [shortcut (shortcut-helper/gen-shortcut-seq (keyword (gobj/get props "action")))]
(ui/render-keyboard-shortcut shortcut)))
(let [shortcut (ui/keyboard-shortcut-from-config (keyword (gobj/get props "action")))]
(cond
(string? shortcut) (ui/render-keyboard-shortcut shortcut)
:else (interpose " | " (map ui/render-keyboard-shortcut shortcut)))))
(def tldraw-renderers {:Page page-cp
:Block block-cp

View File

@ -163,7 +163,7 @@
(-> sequence ;; turn string into sequence
(string/trim)
(string/lower-case)
(string/split #" |\+"))
(string/split #" "))
sequence)]
[:span.keyboard-shortcut
(map-indexed (fn [i key]
@ -177,7 +177,7 @@
sequence)]))
(rum/defc menu-link
[{:keys [only-child? no-padding? class] :as options} child shortcut]
[{:keys [only-child? no-padding? class shortcut] :as options} child]
(if only-child?
[:div.menu-link
(dissoc options :only-child?) child]
@ -224,7 +224,7 @@
(if hr
[:hr.menu-separator {:key (or key "dropdown-hr")}]
(rum/with-key
(menu-link new-options child nil)
(menu-link new-options child)
title)))))
wrapper-children
@ -539,7 +539,7 @@
(if (and (gobj/get e "shiftKey") on-shift-chosen)
(on-shift-chosen item)
(on-chosen item)))}
(if item-render (item-render item chosen?) item) nil))]]
(if item-render (item-render item chosen?) item)))]]
(if get-group-name
(if-let [group-name (get-group-name item)]
@ -568,9 +568,8 @@
(defn keyboard-shortcut-from-config [shortcut-name]
(let [default-binding (:binding (get shortcut-config/all-default-keyboard-shortcuts shortcut-name))
custom-binding (when (state/shortcuts) (get (state/shortcuts) shortcut-name))
binding (or custom-binding default-binding)]
(shortcut-helper/decorate-binding binding)))
custom-binding (when (state/shortcuts) (get (state/shortcuts) shortcut-name))]
(or custom-binding default-binding)))
(rum/defc modal-overlay
[state close-fn close-backdrop?]
@ -1003,6 +1002,10 @@
(def get-adapt-icon-class
(memoize (fn [klass] (r/adapt-class klass))))
(defn tabler-icon
[name]
(gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase name))))
(rum/defc icon
([name] (icon name nil))
([name {:keys [extension? font? class] :as opts}]
@ -1018,7 +1021,7 @@
(dissoc opts :class :extension? :font?))]
;; tabler svg react
(when-let [klass (gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase name)))]
(when-let [klass (tabler-icon name)]
(let [f (get-adapt-icon-class klass)]
[:span.ui__icon.ti
{:class (str "ls-icon-" name " " class)}

View File

@ -204,7 +204,7 @@ export const ContextMenu = observer(function ContextMenu({
{t('whiteboard/paste')}
<div className="tl-menu-right-slot">
<span className="keyboard-shortcut">
<code>{MOD_KEY}</code> <code>v</code>
<code>{MOD_KEY}+v</code>
</span>
</div>
</ReactContextMenu.Item>
@ -217,7 +217,7 @@ export const ContextMenu = observer(function ContextMenu({
{t('whiteboard/paste-as-link')}
<div className="tl-menu-right-slot">
<span className="keyboard-shortcut">
<code>{MOD_KEY}</code> <code></code> <code>v</code>
<code>{MOD_KEY}++v</code>
</span>
</div>
</ReactContextMenu.Item>

View File

@ -22,13 +22,13 @@ export const ToolButton = observer(
// Tool must exist
const Tool = [...app.Tools, TLSelectTool, TLMoveTool]?.find(T => T.id === id)
const shortcuts = (Tool as any)?.['shortcut']
const shortcut = (Tool as any)?.['shortcut']
const tooltipContent =
shortcuts && tooltip ? (
shortcut && tooltip ? (
<div className="flex">
{tooltip}
<KeyboardShortcut action={shortcuts} />
<KeyboardShortcut action={shortcut} />
</div>
) : (
tooltip