Просмотр исходного кода

enhance(ux): show editor popups at the top left corner

Tienson Qin 8 месяцев назад
Родитель
Сommit
184add530b

+ 2 - 0
deps/shui/src/logseq/shui/popup/core.cljs

@@ -100,6 +100,8 @@
                         ;; minus default offset
                          (if as-mask? 6 0))
                       width (if as-mask? 1 height)])
+                   (and (vector event) (= (count event) 2) (every? integer? event))
+                   event
                    :else [0 0])]
     (some-> @*target (d/set-attr! "data-popup-active" (if (keyword? id) (name id) (str id))))
     (let [on-before-hide (fn []

+ 19 - 0
src/main/capacitor/components/app.css

@@ -140,3 +140,22 @@ ion-content {
 [multiple]:focus, textarea:focus, select:focus {
   box-shadow: none;
 }
+
+.ui__popover-content, .ui__dropdown-menu-content {
+    &[data-editor-popup-ref=page-search],
+    &[data-editor-popup-ref=page-search-hashtag],
+    &[data-editor-popup-ref=commands]
+    {
+        max-height: 160px;
+        width: 200px;
+        max-width: 200px;
+
+        &[data-side=top] {
+            max-height: 160px;
+        }
+
+        &[data-side=bottom] {
+            max-height: 160px
+        }
+    }
+}

+ 3 - 2
src/main/capacitor/components/popup.cljs

@@ -6,9 +6,10 @@
             [rum.core :as rum]))
 
 (defn popup-show!
-  [event content-fn {:keys [id] :as opts}]
+  [_event content-fn {:keys [id] :as opts}]
   (if (and (keyword? id) (= "editor.commands" (namespace id)))
-    (shui-popup/show! event content-fn opts)
+    ;; FIXME: Editing a block at bottom will scroll to top
+    (shui-popup/show! [0 86] content-fn opts)
     (when (fn? content-fn)
       (state/set-popup! {:open? true
                          :content-fn content-fn

+ 4 - 10
src/main/frontend/commands.cljs

@@ -591,16 +591,10 @@
                       (count value)
                       (or forward-pos 0))
                    (or backward-pos 0))]
-    (state/set-edit-content! (state/get-edit-input-id)
-                             (str prefix value))
-    ;; HACK: save scroll-pos of current pos, then add trailing content
-    (let [scroll-container (util/nearest-scrollable-container input)
-          scroll-pos (.-scrollTop scroll-container)]
-      (state/set-block-content-and-last-pos! id new-value new-pos)
-      (cursor/move-cursor-to input new-pos)
-      (set! (.-scrollTop scroll-container) scroll-pos)
-      (when check-fn
-        (check-fn new-value (dec (count prefix)) new-pos)))))
+    (state/set-block-content-and-last-pos! id new-value new-pos)
+    (cursor/move-cursor-to input new-pos)
+    (when check-fn
+      (check-fn new-value (dec (count prefix)) new-pos))))
 
 (defn simple-replace!
   [id value selected

+ 13 - 11
src/main/frontend/handler/editor.cljs

@@ -3102,17 +3102,19 @@
 (defn editor-on-change!
   [block id search-timeout]
   (fn [e]
-    (if (= :block-search (state/sub :editor/action))
-      (let [timeout 50]
-        (when @search-timeout
-          (js/clearTimeout @search-timeout))
-        (reset! search-timeout
-                (js/setTimeout
-                 #(edit-box-on-change! e block id)
-                 timeout)))
-      (let [input (gdom/getElement id)]
-        (edit-box-on-change! e block id)
-        (util/scroll-editor-cursor input)))))
+    (let [editor-action (state/get-editor-action)]
+      (if (= :block-search editor-action)
+        (let [timeout 50]
+          (when @search-timeout
+            (js/clearTimeout @search-timeout))
+          (reset! search-timeout
+                  (js/setTimeout
+                   #(edit-box-on-change! e block id)
+                   timeout)))
+        (let [input (gdom/getElement id)]
+          (edit-box-on-change! e block id)
+          (when-not editor-action
+            (util/scroll-editor-cursor input)))))))
 
 (defn- cut-blocks-and-clear-selections!
   [copy?]

+ 8 - 8
src/main/frontend/mobile/mobile_bar.cljs

@@ -83,20 +83,20 @@
           text' (if (and c (not= c " "))
                   (str " " text)
                   text)]
