Procházet zdrojové kódy

enhance(ux): use sidebar sheet instead of persistent sheet

Pros:
1. clicking outside to close sidebar works
2. doesn't have to swipe from the edge

Cons:
1. sidebar animation doesn't follow the gesture, we'll see how to fix
this later
Tienson Qin před 4 měsíci
rodič
revize
51e62b0039

+ 57 - 0
src/main/mobile/components/app.cljs

@@ -40,8 +40,64 @@
    [:div.pt-3
     (journal/all-journals)]))
 
+(defn- setup-sidebar-touch-swipe!
+  []
+  (let [touch-start-x (atom 0)
+        touch-start-y (atom 0)
+        has-triggered? (atom false)
+        blocking-scroll? (atom false)
+
+        swipe-trigger-distance 50         ;; when to actually open sidebar
+        horiz-intent-threshold 10         ;; when to start blocking scroll
+        max-vertical-drift 50
+
+        on-touch-start (fn [^js e]
+                         (let [t (aget e "touches" 0)]
+                           (reset! touch-start-x (.-pageX t))
+                           (reset! touch-start-y (.-pageY t))
+                           (reset! has-triggered? false)
+                           (reset! blocking-scroll? false)))
+
+        on-touch-move (fn [^js e]
+                        (let [t (aget e "touches" 0)
+                              dx (- (.-pageX t) @touch-start-x)
+                              dy (js/Math.abs (- (.-pageY t) @touch-start-y))
+                              horizontal-intent (and (> dx horiz-intent-threshold)
+                                                     (> dx dy))
+                              is-horizontal-swipe (and (> dx swipe-trigger-distance)
+                                                       (< dy max-vertical-drift))]
+
+                          ;; as soon as we detect horizontal intent, block vertical scrolling
+                          (when (or @blocking-scroll? horizontal-intent)
+                            (reset! blocking-scroll? true)
+                            (.preventDefault e))       ;; <-- stops page from scrolling
+
+                          (when (and (not @has-triggered?)
+                                     is-horizontal-swipe)
+                            (reset! has-triggered? true)
+                            (mobile-state/open-left-sidebar!))))
+
+        on-touch-end (fn [_]
+                       (reset! blocking-scroll? false))]
+
+    ;; IMPORTANT: passive:false so preventDefault actually works
+    (.addEventListener js/document "touchstart" on-touch-start #js {:passive false})
+    (.addEventListener js/document "touchmove"  on-touch-move  #js {:passive false})
+    (.addEventListener js/document "touchend"   on-touch-end   #js {:passive false})
+    (.addEventListener js/document "touchcancel" on-touch-end  #js {:passive false})
+
+    ;; cleanup
+    #(do
+       (.removeEventListener js/document "touchstart" on-touch-start)
+       (.removeEventListener js/document "touchmove"  on-touch-move)
+       (.removeEventListener js/document "touchend"   on-touch-end)
+       (.removeEventListener js/document "touchcancel" on-touch-end))))
+
 (rum/defc home-inner
   [*page db-restoring? current-tab]
+  (hooks/use-effect!
+   (fn []
+     (setup-sidebar-touch-swipe!)) [])
   [:div {:id "app-main-content"
          :ref *page}
 
@@ -107,6 +163,7 @@
     (use-theme-effects! current-repo)
     (hooks/use-effect!
      (fn []
+       (setup-sidebar-touch-swipe!)
        (when-let [element (util/mobile-page-scroll)]
          (common-handler/listen-to-scroll! element))) [])
     (silkhq/depth-sheet-stack

+ 17 - 62
src/main/mobile/components/left_sidebar.cljs

@@ -1,10 +1,6 @@
 (ns mobile.components.left-sidebar
   "Mobile left sidebar"
-  (:require [cljs-bean.core :as bean]
-            [dommy.core :as dom]
-            [frontend.components.left-sidebar :as app-left-sidebar]
-            [frontend.rum :as r]
-            [logseq.shui.hooks :as hooks]
+  (:require [frontend.components.left-sidebar :as app-left-sidebar]
             [logseq.shui.silkhq :as silkhq]
             [mobile.state :as mobile-state]
             [rum.core :as rum]))
@@ -13,66 +9,25 @@
   []
   [:div.w-full.app-silk-popup-content-inner.px-2
    [:div.left-sidebar-inner
-    [:div.sidebar-contents-container
+    [:div.sidebar-contents-container.mt-8
      {:class "!gap-4"}
      (app-left-sidebar/sidebar-favorites)
      (app-left-sidebar/sidebar-recent-pages)]]])
 
-(rum/defc left-sidebar-inner
-  []
-  (let [*ref (hooks/use-ref nil)
-        [detent set-detent!] (r/use-atom mobile-state/*left-sidebar-detent)
-        [inertOutside setInertOutside!] (r/use-atom mobile-state/*left-sidebar-inert-outside?)
-        left-padding 25
-        [first-detent set-first-detent!] (hooks/use-state left-padding)]
-
-    (hooks/use-effect!
-     (fn []
-       (when (zero? detent)
-         (set-detent! 1)))
-     [])
-
-    (silkhq/persistent-sheet
-     {:key "left sidebar"
-      :sheetRole "alertdialog"
-      :presented true
-      :onPresentedChange (fn [_v])
-      :activeDetent detent
-      :onActiveDetentChange (fn [v]
-                              (when v
-                                (set-detent! (if (zero? v) 1 v))))}
-     (silkhq/persistent-sheet-portal
-      (silkhq/persistent-sheet-view
-       {:class "app-silk-sidebar-sheet-view"
-        :contentPlacement "left"
-        :detents [(str first-detent "px") "min(90vw, 325px)"]
-        :onTravel (fn [v]
-                    (when (empty? @mobile-state/*modal-blocks)
-                      (let [{:keys [range]} (bean/->clj v)
-                            {:keys [start end]} range
-                            ref (.-current *ref)]
-                        (when ref
-                          (cond
-                            (and (>= start 1) (>= end 2))
-                            (do
-                              (dom/remove-class! ref "Sidebar-hidden")
-                              (setInertOutside! true)
-                              (set-first-detent! 0))
-
-                            (and (<= start 1) (<= end 1))
-                            (do
-                              (dom/add-class! ref "Sidebar-hidden")
-                              (setInertOutside! false)
-                              (set-first-detent! left-padding)))))))
-        :inertOutside inertOutside}
-       (silkhq/persistent-sheet-content
-        {:ref *ref
-         :class "app-silk-sidebar-sheet-content Sidebar-content Sidebar-hidden"}
-        (silkhq/persistent-sheet-expanded-content
-         (sidebar-content))))))))
-
 (rum/defc left-sidebar < rum/reactive
   []
-  (when (rum/react mobile-state/*left-sidebar-open?)
-    (when (empty? (rum/react mobile-state/*modal-blocks))
-      (left-sidebar-inner))))
+  (when (empty? (rum/react mobile-state/*modal-blocks))
+    (let [open? (rum/react mobile-state/*left-sidebar-open?)]
+      (silkhq/sidebar-sheet
+       {:presented (boolean open?)
+        :onPresentedChange (fn [v]
+                             (when (false? v)
+                               (mobile-state/close-left-sidebar!)))}
+       (silkhq/sidebar-sheet-portal
+        (silkhq/sidebar-sheet-view
+         {:class "app-silk-sidebar-sheet-view"}
+         (silkhq/sidebar-sheet-backdrop)
+         (silkhq/sidebar-sheet-content
+          {:class "app-silk-sidebar-sheet-content"}
+          (silkhq/sidebar-sheet-handle)
+          (sidebar-content))))))))

+ 4 - 11
src/main/mobile/state.cljs

@@ -35,26 +35,19 @@
   [data]
   (reset! *popup-data data))
 
-(defonce *left-sidebar-open? (atom true))
-(defonce *left-sidebar-detent (atom 0))
-(defonce *left-sidebar-inert-outside? (atom false))
+(defonce *left-sidebar-open? (atom false))
 
 (defn open-left-sidebar!
   []
-  (reset! *left-sidebar-open? true)
-  (reset! *left-sidebar-inert-outside? true)
-  (reset! *left-sidebar-detent 2))
+  (reset! *left-sidebar-open? true))
 
 (defn close-left-sidebar!
   []
-  (reset! *left-sidebar-open? false)
-  (reset! *left-sidebar-inert-outside? false)
-  (reset! *left-sidebar-detent 1)
-  (js/setTimeout #(reset! *left-sidebar-open? true) 300))
+  (reset! *left-sidebar-open? false))
 
 (defn left-sidebar-open?
   []
-  (not (contains? #{0 1} @*left-sidebar-detent)))
+  @*left-sidebar-open?)
 
 (defn redirect-to-tab! [name]
   (set-tab! (str name)))