Browse Source

Merge pull request #6707 from logseq/feat/whiteboards-create-button

Feat: Create button on sidebar and command panel enhancements
Tienson Qin 3 years ago
parent
commit
25d0699d36

+ 1 - 0
resources/css/common.css

@@ -69,6 +69,7 @@ html[data-theme='dark'] {
   --ls-block-bullet-color: #608e91;
   --ls-block-bullet-color: #608e91;
   --ls-block-highlight-color: #0a3d4b;
   --ls-block-highlight-color: #0a3d4b;
   --ls-selection-background-color: #338fff;
   --ls-selection-background-color: #338fff;
+  --ls-selection-text-color: #fff;
   --ls-page-checkbox-color: #6093a0;
   --ls-page-checkbox-color: #6093a0;
   --ls-page-checkbox-border-color: var(--ls-primary-background-color);
   --ls-page-checkbox-border-color: var(--ls-primary-background-color);
   --ls-page-blockquote-color: var(--ls-primary-text-color);
   --ls-page-blockquote-color: var(--ls-primary-text-color);

+ 27 - 11
resources/css/tabler-extension.css

@@ -8,7 +8,7 @@
 
 
 @font-face {
 @font-face {
   font-family: 'tabler-icons-extension';
   font-family: 'tabler-icons-extension';
-  src: url('../fonts/tabler-icons-extension.woff2?6rsxel') format('woff2');
+  src: url('../fonts/tabler-icons-extension.woff2?mxgthk') format('woff2');
   font-style: normal;
   font-style: normal;
   font-weight: 400;
   font-weight: 400;
 }
 }
@@ -44,42 +44,58 @@
   content: '\ea04';
   content: '\ea04';
 }
 }
 
 
-.tie-object-compact::before {
+.tie-new-block::before {
   content: '\ea05';
   content: '\ea05';
 }
 }
 
 
-.tie-object-expanded::before {
+.tie-new-page::before {
   content: '\ea06';
   content: '\ea06';
 }
 }
 
 
-.tie-page::before {
+.tie-new-whiteboard::before {
   content: '\ea07';
   content: '\ea07';
 }
 }
 
 
-.tie-page-search::before {
+.tie-new-whiteboard-element::before {
   content: '\ea08';
   content: '\ea08';
 }
 }
 
 
-.tie-references-hide::before {
+.tie-object-compact::before {
   content: '\ea09';
   content: '\ea09';
 }
 }
 
 
-.tie-references-show::before {
+.tie-object-expanded::before {
   content: '\ea0a';
   content: '\ea0a';
 }
 }
 
 
-.tie-select-cursor::before {
+.tie-page::before {
   content: '\ea0b';
   content: '\ea0b';
 }
 }
 
 
-.tie-text::before {
+.tie-page-search::before {
   content: '\ea0c';
   content: '\ea0c';
 }
 }
 
 
-.tie-whiteboard::before {
+.tie-references-hide::before {
   content: '\ea0d';
   content: '\ea0d';
 }
 }
 
 
-.tie-whiteboard-element::before {
+.tie-references-show::before {
   content: '\ea0e';
   content: '\ea0e';
 }
 }
+
+.tie-select-cursor::before {
+  content: '\ea0f';
+}
+
+.tie-text::before {
+  content: '\ea10';
+}
+
+.tie-whiteboard::before {
+  content: '\ea11';
+}
+
+.tie-whiteboard-element::before {
+  content: '\ea12';
+}

BIN
resources/fonts/tabler-icons-extension.woff2


+ 10 - 0
src/main/frontend/components/command_palette.css

@@ -17,10 +17,12 @@
       transition: none;
       transition: none;
       border: none;
       border: none;
       border-radius: unset !important;
       border-radius: unset !important;
+      background: none;
     }
     }
 
 
     .chosen {
     .chosen {
       background-color: var(--ls-quaternary-background-color);
       background-color: var(--ls-quaternary-background-color);
+      color: var(--ls-secondary-text-color);
     }
     }
 
 
     .command-results-wrap,
     .command-results-wrap,
@@ -34,6 +36,14 @@
     .input-wrap {
     .input-wrap {
       height: var(--palettle-input-height);
       height: var(--palettle-input-height);
     }
     }