-      ;; (util/scroll-editor-cursor input :to-vw-one-quarter? true)
-      ;; (.focus input)
       (commands/simple-insert! parent-id text' opts))))
 
 (defn commands
   []
   [(command #(insert-text "#" {}) {:icon "hash"} true)
-   (command #(let [input (state/get-input)
-                   new-pos (cursor/get-caret-pos input)]
-               (insert-text page-ref/left-and-right-brackets
-                            {:backward-pos 2
-                             :check-fn (fn [_ _ _]
+   (command #(insert-text page-ref/left-and-right-brackets
+                          {:backward-pos 2
+                           :check-fn (fn [_ _ _]
+                                       (let [input (state/get-input)
+                                             new-pos (cursor/get-caret-pos input)]
                                          (state/set-editor-action-data! {:pos new-pos})
-                                         (commands/handle-step [:editor/search-page]))})) {:icon "brackets"} true)
+                                         (commands/handle-step [:editor/search-page])))})
+
+            {:icon "brackets"} true)
    (command #(insert-text "/" {}) {:icon "command"} true)])
 
 (rum/defc mobile-bar < rum/reactive

+ 15 - 20
src/main/frontend/util.cljc

@@ -1257,18 +1257,12 @@
 
 (def keyboard-height (atom nil))
 #?(:cljs
-   (defn scroll-editor-cursor
-     [^js/HTMLElement el & {:keys [to-vw-one-quarter?]}]
+   (defn mobile-get-scroll
+     [^js/HTMLElement el]
      (when (and el (mobile?))
        (let [box-rect    (.getBoundingClientRect el)
              box-top     (.-top box-rect)
              box-bottom  (.-bottom box-rect)
-
-             header-height (or (some-> (gdom/getElementByClass "cp__header") (.-clientHeight)) 24)
-
-             main-node   (app-scroll-container-node el)
-             scroll-top'  (.-scrollTop main-node)
-
              current-pos (get-selection-start el)
              grapheme-pos (get-graphemes-pos (.-value el) current-pos)
              mock-text   (some-> (gdom/getElement "mock-text")
@@ -1280,23 +1274,24 @@
 
              cursor-y    (if offset-top (+ offset-top box-top offset-height 2) box-bottom)
              vw-height   (or (.-height js/window.visualViewport)
-                             (.-clientHeight js/document.documentElement))
-             ;; mobile toolbar height: 40px
-             scroll      (- cursor-y (- vw-height (+ @keyboard-height (+ 40 4))))]
-         (cond
-           (and to-vw-one-quarter? (> cursor-y (* vw-height 0.2)))
-           (set! (.-scrollTop main-node) (- (+ scroll-top' cursor-y) 130))
+                             (.-clientHeight js/document.documentElement))]
+         {:scroll (- cursor-y (- vw-height (+ @keyboard-height (+ 40 4))))
+          :cursor-y cursor-y
+          :offset-height offset-height}))))
 
+#?(:cljs
+   (defn scroll-editor-cursor
+     [^js/HTMLElement el]
+     (when (and el (mobile?))
+       (let [header-height (or (some-> (gdom/getElementByClass "cp__header") (.-clientHeight)) 24)
+             main-node   (app-scroll-container-node el)
+             scroll-top'  (.-scrollTop main-node)
+             {:keys [scroll offset-height cursor-y]} (mobile-get-scroll el)]
+         (cond
            (and (< cursor-y (+ header-height offset-height 4)) ;; 4 is top+bottom padding for per line
                 (>= cursor-y header-height))
            (.scrollBy main-node (bean/->js {:top (- (+ offset-height 4))}))
 
-           (< cursor-y header-height)
-           (let [_ (.scrollIntoView el true)
-                 main-node (app-scroll-container-node el)
-                 scroll-top' (.-scrollTop main-node)]
-             (set! (.-scrollTop main-node) (- scroll-top' (/ vw-height 4))))
-
            (> scroll 0)
            (set! (.-scrollTop main-node) (+ scroll-top' scroll 32))