mirror of https://github.com/logseq/logseq
add reordering support
parent
d47c4d2c28
commit
79bf300dcb
|
@ -618,7 +618,23 @@ html[data-theme='dark'] {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-drop-area {
|
||||||
|
@apply relative;
|
||||||
|
height: 8px;
|
||||||
|
|
||||||
|
&.drag-over {
|
||||||
|
&::after {
|
||||||
|
@apply absolute block w-full;
|
||||||
|
top: 2px;
|
||||||
|
height: 4px;
|
||||||
|
content: " ";
|
||||||
|
background-color: var(--ls-active-primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-item {
|
.sidebar-item {
|
||||||
|
@apply relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
|
@ -637,8 +653,12 @@ html[data-theme='dark'] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.drag-over {
|
.sidebar-item-drop-overlay-wrapper {
|
||||||
border-color: var(--ls-active-primary-color);
|
@apply flex flex-col absolute h-full w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item-drop-overlay {
|
||||||
|
flex: 1 1 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.item-type-block .sidebar-item-header {
|
&.item-type-block .sidebar-item-header {
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[frontend.components.onboarding :as onboarding]
|
[frontend.components.onboarding :as onboarding]
|
||||||
[frontend.components.page :as page]
|
[frontend.components.page :as page]
|
||||||
[frontend.components.shortcut :as shortcut]
|
[frontend.components.shortcut :as shortcut]
|
||||||
[frontend.components.svg :as svg]
|
|
||||||
[frontend.context.i18n :refer [t]]
|
[frontend.context.i18n :refer [t]]
|
||||||
[frontend.date :as date]
|
[frontend.date :as date]
|
||||||
[frontend.db :as db]
|
[frontend.db :as db]
|
||||||
|
@ -173,20 +172,20 @@
|
||||||
(atom nil))
|
(atom nil))
|
||||||
|
|
||||||
(rum/defc context-menu-content
|
(rum/defc context-menu-content
|
||||||
[db-id idx collapsed?]
|
[db-id idx collapsed? block-count]
|
||||||
[:.menu-links-wrapper
|
[:.menu-links-wrapper
|
||||||
(ui/menu-link {:on-click #(state/sidebar-remove-block! idx)} "Close" nil)
|
(ui/menu-link {:on-click #(state/sidebar-remove-block! idx)} "Close" nil)
|
||||||
(ui/menu-link {:on-click #(state/sidebar-remove-rest! db-id)} "Close others" nil)
|
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-remove-rest! db-id)} "Close others" nil))
|
||||||
(ui/menu-link {:on-click (fn []
|
(when (> block-count 1) (ui/menu-link {:on-click (fn []
|
||||||
(state/clear-sidebar-blocks!)
|
(state/clear-sidebar-blocks!)
|
||||||
(state/hide-right-sidebar!))} "Close all" nil)
|
(state/hide-right-sidebar!))} "Close all" nil))
|
||||||
[:hr.menu-separator]
|
[:hr.menu-separator]
|
||||||
(when-not collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} "Collapse" nil))
|
(when-not collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} "Collapse" nil))
|
||||||
(ui/menu-link {:on-click #(state/sidebar-block-collapse-rest! db-id)} "Collapse others" nil)
|
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-collapse-rest! db-id)} "Collapse others" nil))
|
||||||
(ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! true)} "Collapse all" nil)
|
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! true)} "Collapse all" nil))
|
||||||
[:hr.menu-separator]
|
(when (or collapsed? (> block-count 1)) [:hr.menu-separator])
|
||||||
(when collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} "Expand" nil))
|
(when collapsed? (ui/menu-link {:on-click #(state/sidebar-block-toggle-collapse! db-id)} "Expand" nil))
|
||||||
(ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! false)} "Expand all" nil)
|
(when (> block-count 1) (ui/menu-link {:on-click #(state/sidebar-block-set-collapsed-all! false)} "Expand all" nil))
|
||||||
(when (integer? db-id) [:hr.menu-separator])
|
(when (integer? db-id) [:hr.menu-separator])
|
||||||
(when (integer? db-id)
|
(when (integer? db-id)
|
||||||
(let [name (:block/name (db/entity db-id))]
|
(let [name (:block/name (db/entity db-id))]
|
||||||
|
@ -194,55 +193,70 @@
|
||||||
(rfe/href :whiteboard {:name name})
|
(rfe/href :whiteboard {:name name})
|
||||||
(rfe/href :page {:name name}))} "Open as page" nil)))])
|
(rfe/href :page {:name name}))} "Open as page" nil)))])
|
||||||
|
|
||||||
|
(rum/defc drop-area
|
||||||
|
[idx drag-to]
|
||||||
|
[:.sidebar-drop-area {:id (str "drop-area-" idx)
|
||||||
|
:on-drag-over #(when (not= drag-to idx) (reset! *drag-to idx))
|
||||||
|
:class (when (= idx drag-to) "drag-over")}])
|
||||||
|
|
||||||
(rum/defc sidebar-item < rum/reactive
|
(rum/defc sidebar-item < rum/reactive
|
||||||
[repo idx db-id block-type]
|
[repo idx db-id block-type block-count]
|
||||||
(let [item (build-sidebar-item repo idx db-id block-type)
|
(let [item (build-sidebar-item repo idx db-id block-type)
|
||||||
drag-to (rum/react *drag-to)
|
drag-to (rum/react *drag-to)
|
||||||
drag-from (rum/react *drag-from)]
|
drag-from (rum/react *drag-from)]
|
||||||
(when item
|
(when item
|
||||||
(let [collapsed? (state/sub [:ui/sidebar-collapsed-blocks db-id])]
|
(let [collapsed? (state/sub [:ui/sidebar-collapsed-blocks db-id])]
|
||||||
[:div.flex.sidebar-item.content.color-level.shadow-md.rounded
|
[:<>
|
||||||
{:class [(str "item-type-" (name block-type))
|
(when (zero? idx) (drop-area (dec idx) drag-to))
|
||||||
(when collapsed? "collapsed")
|
[:div.flex.sidebar-item.content.color-level.shadow-md.rounded
|
||||||
(when (and (= idx drag-to) (not= drag-to drag-from)) "drag-over")]}
|
{:class [(str "item-type-" (name block-type))
|
||||||
(let [[title component] item
|
(when collapsed? "collapsed")]}
|
||||||
page-name (if (integer? db-id)
|
(let [[title component] item
|
||||||
(:block/name (db/entity db-id))
|
page-name (if (integer? db-id)
|
||||||
db-id)]
|
(:block/name (db/entity db-id))
|
||||||
[:div.flex.flex-col.w-full
|
db-id)]
|
||||||
[:button.flex.flex-row.justify-between.p-2.sidebar-item-header.color-level
|
[:div.flex.flex-col.w-full.relative
|
||||||
{:draggable true
|
[:button.flex.flex-row.justify-between.p-2.sidebar-item-header.color-level
|
||||||
:on-drag-leave #(reset! *drag-to nil)
|
{:draggable true
|
||||||
:on-drag-over #(reset! *drag-to idx)
|
:on-drag-start (fn [event]
|
||||||
:on-drag-start (fn [event]
|
(editor-handler/block->data-transfer! page-name event)
|
||||||
(editor-handler/block->data-transfer! page-name event)
|
(reset! *drag-from idx))
|
||||||
(reset! *drag-from idx))
|
:on-drag-end (fn [_event]
|
||||||
:on-drag-end (fn [_event]
|
(state/sidebar-move-block! idx drag-to)
|
||||||
(reset! *drag-to nil)
|
(reset! *drag-to nil)
|
||||||
(reset! *drag-from nil))
|
(reset! *drag-from nil))
|
||||||
:on-click (fn [event]
|
:on-click (fn [event]
|
||||||
(.preventDefault event)
|
(.preventDefault event)
|
||||||
(state/sidebar-block-toggle-collapse! db-id))
|
(state/sidebar-block-toggle-collapse! db-id))
|
||||||
:on-mouse-up (fn [event]
|
:on-mouse-up (fn [event]
|
||||||
(when (= (.-which (.-nativeEvent event)) 2)
|
(when (= (.-which (.-nativeEvent event)) 2)
|
||||||
(state/sidebar-remove-block! idx)))
|
(state/sidebar-remove-block! idx)))
|
||||||
:on-context-menu (fn [e]
|
:on-context-menu (fn [e]
|
||||||
(util/stop e)
|
(util/stop e)
|
||||||
(common-handler/show-custom-context-menu! e (context-menu-content db-id idx collapsed?)))}
|
(common-handler/show-custom-context-menu! e (context-menu-content db-id idx collapsed? block-count)))}
|
||||||
[:div.flex.flex-row.overflow-hidden
|
[:div.flex.flex-row.overflow-hidden
|
||||||
[:span.opacity-50.hover:opacity-100.flex.items-center.pr-1
|
[:span.opacity-50.hover:opacity-100.flex.items-center.pr-1
|
||||||
(ui/rotating-arrow collapsed?)]
|
(ui/rotating-arrow collapsed?)]
|
||||||
[:div.ml-1.font-medium.overflow-hidden
|
[:div.ml-1.font-medium.overflow-hidden
|
||||||
title]]
|
title]]
|
||||||
[:.item-actions.flex
|
[:.item-actions.flex
|
||||||
(ui/dropdown (fn [{:keys [toggle-fn]}]
|
(ui/dropdown (fn [{:keys [toggle-fn]}]
|
||||||
[:button.button {:on-click (fn [e]
|
[:button.button {:on-click (fn [e]
|
||||||
(util/stop e)
|
(util/stop e)
|
||||||
(toggle-fn))} (ui/icon "dots")])
|
(toggle-fn))} (ui/icon "dots")])
|
||||||
#(context-menu-content db-id idx collapsed?))
|
#(context-menu-content db-id idx collapsed? block-count))
|
||||||
[:button.button.close {:on-click #(state/sidebar-remove-block! idx)} (ui/icon "x")]]]
|
[:button.button.close {:on-click #(state/sidebar-remove-block! idx)} (ui/icon "x")]]]
|
||||||
[:div.scrollbar-spacing.p-4 {:class (if collapsed? "hidden" "initial")}
|
[:div.scrollbar-spacing.p-4 {:class (if collapsed? "hidden" "initial")}
|
||||||
component]])]))))
|
component]
|
||||||
|
(when drag-from
|
||||||
|
[:.sidebar-item-drop-overlay-wrapper
|
||||||
|
[:.sidebar-item-drop-overlay.top
|
||||||
|
{:on-drag-over #(when (not= drag-to (dec idx))
|
||||||
|
(reset! *drag-to (dec idx)))}]
|
||||||
|
[:.sidebar-item-drop-overlay.bottom
|
||||||
|
{:on-drag-over #(when (not= drag-to idx)
|
||||||
|
(reset! *drag-to idx))}]])])]
|
||||||
|
(drop-area idx drag-to)]))))
|
||||||
|
|
||||||
(defn- get-page
|
(defn- get-page
|
||||||
[match]
|
[match]
|
||||||
|
@ -354,7 +368,8 @@
|
||||||
(js/setTimeout (fn [] (reset! (get state ::anim-finished?) true)) 300)
|
(js/setTimeout (fn [] (reset! (get state ::anim-finished?) true)) 300)
|
||||||
state)}
|
state)}
|
||||||
[state repo t blocks]
|
[state repo t blocks]
|
||||||
(let [*anim-finished? (get state ::anim-finished?)]
|
(let [*anim-finished? (get state ::anim-finished?)
|
||||||
|
block-count (count blocks)]
|
||||||
[:div.cp__right-sidebar-inner.flex.flex-col.h-full#right-sidebar-container
|
[:div.cp__right-sidebar-inner.flex.flex-col.h-full#right-sidebar-container
|
||||||
|
|
||||||
[:div.cp__right-sidebar-scrollable
|
[:div.cp__right-sidebar-scrollable
|
||||||
|
@ -362,21 +377,21 @@
|
||||||
[:div.cp__right-sidebar-settings.hide-scrollbar.gap-1 {:key "right-sidebar-settings"}
|
[:div.cp__right-sidebar-settings.hide-scrollbar.gap-1 {:key "right-sidebar-settings"}
|
||||||
[:div.text-sm
|
[:div.text-sm
|
||||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
||||||
(state/sidebar-add-block! repo "contents" :contents))}
|
(state/sidebar-add-block! repo "contents" :contents))}
|
||||||
(t :right-side-bar/contents)]]
|
(t :right-side-bar/contents)]]
|
||||||
|
|
||||||
[:div.text-sm
|
[:div.text-sm
|
||||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn []
|
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn []
|
||||||
(when-let [page (get-current-page)]
|
(when-let [page (get-current-page)]
|
||||||
(state/sidebar-add-block!
|
(state/sidebar-add-block!
|
||||||
repo
|
repo
|
||||||
page
|
page
|
||||||
:page-graph)))}
|
:page-graph)))}
|
||||||
(t :right-side-bar/page-graph)]]
|
(t :right-side-bar/page-graph)]]
|
||||||
|
|
||||||
[:div.text-sm
|
[:div.text-sm
|
||||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
||||||
(state/sidebar-add-block! repo "help" :help))}
|
(state/sidebar-add-block! repo "help" :help))}
|
||||||
(t :right-side-bar/help)]]
|
(t :right-side-bar/help)]]
|
||||||
|
|
||||||
(when (and config/dev? (state/sub [:ui/developer-mode?]))
|
(when (and config/dev? (state/sub [:ui/developer-mode?]))
|
||||||
|
@ -385,11 +400,12 @@
|
||||||
(state/sidebar-add-block! repo "history" :history))}
|
(state/sidebar-add-block! repo "history" :history))}
|
||||||
(t :right-side-bar/history)]])]]
|
(t :right-side-bar/history)]])]]
|
||||||
|
|
||||||
[:.sidebar-item-list.flex-1.scrollbar-spacing.flex.flex-col.gap-2.pb-2.mx-2
|
[:.sidebar-item-list.flex-1.scrollbar-spacing.flex.flex-col.mx-2
|
||||||
|
{:on-drag-leave #(reset! *drag-to nil)}
|
||||||
(if @*anim-finished?
|
(if @*anim-finished?
|
||||||
(for [[idx [repo db-id block-type]] (medley/indexed blocks)]
|
(for [[idx [repo db-id block-type]] (medley/indexed blocks)]
|
||||||
(rum/with-key
|
(rum/with-key
|
||||||
(sidebar-item repo idx db-id block-type)
|
(sidebar-item repo idx db-id block-type block-count)
|
||||||
(str "sidebar-block-" idx)))
|
(str "sidebar-block-" idx)))
|
||||||
[:div.p-4
|
[:div.p-4
|
||||||
[:span.font-medium.opacity-50 "Loading ..."]])]]]))
|
[:span.font-medium.opacity-50 "Loading ..."]])]]]))
|
||||||
|
|
|
@ -16,7 +16,8 @@ html[data-theme=light] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-item-list {
|
.sidebar-item-list {
|
||||||
height: calc(100vh - 48px);
|
margin-top: -8px;
|
||||||
|
height: calc(100vh - 40px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1092,6 +1092,17 @@ Similar to re-frame subscriptions"
|
||||||
(when-let [elem (gdom/getElementByClass "sidebar-item-list")]
|
(when-let [elem (gdom/getElementByClass "sidebar-item-list")]
|
||||||
(util/scroll-to elem 0)))))
|
(util/scroll-to elem 0)))))
|
||||||
|
|
||||||
|
(defn sidebar-move-block!
|
||||||
|
[idx move-to]
|
||||||
|
(update-state! :sidebar/blocks (fn [blocks]
|
||||||
|
(let [move-to (if (> idx move-to) (inc move-to) move-to)]
|
||||||
|
(if (and move-to (not= move-to idx))
|
||||||
|
(let [item (nth blocks idx)
|
||||||
|
blocks (keep-indexed #(when (not= %1 idx) %2) blocks)
|
||||||
|
[l r] (split-at move-to blocks)]
|
||||||
|
(concat l [item] r))
|
||||||
|
blocks)))))
|
||||||
|
|
||||||
(defn sidebar-remove-block!
|
(defn sidebar-remove-block!
|
||||||
[idx]
|
[idx]
|
||||||
(update-state! :sidebar/blocks (fn [blocks]
|
(update-state! :sidebar/blocks (fn [blocks]
|
||||||
|
|
Loading…
Reference in New Issue