+
+    .cp__palette-input {
+      color: var(--ls-secondary-text-color);
+    }
+
+    .search-result {
+      @apply text-sm font-medium flex items-baseline;
+    }
   }
   }
 
 
   &-input {
   &-input {

+ 1 - 1
src/main/frontend/components/header.css

@@ -317,7 +317,7 @@ html.is-native-iphone {
   --ls-headbar-inner-top-padding: 36px;
   --ls-headbar-inner-top-padding: 36px;
 
 
   .left-sidebar-inner {
   .left-sidebar-inner {
-    .new-page {
+    .create {
       padding-bottom: 32px;
       padding-bottom: 32px;
     }
     }
   }
   }

+ 35 - 18
src/main/frontend/components/search.cljs

@@ -12,6 +12,7 @@
             [frontend.db :as db]
             [frontend.db :as db]
             [frontend.db.model :as model]
             [frontend.db.model :as model]
             [frontend.handler.search :as search-handler]
             [frontend.handler.search :as search-handler]
+            [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.state :as state]
             [frontend.state :as state]
@@ -62,11 +63,10 @@
             [:p {:class "m-0"} elements]))))))
             [:p {:class "m-0"} elements]))))))
 
 
 (rum/defc search-result-item
 (rum/defc search-result-item
-  [type content]
-  [:.text-sm.font-medium.flex.items-baseline
-   [:.text-xs.rounded.border.mr-2.px-1 {:title type}
-    (get type 0)]
-   content])
+  [icon content]
+  [:.search-result
+   (ui/type-icon icon)
+   [:.self-center content]])
 
 
 (rum/defc block-search-result-item
 (rum/defc block-search-result-item
   [repo uuid format content q search-mode]
   [repo uuid format content q search-mode]
@@ -123,7 +123,7 @@
     (page-handler/create! search-q {:redirect? true})
     (page-handler/create! search-q {:redirect? true})
 
 
     :new-whiteboard
     :new-whiteboard
-    (route/redirect-to-whiteboard! search-q)
+    (whiteboard-handler/create-new-whiteboard! search-q)
 
 
     :page
     :page
     (let [data (or alias data)]
     (let [data (or alias data)]
@@ -191,6 +191,15 @@
     nil)
     nil)
   (state/close-modal!))
   (state/close-modal!))
 
 
+(defn- create-item-render
+  [icon label name]
+  (search-result-item
+   {:name icon
+    :class "highlight"
+    :extension? true}
+   [:div.text.font-bold (str label ": ")
+    [:span.ml-1 name]]))
+
 (defn- search-item-render
 (defn- search-item-render
   [search-q {:keys [type data alias]}]
   [search-q {:keys [type data alias]}]
   (let [search-mode (state/get-search-mode)
   (let [search-mode (state/get-search-mode)
@@ -201,22 +210,25 @@
        [:b search-q]
        [:b search-q]
 
 
        :new-page
        :new-page
-       [:div.text.font-bold (str (t :new-page) ": ")
-        [:span.ml-1 (str "\"" (string/trim search-q) "\"")]]
+       (create-item-render "new-page" (t :new-page) (str "\"" (string/trim search-q) "\""))
 
 
        :new-whiteboard
        :new-whiteboard
-       [:div.text.font-bold (str (t :new-whiteboard) ": ")
-        [:span.ml-1 (str "\"" (string/trim search-q) "\"")]]
+       (create-item-render "new-whiteboard" (t :new-whiteboard) (str "\"" (string/trim search-q) "\""))
 
 
        :page
        :page
        [:span {:data-page-ref data}
        [:span {:data-page-ref data}
         (when alias
         (when alias
           (let [target-original-name (model/get-page-original-name alias)]
           (let [target-original-name (model/get-page-original-name alias)]
             [:span.mr-2.text-sm.font-medium.mb-2 (str "Alias -> " target-original-name)]))
             [:span.mr-2.text-sm.font-medium.mb-2 (str "Alias -> " target-original-name)]))
-        (search-result-item (if (model/whiteboard-page? data) "Whiteboard" "Page") (highlight-exact-query data search-q))]
+        (search-result-item {:name (if (model/whiteboard-page? data) "whiteboard" "page")
+                             :extension? true
+                             :title (t (if (model/whiteboard-page? data) :search-item/whiteboard :search-item/page))}
+                            (highlight-exact-query data search-q))]
 
 
        :file
        :file
-       (search-result-item "File" (highlight-exact-query data search-q))
+       (search-result-item {:name "file"
+                            :title (t :search-item/file)}
+                           (highlight-exact-query data search-q))
 
 
        :block
        :block
        (let [{:block/keys [page uuid]} data  ;; content here is normalized
        (let [{:block/keys [page uuid]} data  ;; content here is normalized
@@ -226,10 +238,13 @@
              block (model/query-block-by-uuid uuid)
              block (model/query-block-by-uuid uuid)
              content (:block/content block)]
              content (:block/content block)]
          [:span {:data-block-ref uuid}
          [:span {:data-block-ref uuid}
-          (search-result-item "Block"  (if block
-                                         (block-search-result-item repo uuid format content search-q search-mode)
-                                         (do (log/error "search result with non-existing uuid: " data)
-                                             (str "Cache is outdated. Please click the 'Re-index' button in the graph's dropdown menu."))))])
+          (search-result-item {:name "block"
+                               :title (t :search-item/block)
+                               :extension? true}
+                              (if block
+                                (block-search-result-item repo uuid format content search-q search-mode)
+                                (do (log/error "search result with non-existing uuid: " data)
+                                    (str "Cache is outdated. Please click the 'Re-index' button in the graph's dropdown menu."))))])
 
 
        nil)]))
        nil)]))
 
 
