Browse Source

feat(mobile): swipe right/left to toggle the left sidebar

Tienson Qin 4 years ago
parent
commit
b4ca337af3

+ 1 - 1
package.json

@@ -64,8 +64,8 @@
     },
     "dependencies": {
         "@capacitor/android": "3.2.2",
-        "@capacitor/core": "3.2.2",
         "@capacitor/app": "1.0.6",
+        "@capacitor/core": "3.2.2",
         "@capacitor/filesystem": "1.0.6",
         "@capacitor/ios": "3.2.2",
         "@capacitor/splash-screen": "1.1.3",

+ 10 - 7
src/main/frontend/components/sidebar.cljs

@@ -32,7 +32,8 @@
             [frontend.extensions.srs :as srs]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.components.widgets :as widgets]
-            [frontend.mobile.util :as mobile-util]))
+            [frontend.mobile.util :as mobile-util]
+            [frontend.handler.mobile.swipe :as swipe]))
 
 (defn nav-item
   [title href svg-d active? close-modal-fn]
@@ -289,20 +290,20 @@
               [:span.flex-1 "New page"]])]]]))))
 
 (rum/defc sidebar-mobile-sidebar < rum/reactive
-  [{:keys [open? left-sidebar-open? close-fn route-match]}]
+  [{:keys [left-sidebar-open? close-fn route-match]}]
   [:div.md:hidden.ls-mobile-left-sidebar
    {:class (if left-sidebar-open? "is-left-sidebar-open" "")}
    [:div.fixed.inset-0.z-30.bg-gray-600.pointer-events-none.ease-linear.duration-300
-    {:class (if @open?
+    {:class (if left-sidebar-open?
               "opacity-75 pointer-events-auto"
               "opacity-0 pointer-events-none")
      :on-click close-fn}]
    [:div#left-bar.fixed.inset-y-0.left-0.flex.flex-col.z-40.transform.ease-in-out.duration-300
-    {:class (if @open?
+    {:class (if left-sidebar-open?
               "translate-x-0"
               "-translate-x-full")
      :style {:padding-top (ui/main-content-top-padding)}}
-    (when @open?
+    (when left-sidebar-open?
       [:div.cp__header#head
        [:div.l.flex
         (header/left-menu-button
@@ -516,6 +517,9 @@
                         (if (state/modal-opened?)
                           (state/close-modal!)
                           (hide-context-menu-and-clear-selection)))))))
+  {:did-mount (fn [state]
+                (swipe/setup-listeners!)
+                state)}
   [state route-match main-content]
   (let [{:keys [open? close-fn open-fn]} state
         close-fn (fn []
@@ -559,8 +563,7 @@
         {:class (util/classnames [{:ls-left-sidebar-open left-sidebar-open?}])}
 
         (sidebar-mobile-sidebar
-         {:open?       open?
-          :left-sidebar-open? left-sidebar-open?
+         {:left-sidebar-open? left-sidebar-open?
           :close-fn    close-fn
           :route-match route-match})
 

+ 25 - 0
src/main/frontend/handler/mobile/swipe.cljs

@@ -0,0 +1,25 @@
+(ns frontend.handler.mobile.swipe
+  (:require [goog.dom :as gdom]
+            [cljs-bean.core :as bean]
+            [frontend.state :as state]))
+
+(defn setup-listeners!
+  []
+  (let [container js/document]
+    (.addEventListener container "swiped"
+                       (fn [e]
+                         (let [target (.-target e)
+                               detail (some-> (.-detail e)
+                                              (bean/->clj))]
+                           (case (:dir detail)
+                             "left"
+                             (do
+                               (when (state/get-left-sidebar-open?)
+                                 (state/set-left-sidebar-open! false)))
+                             "right"
+                             (do
+                               (when (and (not (state/get-left-sidebar-open?))
+                                          (:yStart detail)
+                                          (<= (:yStart detail) 200))
+                                 (state/set-left-sidebar-open! true)))
+                             nil))))))

+ 12 - 2
src/main/frontend/utils.js

@@ -1,5 +1,15 @@
 import path from 'path/path.js'
 
+/*!
+ * swiped-events.js - v1.1.6
+ * Pure JavaScript swipe events
+ * https://github.com/john-doherty/swiped-events
+ * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element
+ * @author John Doherty <www.johndoherty.info>
+ * @license MIT
+ */
+!function(t,e){"use strict";"function"!=typeof t.CustomEvent&&(t.CustomEvent=function(t,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var a=e.createEvent("CustomEvent");return a.initCustomEvent(t,n.bubbles,n.cancelable,n.detail),a},t.CustomEvent.prototype=t.Event.prototype),e.addEventListener("touchstart",function(t){if("true"===t.target.getAttribute("data-swipe-ignore"))return;s=t.target,r=Date.now(),n=t.touches[0].clientX,a=t.touches[0].clientY,u=0,i=0},!1),e.addEventListener("touchmove",function(t){if(!n||!a)return;var e=t.touches[0].clientX,r=t.touches[0].clientY;u=n-e,i=a-r},!1),e.addEventListener("touchend",function(t){if(s!==t.target)return;var e=parseInt(l(s,"data-swipe-threshold","20"),10),o=parseInt(l(s,"data-swipe-timeout","500"),10),c=Date.now()-r,d="",p=t.changedTouches||t.touches||[];Math.abs(u)>Math.abs(i)?Math.abs(u)>e&&c<o&&(d=u>0?"swiped-left":"swiped-right"):Math.abs(i)>e&&c<o&&(d=i>0?"swiped-up":"swiped-down");if(""!==d){var b={dir:d.replace(/swiped-/,""),touchType:(p[0]||{}).touchType||"direct",xStart:parseInt(n,10),xEnd:parseInt((p[0]||{}).clientX||-1,10),yStart:parseInt(a,10),yEnd:parseInt((p[0]||{}).clientY||-1,10)};s.dispatchEvent(new CustomEvent("swiped",{bubbles:!0,cancelable:!0,detail:b})),s.dispatchEvent(new CustomEvent(d,{bubbles:!0,cancelable:!0,detail:b}))}n=null,a=null,r=null},!1);var n=null,a=null,u=null,i=null,r=null,s=null;function l(t,n,a){for(;t&&t!==e.documentElement;){var u=t.getAttribute(n);if(u)return u;t=t.parentNode}return a}}(window,document);
+
 if (typeof window === 'undefined') {
   global.window = {}
 }
@@ -288,9 +298,9 @@ export const nodePath = Object.assign({}, path, {
     input = toPosixPath(input)
     return path.dirname(input)
   },
-  
+
   extname (input) {
     input = toPosixPath(input)
     return path.extname(input)
-  }  
+  }
 })