Jelajahi Sumber

Merge branch 'master' into feat/db

Tienson Qin 2 tahun lalu
induk
melakukan
03ec9580c3

+ 2 - 2
android/app/build.gradle

@@ -6,8 +6,8 @@ android {
         applicationId "com.logseq.app"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
-        versionCode 66
-        versionName "0.9.13"
+        versionCode 67
+        versionName "0.9.14"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
              // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

+ 4 - 4
ios/App/App.xcodeproj/project.pbxproj

@@ -519,7 +519,7 @@
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				MARKETING_VERSION = 0.9.13;
+				MARKETING_VERSION = 0.9.14;
 				OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -546,7 +546,7 @@
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				MARKETING_VERSION = 0.9.13;
+				MARKETING_VERSION = 0.9.14;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
@@ -571,7 +571,7 @@
 				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
-				MARKETING_VERSION = 0.9.13;
+				MARKETING_VERSION = 0.9.14;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq.ShareViewController;
@@ -598,7 +598,7 @@
 				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
-				MARKETING_VERSION = 0.9.13;
+				MARKETING_VERSION = 0.9.14;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq.ShareViewController;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 1 - 1
resources/forge.config.js

@@ -4,7 +4,7 @@ module.exports = {
   packagerConfig: {
     name: 'Logseq',
     icon: './icons/logseq_big_sur.icns',
-    buildVersion: 66,
+    buildVersion: 67,
     protocols: [
       {
         "protocol": "logseq",

+ 1 - 1
resources/package.json

@@ -1,7 +1,7 @@
 {
   "name": "Logseq",
   "productName": "Logseq",
-  "version": "0.9.13",
+  "version": "0.9.14",
   "main": "electron.js",
   "author": "Logseq",
   "license": "AGPL-3.0",

+ 2 - 1
src/electron/electron/window.cljs

@@ -28,7 +28,8 @@
    (let [win-state (windowStateKeeper (clj->js {:defaultWidth 980 :defaultHeight 700}))
          native-titlebar? (cfgs/get-item :window/native-titlebar?)
          win-opts  (cond->
-                     {:width                (.-width win-state)
+                     {:backgroundColor      "#fff" ; SEE https://www.electronjs.org/docs/latest/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do
+                      :width                (.-width win-state)
                       :height               (.-height win-state)
                       :frame                (or mac? native-titlebar?)
                       :titleBarStyle        "hiddenInset"

+ 24 - 0
src/main/frontend/components/block.css

@@ -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;

+ 89 - 81
src/main/frontend/components/container.cljs

@@ -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]
@@ -46,18 +45,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,9 +91,9 @@
                (:db/id page-entity)
                :page))
             (if whiteboard-page?
-              (route-handler/redirect-to-whiteboard! name)
+              (route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
               (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))]]))
@@ -136,39 +139,43 @@
 
 (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))]]
-
-   {: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)
+  (let [favorites (->> (:favorites (state/sub-config))
+                       (remove string/blank?)
+                       (filter string?)
+                       (mapv util/safe-page-name-sanity-lc)
+                       (distinct))
+        favorite-entities (->> favorites
+                               (mapv #(db/entity [:block/name %]))
+                               (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"
+      :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 (recent-handler/get-recent-pages)]
+    (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 (recent-handler/get-recent-pages)]
      [:ul.text-sm
       (for [name pages]
         (when-let [entity (db/entity [:block/name (util/safe-page-name-sanity-lc name)])]
@@ -193,8 +200,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
   []
@@ -208,13 +216,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
@@ -222,7 +224,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!
   []
@@ -241,17 +245,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})}])
@@ -341,55 +345,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}

+ 64 - 58
src/main/frontend/components/container.css

@@ -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;
+      }
+
+      a {
+        opacity: .7;
+      }
 
-          &:last-child {
-            transform: translateY(-6px) translateX(2px) rotate(90deg);
-            transform-origin: center center;
-            transition: .15s transform;
-          }
-        }
+      .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;
@@ -633,6 +641,7 @@ html[data-theme='dark'] {
 
     &.drag-over {
       &::after {
+        z-index: 1000;
         background-color: var(--ls-active-primary-color);
       }
     }
@@ -644,13 +653,10 @@ html[data-theme='dark'] {
     min-height: 100px;
 
     .sidebar-item-header {
-      white-space: nowrap;
-
       .breadcrumb {
         margin-top: 0;
         margin-bottom: 0;
-        text-overflow: ellipsis;
-        overflow: hidden;
+        text-align: left;
       }
     }
 

+ 57 - 77
src/main/frontend/components/content.cljs

@@ -48,38 +48,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]
 
@@ -87,34 +84,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))
 