@@ -360,7 +375,9 @@
                                  svg/search
                                  svg/search
                                  [:span.ml-2 data]]
                                  [:span.ml-2 data]]
                         :page (when-let [original-name (model/get-page-original-name data)] ;; might be block reference
                         :page (when-let [original-name (model/get-page-original-name data)] ;; might be block reference
-                                (search-result-item "Page" original-name))
+                                (search-result-item {:name "page"
+                                                     :extension? true}
+                                                    original-name))
                         nil))}))])
                         nil))}))])
 
 
 (defn default-placeholder
 (defn default-placeholder
@@ -439,4 +456,4 @@
       [:p.font-medium.tx-sm (str (count (:blocks search-result)) " " (t :search/items))]
       [:p.font-medium.tx-sm (str (count (:blocks search-result)) " " (t :search/items))]
       [:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600
       [:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600
        (when-not (string/blank? search-q)
        (when-not (string/blank? search-q)
-         (search-auto-complete search-result search-q true))]]]))
+         (search-auto-complete search-result search-q true))]]]))

+ 44 - 9
src/main/frontend/components/sidebar.cljs

@@ -26,6 +26,7 @@
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.user :as user-handler]
             [frontend.handler.user :as user-handler]
+            [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
             [frontend.mobile.action-bar :as action-bar]
             [frontend.mobile.action-bar :as action-bar]
             [frontend.mobile.footer :as footer]
             [frontend.mobile.footer :as footer]
@@ -221,10 +222,44 @@
     (ui/icon (str icon) {:extension? icon-extention?})
     (ui/icon (str icon) {:extension? icon-extention?})
     [:span.flex-1 title]]])
     [:span.flex-1 title]]])
 
 
