mirror of https://github.com/logseq/logseq
enhance(ux): refactor the app context menu to the shui popup
parent
d50e1dee97
commit
5cf8915f6e
|
@ -15,6 +15,9 @@
|
|||
[frontend.components.dnd :as dnd-component]
|
||||
[frontend.components.icon :as icon]
|
||||
[frontend.components.handbooks :as handbooks]
|
||||
[dommy.core :as d]
|
||||
[frontend.components.page-menu :as page-menu]
|
||||
[frontend.components.content :as cp-content]
|
||||
[frontend.config :as config]
|
||||
[frontend.context.i18n :refer [t]]
|
||||
[frontend.db :as db]
|
||||
|
@ -32,6 +35,9 @@
|
|||
[frontend.handler.user :as user-handler]
|
||||
[frontend.handler.whiteboard :as whiteboard-handler]
|
||||
[frontend.handler.recent :as recent-handler]
|
||||
[frontend.handler.property :as property-handler]
|
||||
[frontend.handler.property.util :as pu]
|
||||
[frontend.components.export :as export]
|
||||
[frontend.mixins :as mixins]
|
||||
[frontend.mobile.action-bar :as action-bar]
|
||||
[frontend.mobile.footer :as footer]
|
||||
|
@ -42,6 +48,8 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[logseq.shui.ui :as shui]
|
||||
[logseq.common.util.block-ref :as block-ref]
|
||||
[frontend.util.url :as url-util]
|
||||
[logseq.shui.toaster.core :as shui-toaster]
|
||||
[logseq.shui.dialog.core :as shui-dialog]
|
||||
[logseq.shui.popup.core :as shui-popup]
|
||||
|
@ -127,10 +135,12 @@
|
|||
(if whiteboard-page?
|
||||
(route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
|
||||
(route-handler/redirect-to-page! name {:click-from-recent? recent?})))))
|
||||
:on-context-menu #(shui/popup-show! (.-target %) (x-menu-content)
|
||||
{:as-dropdown? true
|
||||
:content-props {:on-click (fn [] (shui/popup-hide!))
|
||||
:class "w-60"}})}
|
||||
:on-context-menu (fn [^js e]
|
||||
(shui/popup-show! e (x-menu-content)
|
||||
{:as-dropdown? true
|
||||
:content-props {:on-click (fn [] (shui/popup-hide!))
|
||||
:class "w-60"}})
|
||||
(util/stop e))}
|
||||
[: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)
|
||||
|
@ -728,6 +738,16 @@
|
|||
:left (str (first position) "px")
|
||||
:top (str (second position) "px")}} links]]))
|
||||
|
||||
(rum/defc page-title-custom-context-menu-content
|
||||
[page]
|
||||
(when-not (string/blank? page)
|
||||
(let [page-menu-options (page-menu/page-menu page)]
|
||||
[:.menu-links-wrapper
|
||||
(for [{:keys [title options]} page-menu-options]
|
||||
(rum/with-key
|
||||
(ui/menu-link options title)
|
||||
title))])))
|
||||
|
||||
(rum/defc custom-context-menu < rum/reactive
|
||||
[]
|
||||
(let [show? (state/sub :custom-context-menu/show?)
|
||||
|
@ -822,6 +842,74 @@
|
|||
(when handbooks-open?
|
||||
(handbooks/handbooks-popup))]))
|
||||
|
||||
(rum/defc app-context-menu-observer
|
||||
< rum/static
|
||||
(mixins/event-mixin
|
||||
(fn [state]
|
||||
;; fixme: this mixin will register global event listeners on window
|
||||
;; which might cause unexpected issues
|
||||
(mixins/listen state js/window "contextmenu"
|
||||
(fn [e]
|
||||
(let [target (gobj/get e "target")
|
||||
block-el (.closest target ".bullet-container[blockid]")
|
||||
block-id (some-> block-el (.getAttribute "blockid"))
|
||||
{:keys [block block-ref]} (state/sub :block-ref/context)
|
||||
{:keys [page]} (state/sub :page-title/context)]
|
||||
|
||||
(let [handled (cond
|
||||
page
|
||||
(do
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(cp-content/page-title-custom-context-menu-content page)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
(state/set-state! :page-title/context nil))
|
||||
|
||||
block-ref
|
||||
(do
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(cp-content/block-ref-custom-context-menu-content block block-ref)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
(state/set-state! :block-ref/context nil))
|
||||
|
||||
;; block selection
|
||||
(and (state/selection?) (not (d/has-class? target "bullet")))
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(cp-content/custom-context-menu-content)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
|
||||
;; block bullet
|
||||
(and block-id (parse-uuid block-id))
|
||||
(let [block (.closest target ".ls-block")]
|
||||
(when block
|
||||
(state/clear-selection!)
|
||||
(state/conj-selection-block! block :down))
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(cp-content/block-context-menu-content target (uuid block-id))])
|
||||
{:content-props {:class "ls-context-menu-content"}}))
|
||||
|
||||
:else
|
||||
false)]
|
||||
(when (not (false? handled))
|
||||
(util/stop e))))))))
|
||||
[]
|
||||
nil)
|
||||
|
||||
(rum/defcs ^:large-vars/cleanup-todo sidebar <
|
||||
(mixins/modal :modal/show?)
|
||||
rum/reactive
|
||||
|
@ -944,10 +1032,13 @@
|
|||
|
||||
(select/select-modal)
|
||||
(custom-context-menu)
|
||||
(plugins/custom-js-installer {:t t
|
||||
:current-repo current-repo
|
||||
:nfs-granted? granted?
|
||||
:db-restoring? db-restoring?})
|
||||
(plugins/custom-js-installer
|
||||
{:t t
|
||||
:current-repo current-repo
|
||||
:nfs-granted? granted?
|
||||
:db-restoring? db-restoring?})
|
||||
(app-context-menu-observer)
|
||||
|
||||
[:a#download.hidden]
|
||||
(when (and (not config/mobile?)
|
||||
(not config/publishing?))
|
||||
|
|
|
@ -386,64 +386,6 @@
|
|||
;; Also, keyboard bindings should only be activated after
|
||||
;; blocks were already selected.
|
||||
(rum/defc hiccup-content < rum/static
|
||||
(mixins/event-mixin
|
||||
(fn [state]
|
||||
;; fixme: this mixin will register global event listeners on window
|
||||
;; which might cause unexpected issues
|
||||
(mixins/listen state js/window "contextmenu"
|
||||
(fn [e]
|
||||
(let [target (gobj/get e "target")
|
||||
block-el (.closest target ".bullet-container[blockid]")
|
||||
block-id (some-> block-el (.getAttribute "blockid"))
|
||||
{:keys [block block-ref]} (state/sub :block-ref/context)
|
||||
{:keys [page]} (state/sub :page-title/context)]
|
||||
(cond
|
||||
page
|
||||
(do
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(page-title-custom-context-menu-content page)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
(state/set-state! :page-title/context nil))
|
||||
|
||||
block-ref
|
||||
(do
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(block-ref-custom-context-menu-content block block-ref)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
(state/set-state! :block-ref/context nil))
|
||||
|
||||
(and (state/selection?) (not (d/has-class? target "bullet")))
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(custom-context-menu-content)])
|
||||
{:content-props {:class "ls-context-menu-content"}})
|
||||
|
||||
(and block-id (parse-uuid block-id))
|
||||
(let [block (.closest target ".ls-block")]
|
||||
(when block
|
||||
(state/clear-selection!)
|
||||
(state/conj-selection-block! block :down))
|
||||
(shui/popup-show!
|
||||
e
|
||||
(fn [{:keys [id]}]
|
||||
[:div
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(block-context-menu-content target (uuid block-id))])
|
||||
{:content-props {:class "ls-context-menu-content"}}))
|
||||
|
||||
:else
|
||||
nil))))))
|
||||
[id {:keys [hiccup]}]
|
||||
[:div {:id id}
|
||||
(if hiccup
|
||||
|
|
Loading…
Reference in New Issue