@@ -174,8 +169,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
@@ -199,9 +193,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]
 
@@ -209,15 +203,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?)
@@ -228,28 +220,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]
 
@@ -260,38 +250,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)]
@@ -300,16 +287,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
@@ -317,8 +302,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]
@@ -330,29 +314,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]
@@ -361,7 +341,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))])))
 
 (rum/defc property-custom-context-menu-content

+ 3 - 13
src/main/frontend/components/header.css

@@ -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 {

+ 9 - 2
src/main/frontend/components/repo.cljs

@@ -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]
@@ -235,6 +236,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)
@@ -249,11 +251,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->

+ 15 - 13
src/main/frontend/components/right_sidebar.cljs

@@ -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-close-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-close-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]
@@ -224,7 +224,7 @@
       (let [collapsed? (state/sub [:ui/sidebar-collapsed-blocks db-id])]
         [:<>
          (when (zero? idx) (drop-indicator (dec idx) drag-to))
-         [:div.flex.sidebar-item.content.color-level.shadow-md.rounded-md.overflow-hidden
+         [:div.flex.sidebar-item.content.color-level.shadow-md.rounded-md
           {:class [(str "item-type-" (name block-type))
                    (when collapsed? "collapsed")]}
           (let [[title component] item]
@@ -266,10 +266,12 @@
                               (context-menu-content db-id idx block-type collapsed? block-count close-fn)))
                [:button.button.close {:title (t :right-side-bar/pane-close)
                                       :on-click #(state/sidebar-remove-block! idx)} (ui/icon "x")]]]
-             [:div.scrollbar-spacing.p-4 {:role "region"
+             [:div.pt-4.p-1 {:role "region"
                                           :id (str "sidebar-panel-content-" idx)
                                           :aria-labelledby (str "sidebar-panel-header-" idx)
-                                          :class (if collapsed? "hidden" "initial")}
+                                          :class (util/classnames [{:hidden collapsed?
+                                                                    :initial (not collapsed?)
+                                                                    :p-4 (not (contains? #{:page :block :contents} block-type))}])}
               (inner-component component (not drag-from))]
              (when drag-from (drop-area idx))])]
          (drop-indicator idx drag-to)]))))
@@ -417,7 +419,7 @@
                                                                        (state/sidebar-add-block! repo "history" :history))}
             (t :right-side-bar/history)]])]]
 