+(defn close-sidebar-on-mobile!
+  []
+  (and (util/sm-breakpoint?)
+    (state/toggle-left-sidebar!)))
+
+(defn create-dropdown
+  []
+  (ui/dropdown-with-links
+   (fn [{:keys [toggle-fn]}]
+     [:button#create-button
+      {:on-click toggle-fn}
+      [:<>
+       (ui/icon "plus")
+       [:span.mx-1 (t :left-side-bar/create)]]])
+   (->>
+    [{: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]))}
+      :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!))}
+      :icon (ui/type-icon {:name "new-whiteboard"
+                           :class "highlight"
+                           :extension? true})}])
+   {}))
+
 (rum/defc sidebar-nav
 (rum/defc sidebar-nav
   [route-match close-modal-fn left-sidebar-open? srs-open?]
   [route-match close-modal-fn left-sidebar-open? srs-open?]
   (let [default-home (get-default-home-if-valid)
   (let [default-home (get-default-home-if-valid)
         route-name (get-in route-match [:data :name])
         route-name (get-in route-match [:data :name])
+        enable-whiteboards? (state/enable-whiteboards?)
         on-contents-scroll #(when-let [^js el (.-target %)]
         on-contents-scroll #(when-let [^js el (.-target %)]
                               (let [top (.-scrollTop el)
                               (let [top (.-scrollTop el)
                                     cls (.-classList el)
                                     cls (.-classList el)
@@ -290,7 +325,7 @@
           :active (and (not srs-open?) (= route-name :all-pages))
           :active (and (not srs-open?) (= route-name :all-pages))
           :icon   "files"})
           :icon   "files"})
 
 
-        (when (state/enable-whiteboards?)
+        (when enable-whiteboards?
           (sidebar-item
           (sidebar-item
            {:class "whiteboard"
            {:class "whiteboard"
             :title (t :right-side-bar/whiteboards)
             :title (t :right-side-bar/whiteboards)
@@ -307,15 +342,15 @@
        (when (and left-sidebar-open? (not config/publishing?))
        (when (and left-sidebar-open? (not config/publishing?))
          (recent-pages t))]
          (recent-pages t))]
 
 
-      [:footer.px-2 {:class "new-page"}
+      [:footer.px-2 {:class "create"}
        (when-not config/publishing?
        (when-not config/publishing?
-         [:a.item.group.flex.items-center.px-2.py-2.text-sm.font-medium.rounded-md.new-page-link
-          {:on-click (fn []
-                       (and (util/sm-breakpoint?)
-                            (state/toggle-left-sidebar!))
-                       (state/pub-event! [:go/search]))}
-          (ui/icon "circle-plus mr-3" {:style {:font-size 20}})
-          [:span.flex-1 (t :right-side-bar/new-page)]])]]]))
+         (if enable-whiteboards?
+           (create-dropdown)
+           [:a.item.group.flex.items-center.px-2.py-2.text-sm.font-medium.rounded-md.new-page-link
+            {:on-click #((close-sidebar-on-mobile!)
+                         (state/pub-event! [:go/search]))}
+            (ui/icon "circle-plus mr-3" {:style {:font-size 20}})
+            [:span.flex-1 (t :right-side-bar/new-page)]]))]]]))
 
 
 (rum/defc left-sidebar < rum/reactive
 (rum/defc left-sidebar < rum/reactive
   [{:keys [left-sidebar-open? route-match]}]
   [{:keys [left-sidebar-open? route-match]}]

+ 41 - 2
src/main/frontend/components/sidebar.css

@@ -264,17 +264,56 @@
     }
     }
   }
   }
 
 
-  .new-page {
+  .create {
     position: absolute;
     position: absolute;
     bottom: 0;
     bottom: 0;
     left: 0;
     left: 0;
     width: 100%;
     width: 100%;
     padding: 14px;
     padding: 14px;
+    background-image: linear-gradient(transparent, var(--ls-primary-background-color));
+
+    @screen sm {
+      background-image: linear-gradient(transparent, var(--ls-secondary-background-color));
+    }
 
 
     &-link {
     &-link {
       background-color: var(--ls-primary-background-color);
       background-color: var(--ls-primary-background-color);
       box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
       box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
     }
     }
+
+    .dropdown-wrapper {
+      top: initial;
+      right: initial;
+      bottom: calc(100% + 6px);
+      left: 0;
+      width: max-content;
+
+      @screen sm {
+        bottom: 0;
+        left: calc(100% + 6px);
+      }
+    }
+
+    #create-button {
+      @apply p-2 text-sm font-medium rounded-md w-full border;
+      background-color: var(--ls-secondary-background-color) !important;
+      border-color: transparent;
+
+      &: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;
+        }
+      }
+    }
   }
   }
 
 
   @screen sm {
   @screen sm {
@@ -286,7 +325,7 @@
       margin-top: 52px;
       margin-top: 52px;
     }
     }
 
 
