|
@@ -16,13 +16,16 @@
|
|
|
[frontend.config :as config]
|
|
|
[frontend.context.i18n :refer [t]]
|
|
|
[frontend.db :as db]
|
|
|
+ [electron.ipc :as ipc]
|
|
|
[frontend.db-mixins :as db-mixins]
|
|
|
[frontend.db.model :as db-model]
|
|
|
[frontend.extensions.pdf.utils :as pdf-utils]
|
|
|
+ [frontend.storage :as storage]
|
|
|
[frontend.extensions.srs :as srs]
|
|
|
[frontend.handler.common :as common-handler]
|
|
|
[frontend.handler.editor :as editor-handler]
|
|
|
[frontend.handler.page :as page-handler]
|
|
|
+ [frontend.util.page :as page-util]
|
|
|
[frontend.handler.route :as route-handler]
|
|
|
[frontend.handler.user :as user-handler]
|
|
|
[frontend.handler.whiteboard :as whiteboard-handler]
|
|
@@ -32,8 +35,10 @@
|
|
|
[frontend.mobile.mobile-bar :refer [mobile-bar]]
|
|
|
[frontend.mobile.util :as mobile-util]
|
|
|
[frontend.modules.shortcut.data-helper :as shortcut-dh]
|
|
|
+ [frontend.modules.shortcut.utils :as shortcut-utils]
|
|
|
[frontend.state :as state]
|
|
|
[frontend.ui :as ui]
|
|
|
+ [logseq.shui.ui :as shui]
|
|
|
[logseq.shui.toaster.core :as shui-toaster]
|
|
|
[logseq.shui.dialog.core :as shui-dialog]
|
|
|
[frontend.util :as util]
|
|
@@ -49,20 +54,16 @@
|
|
|
|
|
|
(rum/defc nav-content-item < rum/reactive
|
|
|
[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
|
|
|
+ (let [collapsed? (state/sub [:ui/navigation-item-collapsed? class])]
|
|
|
+ [:div.nav-content-item
|
|
|
{: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))}}
|
|
|
+ :has-children (and (number? count) (> count 0))}])}
|
|
|
[: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"})]
|
|
|
+ [:div.a name]
|
|
|
+ [:div.b (ui/icon "chevron-left" {:class "more" :size 14})]]
|
|
|
(when child [:div.bd child])]]))
|
|
|
|
|
|
(defn- delta-y
|
|
@@ -80,26 +81,60 @@
|
|
|
[name icon recent?]
|
|
|
(let [original-name (db-model/get-page-original-name name)
|
|
|
whiteboard-page? (db-model/whiteboard-page? name)
|
|
|
- untitiled? (db-model/untitled-page? name)]
|
|
|
- [:a.flex.items-center
|
|
|
- {:on-click
|
|
|
- (fn [e]
|
|
|
- (let [name (util/safe-page-name-sanity-lc name)
|
|
|
- source-page (db-model/get-alias-source-page (state/get-current-repo) name)
|
|
|
- name (if (empty? source-page) name (:block/name source-page))]
|
|
|
- (if (and (gobj/get e "shiftKey") (not whiteboard-page?))
|
|
|
- (when-let [page-entity (if (empty? source-page) (db/entity [:block/name name]) source-page)]
|
|
|
- (state/sidebar-add-block!
|
|
|
- (state/get-current-repo)
|
|
|
- (:db/id page-entity)
|
|
|
- :page))
|
|
|
- (if whiteboard-page?
|
|
|
- (route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
|
|
|
- (route-handler/redirect-to-page! name {:click-from-recent? recent?})))))}
|
|
|
- [: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))]]))
|
|
|
+ untitled? (db-model/untitled-page? name)
|
|
|
+ name (util/safe-page-name-sanity-lc name)
|
|
|
+ file-rpath (when (util/electron?) (page-util/get-page-file-rpath name))
|
|
|
+ source-page (db-model/get-alias-source-page (state/get-current-repo) name)
|
|
|
+ ctx-icon #(shui/tabler-icon %1 {:class "scale-90 pr-1 opacity-80"})
|
|
|
+ open-in-sidebar #(when-let [page-entity (and (not whiteboard-page?)
|
|
|
+ (if (empty? source-page)
|
|
|
+ (db/entity [:block/name name]) source-page))]
|
|
|
+ (state/sidebar-add-block!
|
|
|
+ (state/get-current-repo)
|
|
|
+ (:db/id page-entity)
|
|
|
+ :page))]
|
|
|
+ (shui/context-menu
|
|
|
+ (shui/context-menu-trigger
|
|
|
+ [:a.flex.items-center
|
|
|
+ {:on-click
|
|
|
+ (fn [e]
|
|
|
+ (let [name (if (empty? source-page) name (:block/name source-page))]
|
|
|
+ (if (gobj/get e "shiftKey")
|
|
|
+ (open-in-sidebar)
|
|
|
+ (if whiteboard-page?
|
|
|
+ (route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
|
|
|
+ (route-handler/redirect-to-page! name {:click-from-recent? recent?})))))}
|
|
|
+ [:span.page-icon.ml-3.justify-center (if whiteboard-page? (ui/icon "whiteboard" {:extension? true}) icon)]
|
|
|
+ [:span.page-title {:class (when untitled? "opacity-50")}
|
|
|
+ (if untitled? (t :untitled)
|
|
|
+ (pdf-utils/fix-local-asset-pagename original-name))]]
|
|
|
+ (shui/context-menu-content
|
|
|
+ {:class "w-60"}
|
|
|
+ (when-not recent?
|
|
|
+ (shui/context-menu-item
|
|
|
+ {:on-click #(page-handler/unfavorite-page! original-name)}
|
|
|
+ (ctx-icon "star-off")
|
|
|
+ (t :page/unfavorite)
|
|
|
+ (shui/context-menu-shortcut (some-> (shortcut-dh/shortcut-binding :command/toggle-favorite) (first)
|
|
|
+ (shortcut-utils/decorate-binding)))))
|
|
|
+ (when-let [page-fpath (and (util/electron?) file-rpath
|
|
|
+ (config/get-repo-fpath (state/get-current-repo) file-rpath))]
|
|
|
+ [:<>
|
|
|
+ (shui/context-menu-item
|
|
|
+ {:on-click #(ipc/ipc :openFileInFolder page-fpath)}
|
|
|
+ (ctx-icon "folder")
|
|
|
+ (t :page/open-in-finder))
|
|
|
+
|
|
|
+ (shui/context-menu-item
|
|
|
+ {:on-click #(js/window.apis.openPath page-fpath)}
|
|
|
+ (ctx-icon "file")
|
|
|
+ (t :page/open-with-default-app))])
|
|
|
+
|
|
|
+ (shui/context-menu-item
|
|
|
+ {:on-click open-in-sidebar}
|
|
|
+ (ctx-icon "layout-sidebar-right")
|
|
|
+ (t :content/open-in-sidebar)
|
|
|
+ (shui/context-menu-shortcut (shortcut-utils/decorate-binding "shift+click"))))))))
|
|
|
|
|
|
(defn get-page-icon [page-entity]
|
|
|
(let [default-icon (ui/icon "page" {:extension? true})
|
|
@@ -153,7 +188,7 @@
|
|
|
(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))]]
|
|
|
+ [:strong.flex-1.ml-2 (string/upper-case (t :left-side-bar/nav-favorites))]]
|
|
|
|
|
|
{:class "favorites"
|
|
|
:count (count favorite-entities)
|
|
@@ -179,7 +214,7 @@
|
|
|
(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
|
|
|
+ [:strong.flex-1.ml-2
|
|
|
(string/upper-case (t :left-side-bar/nav-recent-pages))]]
|
|
|
|
|
|
{:class "recent"
|
|
@@ -356,7 +391,7 @@
|
|
|
{:aria-label "Navigation menu"}
|
|
|
(repo/repos-dropdown)
|
|
|
|
|
|
- [:div.nav-header.flex.gap-1.flex-col.mt-3
|
|
|
+ [:div.nav-header.flex.flex-col.mt-2
|
|
|
(let [page (:page default-home)]
|
|
|
(if (and page (not (state/enable-journals? (state/get-current-repo))))
|
|
|
(sidebar-item
|
|
@@ -435,6 +470,44 @@
|
|
|
(neg? offset-ratio)
|
|
|
(+ 1))}))]]))
|
|
|
|
|
|
+(rum/defc sidebar-resizer
|
|
|
+ []
|
|
|
+ (let [*el-ref (rum/use-ref nil)
|
|
|
+ ^js el-doc js/document.documentElement
|
|
|
+ adjust-size! (fn [width]
|
|
|
+ (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)
|
|
|
+ (storage/set :ls-left-sidebar-width width))]
|
|
|
+
|
|
|
+ ;; restore size
|
|
|
+ (rum/use-layout-effect!
|
|
|
+ (fn []
|
|
|
+ (when-let [width (storage/get :ls-left-sidebar-width)]
|
|
|
+ (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)))
|
|
|
+ [])
|
|
|
+
|
|
|
+ ;; draggable handler
|
|
|
+ (rum/use-effect!
|
|
|
+ (fn []
|
|
|
+ (when-let [el (and (fn? js/window.interact) (rum/deref *el-ref))]
|
|
|
+ (let [^js sidebar-el (.querySelector el-doc "#left-sidebar")]
|
|
|
+ (-> (js/interact el)
|
|
|
+ (.draggable
|
|
|
+ #js {:listeners
|
|
|
+ #js {:move (fn [^js/MouseEvent e]
|
|
|
+ (when-let [offset (.-left (.-rect e))]
|
|
|
+ (let [width (.toFixed (max (min offset 460) 240) 2)]
|
|
|
+ (adjust-size! (str width "px")))))}})
|
|
|
+ (.styleCursor false)
|
|
|
+ (.on "dragstart" (fn []
|
|
|
+ (.. sidebar-el -classList (add "is-resizing"))
|
|
|
+ (.. el-doc -classList (add "is-resizing-buf"))))
|
|
|
+ (.on "dragend" (fn []
|
|
|
+ (.. sidebar-el -classList (remove "is-resizing"))
|
|
|
+ (.. el-doc -classList (remove "is-resizing-buf"))))))
|
|
|
+ #()))
|
|
|
+ [])
|
|
|
+ [:span.left-sidebar-resizer {:ref *el-ref}]))
|
|
|
+
|
|
|
(rum/defcs left-sidebar < rum/reactive
|
|
|
(rum/local false ::closing?)
|
|
|
(rum/local -1 ::close-signal)
|
|
@@ -477,7 +550,9 @@
|
|
|
|
|
|
;; sidebar contents
|
|
|
(sidebar-nav route-match close-fn left-sidebar-open? enable-whiteboards? srs-open? *closing?
|
|
|
- @*close-signal (and touch-pending? touching-x-offset))]))
|
|
|
+ @*close-signal (and touch-pending? touching-x-offset))
|
|
|
+ ;; resizer
|
|
|
+ (sidebar-resizer)]))
|
|
|
|
|
|
(rum/defc recording-bar
|
|
|
[]
|