-      [:.sidebar-item-list.flex-1.scrollbar-spacing.flex.flex-col.mx-2
+      [:.sidebar-item-list.flex-1.scrollbar-spacing.ml-2.pr-3
        (if @*anim-finished?
          (for [[idx [repo db-id block-type]] (medley/indexed blocks)]
            (rum/with-key

+ 8 - 3
src/main/frontend/components/right_sidebar.css

@@ -17,7 +17,8 @@ html[data-theme=light] {
 
 .sidebar-item-list {
   margin-top: -8px;
-  height: calc(100vh - 40px);
+  padding-bottom: 150px;
+  height: calc(100vh - 48px);
 }
 
 
@@ -30,8 +31,12 @@ html[data-theme=light] a.toggle:hover {
     color: var(--ls-header-button-background);
 }
 
-.cp__right-sidebar-topbar button {
-  opacity: 1;
+.cp__right-sidebar-topbar {
+  background-color: var(--ls-primary-background-color);
+
+  button {
+    opacity: 1;
+  }
 }
 
 html[data-theme=dark] {

+ 0 - 12
src/main/frontend/components/svg.cljs

@@ -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"

+ 41 - 2
src/main/frontend/extensions/pdf/core.cljs

@@ -823,11 +823,38 @@
             (rum/with-key (pdf-resizer viewer) "pdf-resizer"))
           (rum/with-key (pdf-toolbar viewer {:on-external-window! #(open-external-win! (state/get-current-pdf))}) "pdf-toolbar")])])))
 
+(rum/defcs pdf-password-input <
+  (rum/local "" ::password)
+  [state confirm-fn]
+  (let [password (get state ::password)]
+    [:div.container
+     [:div.text-lg.mb-4 "Password required"]
+     [:div.sm:flex.sm:items-start
+      [:div.mt-3.text-center.sm:mt-0.sm:text-left
+       [:h3#modal-headline.leading-6.font-medium
+        "This document is password protected. Please enter a password:"]]]
+
+     [:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2.mb-4
+      {:auto-focus true
+       :on-change (fn [e]
+                    (reset! password (util/evalue e)))}]
+
+     [:div.mt-5.sm:mt-4.sm:flex.sm:flex-row-reverse
+      [:span.flex.w-full.rounded-md.shadow-sm.sm:ml-3.sm:w-auto
+       [:button.inline-flex.justify-center.w-full.rounded-md.border.border-transparent.px-4.py-2.bg-indigo-600.text-base.leading-6.font-medium.text-white.shadow-sm.hover:bg-indigo-500.focus:outline-none.focus:border-indigo-700.focus:shadow-outline-indigo.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5
+        {:type "button"
+         :on-click (fn []
+                     (let [password @password]
+                       (confirm-fn password)))}
+        "Submit"]]]]))
+
+
 (rum/defc ^:large-vars/data-var pdf-loader
   [{:keys [url hls-file identity filename] :as pdf-current}]
   (let [*doc-ref       (rum/use-ref nil)
         [loader-state, set-loader-state!] (rum/use-state {:error nil :pdf-document nil :status nil})
         [hls-state, set-hls-state!] (rum/use-state {:initial-hls nil :latest-hls nil :extra nil :loaded false :error nil})
+        [doc-password, set-doc-password!] (rum/use-state nil) ;; use nil to handle empty string
         [initial-page, set-initial-page!] (rum/use-state 1)
         set-dirty-hls! (fn [latest-hls]                     ;; TODO: incremental
                          (set-hls-state! #(merge % {:initial-hls [] :latest-hls latest-hls})))
@@ -881,6 +908,7 @@
        (let [^js loader-el (rum/deref *doc-ref)
              get-doc$      (fn [^js opts] (.-promise (js/pdfjsLib.getDocument opts)))
              opts          {:url           url
+                            :password      (or doc-password "")
                             :ownerDocument (.-ownerDocument loader-el)
                             :cMapUrl       "./cmaps/"
                             ;;:cMapUrl       "https://cdn.jsdelivr.net/npm/[email protected]/cmaps/"
@@ -889,10 +917,11 @@
          (set-loader-state! {:status :loading})
 
          (-> (get-doc$ (clj->js opts))
-             (p/then #(set-loader-state! {:pdf-document % :status :completed}))
+             (p/then (fn [doc]
+                       (set-loader-state! {:pdf-document doc :status :completed})))
              (p/catch #(set-loader-state! {:error %})))
          #()))
-     [url])
+     [url doc-password])
 
     (rum/use-effect!
      (fn []
@@ -917,6 +946,16 @@
               false)
              (state/set-state! :pdf/current nil))
 
+           "PasswordException"
+           (do
+             (set-loader-state! {:error nil})
+             (state/set-modal! (fn [close-fn]
+                                 (let [on-password-fn
+                                       (fn [password]
+                                         (close-fn)
+                                         (set-doc-password! password))]
+                                   (pdf-password-input on-password-fn)))))
+
            (do
              (notification/show!
               (str "Error: " (.-name error) "\n" (.-message error) "\n"

+ 4 - 3
src/main/frontend/extensions/tldraw.cljs

@@ -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

+ 6 - 3
src/main/frontend/handler/db_based/recent.cljs

@@ -2,7 +2,8 @@
   "Fns related to recent pages feature"
   (:require [frontend.db :as db]
             [frontend.state :as state]
-            [logseq.graph-parser.util :as gp-util]))
+            [logseq.graph-parser.util :as gp-util]
+            [clojure.string :as string]))
 
 (defn add-page-to-recent!
   [repo page click-from-recent?]
@@ -19,8 +20,10 @@
 
 (defn get-recent-pages
   []
-  (->> (db/get-key-value :recent/pages)
+  (->> (db/sub-key-value :recent/pages)
+       (distinct)
        (map (fn [id]
               (let [e (db/entity [:block/uuid id])]
                 (or (:block/original-name e)
-                    (:block/uuid e)))))))
+                    (:block/uuid e)))))
+       (remove string/blank?)))

+ 1 - 0
src/main/frontend/handler/page.cljs

@@ -873,6 +873,7 @@
                          (concat (drop-last prev) [from (last prev)] next)
                          (concat prev [from] next))
                        (remove nil?)
+                       (mapv util/safe-page-name-sanity-lc)
                        distinct
                        vec)]
         (config-handler/set-config! :favorites favorites)))))

+ 2 - 2
src/main/frontend/handler/route.cljs

@@ -89,10 +89,10 @@
 (defn redirect-to-whiteboard!
   ([name]
    (redirect-to-whiteboard! name nil))
-  ([name {:keys [block-id new-whiteboard?]}]
+  ([name {:keys [block-id new-whiteboard? click-from-recent?]}]
    ;; Always skip onboarding when loading an existing whiteboard
    (when-not new-whiteboard? (state/set-onboarding-whiteboard! true))
-   (recent-handler/add-page-to-recent! (state/get-current-repo) name false)
+   (recent-handler/add-page-to-recent! (state/get-current-repo) name click-from-recent?)
    (if (= name (state/get-current-whiteboard))
      (state/focus-whiteboard-shape block-id)
      (redirect! {:to :whiteboard

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

@@ -178,7 +178,7 @@
                    (-> sequence ;; turn string into sequence
                        (string/trim)
                        (string/lower-case)
-                       (string/split  #" |\+"))
+                       (string/split  #" "))
                    sequence)]
     [:span.keyboard-shortcut
      (map-indexed (fn [i key]
@@ -192,7 +192,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]
@@ -239,7 +239,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
@@ -554,7 +554,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)]
@@ -583,9 +583,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?]
@@ -1018,6 +1017,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 size] :as opts}]
@@ -1033,7 +1036,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)}

+ 1 - 1
src/main/frontend/version.cljs

@@ -1,3 +1,3 @@
 (ns ^:no-doc frontend.version)
 
-(defonce version "0.9.13")
+(defonce version "0.9.14")

+ 2 - 2
src/resources/dicts/en.edn

@@ -149,8 +149,8 @@
  :right-side-bar/separator "Right sidebar resize handler"
  :right-side-bar/toggle-right-sidebar "Toggle right sidebar"
  :right-side-bar/pane-close "Close"
- :right-side-bar/pane-clese-others "Close others" 
- :right-side-bar/pane-clese-all "Close all"
+ :right-side-bar/pane-close-others "Close others"
+ :right-side-bar/pane-close-all "Close all"
  :right-side-bar/pane-collapse "Collapse"
  :right-side-bar/pane-collapse-others "Collapse others"
  :right-side-bar/pane-collapse-all "Collapse all"

+ 10 - 0
src/resources/dicts/es.edn

@@ -557,6 +557,16 @@
  :right-side-bar/history-undos                      "Deshacer"
  :right-side-bar/new-page                           "Nueva página"
  :right-side-bar/page-graph                         "Grafo de página"
+ :right-side-bar/pane-close-all                     "Cerrar todo"
+ :right-side-bar/pane-close-others                  "Cerrar otros"
+ :right-side-bar/pane-close                         "Cerrar"
+ :right-side-bar/pane-collapse-all                  "Colapsar todo"
+ :right-side-bar/pane-collapse                      "Colapsar"
+ :right-side-bar/pane-collapse-others               "Colapsar otros"
+ :right-side-bar/pane-expand-all                    "Expandir todo"
+ :right-side-bar/pane-expand                        "Expandir"
+ :right-side-bar/pane-more                          "Más"
+ :right-side-bar/pane-open-as-page                  "Abrir como página"
  :right-side-bar/separator                          "Right sidebar resize handler "
  :right-side-bar/show-journals                      "Mostrar Diarios"
  :right-side-bar/switch-theme                       "Temas"

+ 2 - 2
src/resources/dicts/ja.edn

@@ -149,8 +149,8 @@
  :right-side-bar/separator "右サイドバーのサイズ変更"
  :right-side-bar/toggle-right-sidebar "右サイドバーを開閉"
  :right-side-bar/pane-close "閉じる"
- :right-side-bar/pane-clese-others "他を全て閉じる"
- :right-side-bar/pane-clese-all "全て閉じる"
+ :right-side-bar/pane-close-others "他を全て閉じる"
+ :right-side-bar/pane-close-all "全て閉じる"
  :right-side-bar/pane-collapse "折り畳む"
  :right-side-bar/pane-collapse-others "他を全て折り畳む"
  :right-side-bar/pane-collapse-all "全て折り畳む"

+ 12 - 2
src/resources/dicts/nb-no.edn

@@ -682,7 +682,7 @@
  :flashcards/modal-welcome-desc-3 "klikk på denne lenken"
  :flashcards/modal-welcome-desc-4 " for å sjekke ut dokumentasjonen."
  :flashcards/modal-welcome-title "På tide å opprette et kort!"
- :graph/local-graphs "Lokale grafes:"
+ :graph/local-graphs "Lokale grafer:"
  :graph/remote-graphs "Fjerngrafer:"
  :left-side-bar/switch "Bytt til:"
  :on-boarding/command-palette-quick-tour "Rask Omvisning for onboarding"
@@ -783,4 +783,14 @@
  :right-side-bar/history-undos "Angret"
  :search-item/no-result "Ingen matchende resultat"
  :settings-permission/start-granting "Gi tillatelse"
- :whiteboard/edit-pdf "Rediger PDF"}
+ :whiteboard/edit-pdf "Rediger PDF"
+ :right-side-bar/pane-close-all "Lukk alle"
+ :right-side-bar/pane-close-others "Lukk andre"
+ :right-side-bar/pane-close "Lukk"
+ :right-side-bar/pane-collapse "Kollapse"
+ :right-side-bar/pane-collapse-all "Kollapse alle"
+ :right-side-bar/pane-collapse-others "Kollapse andre"
+ :right-side-bar/pane-expand "Ekspander"
+ :right-side-bar/pane-expand-all "Ekspander alle"
+ :right-side-bar/pane-more "Mer"
+ :right-side-bar/pane-open-as-page "Åpne som side"}

+ 2 - 2
tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx

@@ -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>

+ 3 - 3
tldraw/apps/tldraw-logseq/src/components/ToolButton/ToolButton.tsx

@@ -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