瀏覽代碼

feat(gesture): indent/outdent only when it is available

llcc 3 年之前
父節點
當前提交
3f92bc7e90

+ 0 - 113
src/main/frontend/components/block.cljs

@@ -41,7 +41,6 @@
             [frontend.handler.repeated :as repeated]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
-            [frontend.mobile.haptics :as haptics]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.outliner.tree :as tree]
             [frontend.search :as search]
@@ -1877,118 +1876,6 @@
                     [:a.fade-link
                      summary]])]))))
 
-(def swipe (atom nil))
-
-(defn- get-element-width
-  [^js element]
-  (or (some-> (.. element -style -width)
-              (string/replace "px" "")
-              util/safe-parse-int)
-      0))
-
-(defn- on-touch-start
-  [event]
-  (let [touch (aget (.-touches event) 0)
-        x (.-clientX touch)
-        y (.-clientY touch)]
-    (reset! swipe {:x0 x :y0 y :xi x :yi y :tx x :ty y :direction nil})))
-
-(defn- on-touch-move
-  [event uuid]
-  (let [{:keys [x0 xi direction]} @swipe
-        touch (aget (.-touches event) 0)
-        tx (.-clientX touch)
-        ty (.-clientY touch)
-        direction (if (nil? direction)
-                    (if (> tx x0)
-                      :right
-                      :left)
-                    direction)]
-    (swap! swipe #(-> %
-                      (assoc :tx tx)
-                      (assoc :ty ty)
-                      (assoc :xi tx)
-                      (assoc :yi ty)
-                      (assoc :direction direction)))
-    (when (< (* (- xi x0) (- tx xi)) 0)
-      (swap! swipe #(-> %
-                        (assoc :x0 tx)
-                        (assoc :y0 ty))))
-    (let [{:keys [x0 y0]} @swipe
-          dx (- tx x0)
-          dy (- ty y0)]
-      (when-not (or (> (. js/Math abs dy) 15)
-                    (< (. js/Math abs dx) 3))
-        (let [left (.querySelector js/document (str "#block-left-menu-" uuid))
-              right (.querySelector js/document (str "#block-right-menu-" uuid))]
-
-          (cond
-            (= direction :right)
-            (do
-              (if (> dx 0)
-                (set! (.. left -style -width) (str dx "px"))
-                (set! (.. left -style -width) (str (+ 50 dx) "px")))
-
-              (if (>= (get-element-width left) 50)
-                (set! (.. left -style -opacity) "100%")
-                (set! (.. left -style -opacity) "30%")))
-            
-            (= direction :left)
-            (do
-              (if (< dx 0)
-                (set! (.. right -style -width) (str (- dx) "px"))
-                (set! (.. right -style -width) (str (- 80 dx) "px")))
-
-              (let [outdent (.querySelector right ".outdent")
-                    more (.querySelector right ".more")]
-
-                (if (and (>= (get-element-width right) 40)
-                         (< (get-element-width right) 80))
-                  (set! (.. outdent -style -opacity) "100%")
-                  (set! (.. outdent -style -opacity) "30%"))
-
-                (if (>= (get-element-width right) 80)
-                  (set! (.. more -style -opacity) "100%")
-                  (set! (.. more -style -opacity) "30%"))))
-
-            :else
-            nil))))))
-
-(defn- on-touch-end
-  [_event block uuid]
-  (let [left-menu (.querySelector js/document (str "#block-left-menu-" uuid))
-        right-menu (.querySelector js/document (str "#block-right-menu-" uuid))
-        {:keys [x0 tx]} @swipe
-        dx (- tx x0)]
-    
-    (try
-      (when (> (. js/Math abs dx) 5)
-        (cond
-          (>= (get-element-width left-menu) 50)
-          (haptics/with-haptics-impact
-            (block-handler/indent-outdent-block! block :right)
-            :light)
-
-          (<= 40 (get-element-width right-menu) 80)
-          (haptics/with-haptics-impact
-            (block-handler/indent-outdent-block! block :left)
-            :light)
-
-          (> (get-element-width right-menu) 80)
-          (haptics/with-haptics-impact
-            (do (state/set-state! :mobile/show-action-bar? true)
-                (state/set-state! :mobile/actioned-block block)
-                (editor-handler/select-block! uuid))
-            :light)
-
-          :else
-          nil))
-      (catch js/Error e
-        (js/console.error e))
-      (finally
-        (set! (.. left-menu -style -width) "0px")
-        (set! (.. right-menu -style -width) "0px")))))
-
 (rum/defc block-content < rum/reactive
   [config {:block/keys [uuid content children properties scheduled deadline format pre-block?] :as block} edit-input-id block-id slide?]
   (let [{:block/keys [title body] :as block} (if (:block/title block) block

+ 5 - 6
src/main/frontend/components/sidebar.cljs

@@ -484,7 +484,8 @@
         home? (= :home route-name)
         edit? (:editor/editing? @state/state)
         default-home (get-default-home-if-valid)
-        logged? (user-handler/logged-in?)]
+        logged? (user-handler/logged-in?)
+        show-action-bar? (state/sub :mobile/show-action-bar?)]
     (theme/container
      {:t             t
       :theme         theme
@@ -526,15 +527,13 @@
                :indexeddb-support?  indexeddb-support?
                :light?              light?
                :db-restoring?       db-restoring?
-               :main-content        main-content})
+               :main-content        main-content
+               :show-action-bar?    show-action-bar?})
 
         (when (and (mobile-util/is-native-platform?)
                    current-repo
                    (not (state/sub :modal/show?)))
-          (footer/footer))
-
-        (when (state/sub :mobile/show-action-bar?)
-          (action-sheet/action-bar))]
+          (footer/footer))]
 
        (right-sidebar/sidebar)
 

