enhance(ux): refactor the app context menu to the shui popup

pull/11055/head
charlie 2024-03-18 16:33:30 +08:00
parent d50e1dee97
commit 5cf8915f6e
2 changed files with 99 additions and 66 deletions

View File

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

View File

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