-    .new-page {
+    .create {
       &-link {
       &-link {
         background-color: var(--ls-primary-background-color);
         background-color: var(--ls-primary-background-color);
       }
       }

+ 1 - 4
src/main/frontend/components/whiteboard.cljs

@@ -1,6 +1,5 @@
 (ns frontend.components.whiteboard
 (ns frontend.components.whiteboard
   (:require [cljs.math :as math]
   (:require [cljs.math :as math]
-            [datascript.core :as d]
             [frontend.components.page :as page]
             [frontend.components.page :as page]
             [frontend.components.reference :as reference]
             [frontend.components.reference :as reference]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
@@ -151,9 +150,7 @@
    {:on-click
    {:on-click
     (fn [e]
     (fn [e]
       (util/stop e)
       (util/stop e)
-      (let [name (str (d/squuid))]
-        (whiteboard-handler/create-new-whiteboard-page! name)
-        (route-handler/redirect-to-whiteboard! name)))}
+      (whiteboard-handler/create-new-whiteboard!))}
    (ui/icon "plus")
    (ui/icon "plus")
    [:span.dashboard-create-card-caption.select-none
    [:span.dashboard-create-card-caption.select-none
     "New whiteboard"]])
     "New whiteboard"]])

+ 6 - 0
src/main/frontend/dicts.cljc

@@ -45,6 +45,10 @@
         :search/result-for "Search result for "
         :search/result-for "Search result for "
         :search/items "items"
         :search/items "items"
         :search/page-names "Search page names"
         :search/page-names "Search page names"
+        :search-item/whiteboard "Whiteboard"
+        :search-item/page "Page"
+        :search-item/file "File"
+        :search-item/block "Block"
         :help/context-menu "Block context menu"
         :help/context-menu "Block context menu"
         :help/fold-unfold "Fold/unfold blocks (when not in edit mode)"
         :help/fold-unfold "Fold/unfold blocks (when not in edit mode)"
         :help/markdown-syntax "Markdown syntax"
         :help/markdown-syntax "Markdown syntax"
@@ -72,7 +76,9 @@
         :right-side-bar/show-journals "Show Journals"
         :right-side-bar/show-journals "Show Journals"
         :right-side-bar/separator "Right sidebar resize handler"
         :right-side-bar/separator "Right sidebar resize handler"
         :left-side-bar/journals "Journals"
         :left-side-bar/journals "Journals"
+        :left-side-bar/create "Create"
         :left-side-bar/new-page "New page"
         :left-side-bar/new-page "New page"
+        :left-side-bar/new-whiteboard "New whiteboard"
         :left-side-bar/nav-favorites "Favorites"
         :left-side-bar/nav-favorites "Favorites"
         :left-side-bar/nav-shortcuts "Shortcuts"
         :left-side-bar/nav-shortcuts "Shortcuts"
         :left-side-bar/nav-recent-pages "Recent"
         :left-side-bar/nav-recent-pages "Recent"

+ 9 - 0
src/main/frontend/handler/whiteboard.cljs

@@ -2,6 +2,8 @@
   (:require [datascript.core :as d]
   (:require [datascript.core :as d]
             [frontend.db.model :as model]
             [frontend.db.model :as model]
             [frontend.db.utils :as db-utils]
             [frontend.db.utils :as db-utils]
+            [frontend.handler.editor :as editor-handler]
+            [frontend.handler.route :as route-handler]
             [frontend.modules.outliner.core :as outliner]
             [frontend.modules.outliner.core :as outliner]
             [frontend.modules.outliner.file :as outliner-file]
             [frontend.modules.outliner.file :as outliner-file]
             [frontend.state :as state]
             [frontend.state :as state]
@@ -148,6 +150,13 @@
            (outliner-file/sync-to-file page-entity))))
            (outliner-file/sync-to-file page-entity))))
      tldr)))
      tldr)))
 
 