+ 142 - 0
src/main/frontend/handler/block.cljs

@@ -5,7 +5,9 @@
    [frontend.db :as db]
    [frontend.db.model :as db-model]
    [frontend.db.react :as react]
+   [frontend.db.utils :as db-utils]
    [frontend.format.block :as block]
+   [frontend.mobile.haptics :as haptics]
    [frontend.modules.outliner.core :as outliner-core]
    [frontend.modules.outliner.transaction :as outliner-tx]
    [frontend.state :as state]
@@ -118,8 +120,148 @@
                               (->> (concat result more-data)
                                    (util/distinct-by :db/id))))))
 
+(defn indentable?
+  [{:block/keys [parent] :as block}]
+  (when parent
+    (let [parent-block (db-utils/pull (:db/id parent))
+          first-child (first
+                       (db-model/get-block-immediate-children
+                        (state/get-current-repo)
+                        (:block/uuid parent-block)))]
+      (not= (:db/id block) (:db/id first-child)))))
+
+(defn outdentable?
+  [{:block/keys [level] :as _block}]
+  (not= level 1))
+
 (defn indent-outdent-block!
   [block direction]
   (outliner-tx/transact!
    {:outliner-op :move-blocks}
    (outliner-core/indent-outdent-blocks! [block] (= direction :right))))
+
+(defn select-block!
+  [block-uuid]
+  (let [blocks (js/document.getElementsByClassName (str block-uuid))]
+    (when (seq blocks)
+      (state/exit-editing-and-set-selected-blocks! blocks))))
+
+(def swipe (atom nil))
+
+(defn on-touch-start
+  [event]
+  (when-let [touch (aget (.-targetTouches event) 0)]
+    (let [x (.-clientX touch)
+          y (.-clientY touch)]
+      (reset! swipe {:x0 x :y0 y :xi x :yi y :tx x :ty y :direction nil}))))
+
+
+(defn on-touch-move
+  [event block uuid *show-left-menu? *show-right-menu?]
+  (when-let [touch (aget (.-targetTouches event) 0)]
+    (let [{:keys [x0 xi direction]} @swipe
+          tx (.-clientX touch)
+          ty (.-clientY touch)
+          direction (if (nil? direction)
+                      (if (> tx x0)
+                        :right
+                        :left)
+                      direction)]
+      (swap! swipe #(-> %
+                        (assoc :tx tx)
+                        (assoc :ty ty)
+                        (assoc :xi tx)
+                        (assoc :yi ty)
+                        (assoc :direction direction)))
+      (when (< (* (- xi x0) (- tx xi)) 0)
+        (swap! swipe #(-> %
+                          (assoc :x0 tx)
+                          (assoc :y0 ty))))
+      (let [{:keys [x0 y0]} @swipe
+            dx (- tx x0)
+            dy (- ty y0)]
+        (when-not (or (> (. js/Math abs dy) 15)
+                      (< (. js/Math abs dx) 5))
+          (let [left (.querySelector js/document (str "#block-left-menu-" uuid))
+                right (.querySelector js/document (str "#block-right-menu-" uuid))]
+
+            (cond
+              (= direction :right)
+              (do
+                (reset! *show-left-menu? true)
+                (when left
+                  (if (> dx 0)
+                    (set! (.. left -style -width) (str dx "px"))
+                    (set! (.. left -style -width) (str (+ 50 dx) "px")))
+
+                  (let [indent (.querySelector left ".indent")]
+                    (when (indentable? block)
+                      (if (>= (util/get-element-width left) 50)
+                        (set! (.. indent -style -opacity) "100%")
+                        (set! (.. indent -style -opacity) "30%"))))))
+
+              (= direction :left)
+              (do
+                (reset! *show-right-menu? true)
+                (when right
+                  (if (< dx 0)
+                    (set! (.. right -style -width) (str (- dx) "px"))
+                    (set! (.. right -style -width) (str (- 80 dx) "px")))
+
+                  (let [outdent (.querySelector right ".outdent")
+                        more (.querySelector right ".more")]
+
+                    (when (outdentable? block)
+                      (if (and (>= (util/get-element-width right) 40)
+                               (< (util/get-element-width right) 80))
+                        (set! (.. outdent -style -opacity) "100%")
+                        (set! (.. outdent -style -opacity) "30%")))
+
+                    (if (>= (util/get-element-width right) 80)
+                      (set! (.. more -style -opacity) "100%")
+                      (set! (.. more -style -opacity) "30%")))))
+              :else
+              nil)))))))
+
+(defn on-touch-end
+  [_event block uuid *show-left-menu? *show-right-menu?]
+  (let [left-menu (.querySelector js/document (str "#block-left-menu-" uuid))
+        right-menu (.querySelector js/document (str "#block-right-menu-" uuid))
+        {:keys [x0 tx]} @swipe
+        dx (- tx x0)]
+    (try
+      (when (> (. js/Math abs dx) 5)
+        (cond
+          (and left-menu (>= (util/get-element-width left-menu) 50))
+          (when (indentable? block)
+           (haptics/with-haptics-impact
+             (indent-outdent-block! block :right)
+             :light))
+
+          (and right-menu (<= 40 (util/get-element-width right-menu) 80))
+          (when (outdentable? block)
+            (haptics/with-haptics-impact
+              (indent-outdent-block! block :left)
+              :light))
+
+          (and right-menu (> (util/get-element-width right-menu) 80))
+          (haptics/with-haptics-impact
+            (do (state/set-state! :mobile/show-action-bar? true)
+                (state/set-state! :mobile/actioned-block block)
+                (select-block! uuid))
+            :light)
+
+          :else
+          nil))
+      (catch js/Error e
+        (js/console.error e))
+      (finally
+        (reset! *show-left-menu? false)
+        (reset! *show-right-menu? false)))))
+
+(defn on-touch-cancel
+  [_event *show-left-menu? *show-right-menu?]
+  (reset! *show-left-menu? false)
+  (reset! *show-right-menu? false))
+
+

