Explorar o código

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

charlie hai 1 ano
pai
achega
5cf8915f6e

+ 99 - 8
src/main/frontend/components/container.cljs

@@ -15,6 +15,9 @@
             [frontend.components.dnd :as dnd-component]
             [frontend.components.dnd :as dnd-component]
             [frontend.components.icon :as icon]
             [frontend.components.icon :as icon]
             [frontend.components.handbooks :as handbooks]
             [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.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
             [frontend.db :as db]
@@ -32,6 +35,9 @@
             [frontend.handler.user :as user-handler]
             [frontend.handler.user :as user-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.handler.recent :as recent-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.mixins :as mixins]
             [frontend.mobile.action-bar :as action-bar]
             [frontend.mobile.action-bar :as action-bar]
             [frontend.mobile.footer :as footer]
             [frontend.mobile.footer :as footer]
@@ -42,6 +48,8 @@
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [logseq.shui.ui :as shui]
             [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.toaster.core :as shui-toaster]
             [logseq.shui.dialog.core :as shui-dialog]
             [logseq.shui.dialog.core :as shui-dialog]
             [logseq.shui.popup.core :as shui-popup]
             [logseq.shui.popup.core :as shui-popup]
@@ -127,10 +135,12 @@
             (if whiteboard-page?
             (if whiteboard-page?
               (route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
               (route-handler/redirect-to-whiteboard! name {:click-from-recent? recent?})
               (route-handler/redirect-to-page! 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-icon.ml-3.justify-center (if whiteboard-page? (ui/icon "whiteboard" {:extension? true}) icon)]
      [:span.page-title {:class (when untitled? "opacity-50")}
      [:span.page-title {:class (when untitled? "opacity-50")}
       (if untitled? (t :untitled)
       (if untitled? (t :untitled)
@@ -728,6 +738,16 @@
                :left (str (first position) "px")
                :left (str (first position) "px")
                :top (str (second position) "px")}} links]]))
                :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
 (rum/defc custom-context-menu < rum/reactive
   []
   []
   (let [show? (state/sub :custom-context-menu/show?)
   (let [show? (state/sub :custom-context-menu/show?)
@@ -822,6 +842,74 @@
      (when handbooks-open?
      (when handbooks-open?
        (handbooks/handbooks-popup))]))
        (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 <
 (rum/defcs ^:large-vars/cleanup-todo sidebar <
   (mixins/modal :modal/show?)
   (mixins/modal :modal/show?)
   rum/reactive
   rum/reactive
@@ -944,10 +1032,13 @@
 
 
       (select/select-modal)
       (select/select-modal)
       (custom-context-menu)
       (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]
       [:a#download.hidden]
       (when (and (not config/mobile?)
       (when (and (not config/mobile?)
                  (not config/publishing?))
                  (not config/publishing?))

+ 0 - 58
src/main/frontend/components/content.cljs

@@ -386,64 +386,6 @@
 ;; Also, keyboard bindings should only be activated after
 ;; Also, keyboard bindings should only be activated after
 ;; blocks were already selected.
 ;; blocks were already selected.
 (rum/defc hiccup-content < rum/static
 (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]}]
   [id {:keys [hiccup]}]
   [:div {:id id}
   [:div {:id id}
    (if hiccup
    (if hiccup