+(defn create-new-whiteboard!
+  ([name]
+   (create-new-whiteboard-page! name)
+   (route-handler/redirect-to-whiteboard! name))
+  ([]
+   (create-new-whiteboard! (str (d/squuid)))))
+
 (defn page-name->tldr!
 (defn page-name->tldr!
   ([page-name]
   ([page-name]
    (page-name->tldr! page-name nil))
    (page-name->tldr! page-name nil))

+ 8 - 1
src/main/frontend/modules/shortcut/config.cljs

@@ -12,6 +12,7 @@
             [frontend.handler.search :as search-handler]
             [frontend.handler.search :as search-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.modules.shortcut.dicts :as dicts]
             [frontend.modules.shortcut.dicts :as dicts]
             [frontend.modules.shortcut.before :as m]
             [frontend.modules.shortcut.before :as m]
             [frontend.state :as state]
             [frontend.state :as state]
@@ -30,6 +31,7 @@
 ;; To add a new entry to this map, first add it here and then
 ;; To add a new entry to this map, first add it here and then
 ;; a description for it in frontend.modules.shortcut.dicts/all-default-keyboard-shortcuts.
 ;; a description for it in frontend.modules.shortcut.dicts/all-default-keyboard-shortcuts.
 ;; :inactive key is for commands that are not active for a given platform or feature condition
 ;; :inactive key is for commands that are not active for a given platform or feature condition
+;; Avoid using single letter shortcuts to allow chords that start with those characters
 (def ^:large-vars/data-var all-default-keyboard-shortcuts
 (def ^:large-vars/data-var all-default-keyboard-shortcuts
   {:date-picker/complete         {:binding "enter"
   {:date-picker/complete         {:binding "enter"
                                   :fn      ui-handler/shortcut-complete}
                                   :fn      ui-handler/shortcut-complete}
@@ -101,6 +103,9 @@
    :editor/new-line              {:binding "shift+enter"
    :editor/new-line              {:binding "shift+enter"
                                   :fn      editor-handler/keydown-new-line-handler}
                                   :fn      editor-handler/keydown-new-line-handler}
 
 
+   :editor/new-whiteboard        {:binding "n w"
+                                  :fn      whiteboard-handler/create-new-whiteboard!}
+
    :editor/follow-link           {:binding "mod+o"
    :editor/follow-link           {:binding "mod+o"
                                   :fn      editor-handler/follow-link-under-cursor!}
                                   :fn      editor-handler/follow-link-under-cursor!}
 
 
@@ -307,7 +312,7 @@
 
 
    :graph/re-index                 {:fn (fn []
    :graph/re-index                 {:fn (fn []
                                           (p/let [multiple-windows? (ipc/ipc "graphHasMultipleWindows" (state/get-current-repo))]
                                           (p/let [multiple-windows? (ipc/ipc "graphHasMultipleWindows" (state/get-current-repo))]
-                                                 (state/pub-event! [:graph/ask-for-re-index multiple-windows?])))
+                                            (state/pub-event! [:graph/ask-for-re-index multiple-windows?])))
                                     :binding false}
                                     :binding false}
 
 
    :command/run                    {:binding "mod+shift+1"
    :command/run                    {:binding "mod+shift+1"
@@ -551,6 +556,7 @@
                           :editor/open-file-in-default-app
                           :editor/open-file-in-default-app
                           :editor/open-file-in-directory
                           :editor/open-file-in-directory
                           :editor/copy-current-file
                           :editor/copy-current-file
+                          :editor/new-whiteboard
                           :ui/toggle-wide-mode
                           :ui/toggle-wide-mode
                           :ui/select-theme-color
                           :ui/select-theme-color
                           :ui/goto-plugins
                           :ui/goto-plugins
@@ -680,6 +686,7 @@
     :editor/insert-youtube-timestamp
     :editor/insert-youtube-timestamp
     :editor/open-file-in-default-app
     :editor/open-file-in-default-app
     :editor/open-file-in-directory
     :editor/open-file-in-directory
+    :editor/new-whiteboard
     :auto-complete/prev
     :auto-complete/prev
     :auto-complete/next
     :auto-complete/next
     :auto-complete/complete
     :auto-complete/complete

+ 2 - 1
src/main/frontend/modules/shortcut/data_helper.cljs

@@ -93,11 +93,12 @@
 
 
 (defn decorate-binding [binding]
 (defn decorate-binding [binding]
   (-> (if (string? binding) binding (str/join "+"  binding))
   (-> (if (string? binding) binding (str/join "+"  binding))
-      (str/replace "mod" (if util/mac? "cmd" "ctrl"))
+      (str/replace "mod" (if util/mac? "" "ctrl"))
       (str/replace "alt" (if util/mac? "opt" "alt"))
       (str/replace "alt" (if util/mac? "opt" "alt"))
       (str/replace "shift+/" "?")
       (str/replace "shift+/" "?")
       (str/replace "left" "←")
       (str/replace "left" "←")
       (str/replace "right" "→")
       (str/replace "right" "→")
+      (str/replace "shift" "⇧")
       (str/replace "open-square-bracket" "[")
       (str/replace "open-square-bracket" "[")
       (str/replace "close-square-bracket" "]")
       (str/replace "close-square-bracket" "]")
       (str/lower-case)))
       (str/lower-case)))

+ 1 - 0
src/main/frontend/modules/shortcut/dicts.cljc

@@ -30,6 +30,7 @@
    :editor/delete                "Delete / Delete forwards"
    :editor/delete                "Delete / Delete forwards"
    :editor/new-block             "Create new block"
    :editor/new-block             "Create new block"
    :editor/new-line              "New line in current block"
    :editor/new-line              "New line in current block"
+   :editor/new-whiteboard        "Create new whiteboard"
    :editor/follow-link           "Follow link under cursor"
    :editor/follow-link           "Follow link under cursor"
    :editor/open-link-in-sidebar  "Open link in sidebar"
    :editor/open-link-in-sidebar  "Open link in sidebar"
    :editor/bold                  "Bold"
    :editor/bold                  "Bold"

+ 8 - 2
src/main/frontend/ui.cljs

@@ -157,7 +157,7 @@
      [:.menu-links-wrapper
      [:.menu-links-wrapper
       (when links-header links-header)
       (when links-header links-header)
 
 
-      (for [{:keys [options title icon key hr hover-detail item _as-link?]} (if (fn? links) (links) links)]
+      (for [{:keys [options title icon shortcut key hr hover-detail item _as-link?]} (if (fn? links) (links) links)]
         (let [new-options
         (let [new-options
               (merge options
               (merge options
                      (cond->
                      (cond->
@@ -178,7 +178,7 @@
           (if hr
           (if hr
             [:hr.menu-separator {:key "dropdown-hr"}]
             [:hr.menu-separator {:key "dropdown-hr"}]
             (rum/with-key
             (rum/with-key
-              (menu-link new-options child nil)
+              (menu-link new-options child shortcut)
               title))))
               title))))
       (when links-footer links-footer)])
       (when links-footer links-footer)])
    opts))
    opts))
@@ -931,6 +931,12 @@
                        (if extension? "tie tie" "ti ti"))}
                        (if extension? "tie tie" "ti ti"))}
               (dissoc opts :class :extension?))]))
               (dissoc opts :class :extension?))]))
 
 