+ 23 - 9
src/main/frontend/mobile/action_sheet.cljs

@@ -1,9 +1,12 @@
 (ns frontend.mobile.action-sheet
-  (:require [frontend.extensions.srs :as srs]
+  (:require [frontend.db :as db]
+            [frontend.extensions.srs :as srs]
             [frontend.handler.editor :as editor-handler]
             [frontend.mixins :as mixins]
             [frontend.state :as state]
             [frontend.ui :as ui]
+            [frontend.util :as util]
+            [goog.object :as gobj]
             [rum.core :as rum]))
 
 (defn- action-command
@@ -25,23 +28,34 @@
      (mixins/hide-when-esc-or-outside
       state
       :on-hide (fn []
-                 (state/set-state! :mobile/show-action-bar? false)
-                 (editor-handler/clear-selection!)))))
+                 (editor-handler/clear-selection!)
+                 (state/set-state! :mobile/show-action-bar? false)))))
   [state]
   (when-let [block (state/sub :mobile/actioned-block)]
-    (let [block-id   (:block/uuid block)]
-      [:div.fixed.action-bar
+    (let [{:block/keys [uuid children]} block
+          last-child-block-id (when-not (empty? children)
+                                (-> (db/get-block-children (state/get-current-repo) uuid)
+                                    last
+                                    :block/uuid))]
+      (let [tag-id (or last-child-block-id uuid)
+            bottom-el (.querySelector js/document (str "#block-content-" tag-id))
+            bottom (gobj/get (.getBoundingClientRect bottom-el) "bottom")
+            vw-height (or (.-height js/window.visualViewport)
+                          (.-clientHeight js/document.documentElement))
+            delta (- vw-height bottom 170)]
+        (when (< delta 0)
+          (.scrollBy (util/app-scroll-container-node) #js {:top (- 10 delta)})))
+      [:div.action-bar
        (when-not (= (:block/format block) :org)
          (action-command "heading" "Heading"
                          #(let [properties (:block/properties block)
                                 heading?   (true? (:heading properties))]
                             (if heading?
-                              (editor-handler/remove-block-property! block-id :heading)
-                              (editor-handler/set-block-property! block-id :heading true)))))
-
+                              (editor-handler/remove-block-property! uuid :heading)
+                              (editor-handler/set-block-property! uuid :heading true)))))
        (action-command "infinity" "Card" #(srs/make-block-a-card! (:block/uuid block)))
        (action-command "copy" "Copy" #(editor-handler/copy-selection-blocks))
        (action-command "registered" "Copy ref"
-                       (fn [_event] (editor-handler/copy-block-ref! block-id #(str "((" % "))"))))
+                       (fn [_event] (editor-handler/copy-block-ref! uuid #(str "((" % "))"))))
        (action-command "cut" "Cut" #(editor-handler/cut-selection-blocks true))
        (action-command "trash" "Delete" #(editor-handler/delete-block-aux! block true))])))

+ 8 - 0
src/main/frontend/util.cljc

@@ -1267,6 +1267,14 @@
      [node]
      (gobj/get (.getBoundingClientRect node) "top")))
 
+#?(:cljs
+   (defn get-element-width
+     [^js element]
+     (or (some-> (.. element -style -width)
+                 (string/replace "px" "")
+                 safe-parse-int)
+         0)))
+
 #?(:cljs
    (defn sort-by-height
      [elements]