+(rum/defc type-icon
+  [{:keys [name class title extension?]}]
+  [:.type-icon {:class class
+                :title title}
+   (icon name {:extension? extension?})])
+
 (rum/defc with-shortcut < rum/reactive
 (rum/defc with-shortcut < rum/reactive
   < {:key-fn (fn [key pos] (str "shortcut-" key pos))}
   < {:key-fn (fn [key pos] (str "shortcut-" key pos))}
   [shortcut-key position content]
   [shortcut-key position content]

+ 32 - 0
src/main/frontend/ui.css

@@ -352,3 +352,35 @@ html.is-mobile {
 .bg-quaternary {
 .bg-quaternary {
   background-color: var(--ls-quaternary-background-color);
   background-color: var(--ls-quaternary-background-color);
 }
 }
+
+.type-icon {
+  @apply text-xs text-center flex items-center justify-center rounded border mr-2 relative;
+
+  width: 1.5rem;
+  height: 1.5rem;
+  flex-shrink: 0;
+  border-color: var(--ls-primary-background-color);
+  overflow: hidden;
+  color: var(--ls-primary-text-color);
+
+  .ti,
+  .tie {
+    z-index: 1;
+  }
+
+  &:before {
+    @apply block absolute inset-0 ;
+    background: var(--ls-primary-background-color);
+    content: " ";
+  }
+
+  &.highlight {
+    color: var(--ls-selection-text-color);
+    border-color: var(--ls-selection-background-color);
+
+    &:before {
+      opacity: 0.5;
+      background: var(--ls-selection-background-color);
+    }
+  }
+}