Browse Source

enhance(iOS): disable webview resize

llcc 3 years ago
parent
commit
9e568c8016
32 changed files with 192 additions and 208 deletions
  1. 3 0
      android/app/src/main/assets/capacitor.config.json
  2. 4 0
      capacitor.config.ts
  3. 3 0
      ios/App/App/capacitor.config.json
  4. 2 2
      src/main/frontend/components/block.cljs
  5. 2 2
      src/main/frontend/components/header.cljs
  6. 3 1
      src/main/frontend/components/header.css
  7. 2 2
      src/main/frontend/components/onboarding/setups.cljs
  8. 1 1
      src/main/frontend/components/page.cljs
  9. 1 1
      src/main/frontend/components/page_menu.cljs
  10. 2 2
      src/main/frontend/components/repo.cljs
  11. 6 6
      src/main/frontend/components/settings.cljs
  12. 18 14
      src/main/frontend/components/sidebar.cljs
  13. 2 2
      src/main/frontend/components/widgets.cljs
  14. 2 2
      src/main/frontend/config.cljs
  15. 2 2
      src/main/frontend/db/conn.cljs
  16. 1 1
      src/main/frontend/extensions/excalidraw.cljs
  17. 1 1
      src/main/frontend/extensions/video/youtube.cljs
  18. 5 5
      src/main/frontend/fs.cljs
  19. 2 2
      src/main/frontend/handler.cljs
  20. 21 27
      src/main/frontend/handler/editor.cljs
  21. 2 5
      src/main/frontend/handler/editor/lifecycle.cljs
  22. 19 10
      src/main/frontend/handler/events.cljs
  23. 3 3
      src/main/frontend/handler/page.cljs
  24. 1 1
      src/main/frontend/handler/ui.cljs
  25. 2 2
      src/main/frontend/handler/web/nfs.cljs
  26. 13 5
      src/main/frontend/mobile/core.cljs
  27. 7 9
      src/main/frontend/mobile/footer.cljs
  28. 4 52
      src/main/frontend/mobile/util.cljs
  29. 1 1
      src/main/frontend/modules/instrumentation/sentry.cljs
  30. 9 7
      src/main/frontend/state.cljs
  31. 2 2
      src/main/frontend/ui.cljs
  32. 46 38
      src/main/frontend/util.cljc

+ 3 - 0
android/app/src/main/assets/capacitor.config.json

@@ -10,6 +10,9 @@
 			"androidScaleType": "CENTER_CROP",
 			"splashImmersive": false,
 			"backgroundColor": "#002b36"
+		},
+		"Keyboard": {
+			"resize": "none"
 		}
 	},
 	"ios": {

+ 4 - 0
capacitor.config.ts

@@ -13,6 +13,10 @@ const config: CapacitorConfig = {
             splashImmersive: false,
             backgroundColor: "#002b36"
         },
+
+        Keyboard: {
+            resize: "none"
+        }
     },
     ios: {
         scheme: "Logseq"

+ 3 - 0
ios/App/App/capacitor.config.json

@@ -10,6 +10,9 @@
 			"androidScaleType": "CENTER_CROP",
 			"splashImmersive": false,
 			"backgroundColor": "#002b36"
+		},
+		"Keyboard": {
+			"resize": "none"
 		}
 	},
 	"ios": {

+ 2 - 2
src/main/frontend/components/block.cljs

@@ -259,7 +259,7 @@
   (let [src (::src state)
         granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
         href (config/get-local-asset-absolute-path href)]
-    (when (or granted? (util/electron?) (mobile-util/is-native-platform?))
+    (when (or granted? (util/electron?) (mobile-util/native-platform?))
       (p/then (editor-handler/make-asset-url href) #(reset! src %)))
 
     (when @src
@@ -1467,7 +1467,7 @@
                                    "hide-inner-bullet"))}
                     [:span.bullet {:blockid (str uuid)}]]]]
        (cond
-         (and (or (mobile-util/is-native-platform?)
+         (and (or (mobile-util/native-platform?)
                   (:ui/show-empty-bullets? (state/get-config)))
               (not doc-mode?))
          bullet

+ 2 - 2
src/main/frontend/components/header.cljs

@@ -228,7 +228,7 @@
         show-open-folder? (and (nfs/supported?)
                                (or (empty? repos)
                                    (nil? (state/sub :git/current-repo)))
-                               (not (mobile-util/is-native-platform?))
+                               (not (mobile-util/native-platform?))
                                (not config/publishing?))]
     [:div.cp__header#head
      {:class           (util/classnames [{:electron-mac   electron-mac?
@@ -271,7 +271,7 @@
                 (mobile-util/native-ios?))
         (back-and-forward))
 
-      (when-not (mobile-util/is-native-platform?)
+      (when-not (mobile-util/native-platform?)
         (new-block-mode))
 
       (when show-open-folder?

+ 3 - 1
src/main/frontend/components/header.css

@@ -221,7 +221,9 @@ html.is-native-iphone-without-notch,
 html.is-native-ipad {
 
      #main-container {
-        padding-top: 0px;
+         padding-top: 0px;
+         display: flex;
+         flex-direction: column;
     }
 
      #main-content-container {

+ 2 - 2
src/main/frontend/components/onboarding/setups.cljs

@@ -71,10 +71,10 @@
       [:section.a
        [:strong "Let’s get you set up."]
        [:small (str "Where on your " DEVICE " do you want to save your work?")
-        (when (mobile-util/is-native-platform?)
+        (when (mobile-util/native-platform?)
           (mobile-intro))]
 
-       (if (or (nfs/supported?) (mobile-util/is-native-platform?))
+       (if (or (nfs/supported?) (mobile-util/native-platform?))
          [:div.choose.flex.flex-col.items-center
           {:on-click #(page-handler/ls-dir-files!
                        (fn []

+ 1 - 1
src/main/frontend/components/page.cljs

@@ -350,7 +350,7 @@
        [:div.relative
         (when (and (not sidebar?) (not block?))
           [:div.flex.flex-row.space-between
-           (when (or (mobile-util/is-native-platform?) (util/mobile?))
+           (when (or (mobile-util/native-platform?) (util/mobile?))
              [:div.flex.flex-row.pr-2
               {:style {:margin-left -15}
                :on-mouse-over (fn [e]

+ 1 - 1
src/main/frontend/components/page_menu.cljs

@@ -84,7 +84,7 @@
                          (page-handler/unfavorite-page! page-original-name)
                          (page-handler/favorite-page! page-original-name)))}}
 
-          (when-not (mobile-util/is-native-platform?)
+          (when-not (mobile-util/native-platform?)
             {:title (t :page/presentation-mode)
              :options {:on-click (fn []
                                    (state/sidebar-add-block!

+ 2 - 2
src/main/frontend/components/repo.cljs

@@ -42,7 +42,7 @@
        [:div.pl-1.content.mt-3
         [:div.flex.flex-row.my-4
          (when (or (nfs-handler/supported?)
-                   (mobile-util/is-native-platform?))
+                   (mobile-util/native-platform?))
            [:div.mr-8
             (ui/button
               (t :open-a-directory)
@@ -95,7 +95,7 @@
                        (when (and nfs-repo?
                                   (not= current-repo config/local-repo)
                                   (or (nfs-handler/supported?)
-                                      (mobile-util/is-native-platform?)))
+                                      (mobile-util/native-platform?)))
                          {:title (t :sync-from-local-files)
                           :hover-detail (t :sync-from-local-files-detail)
                           :options {:on-click

+ 6 - 6
src/main/frontend/components/settings.cljs

@@ -131,7 +131,7 @@
                               :href     href
                               :on-click on-click))]
     (when-not (or (util/mobile?)
-                  (mobile-util/is-native-platform?))
+                  (mobile-util/native-platform?))
       [:div.text-sm desc])]])
 
 
@@ -161,7 +161,7 @@
      (ui/toggle show-brackets?
                 config-handler/toggle-ui-show-brackets!
                 true)]]
-   (when (not (or (util/mobile?) (mobile-util/is-native-platform?)))
+   (when (not (or (util/mobile?) (mobile-util/native-platform?)))
      [:div {:style {:text-align "right"}}
       (ui/render-keyboard-shortcut (shortcut-helper/gen-shortcut-seq :ui/toggle-brackets))])])
 
@@ -559,9 +559,9 @@
      (show-brackets-row t show-brackets?)
      (when (util/electron?) (switch-spell-check-row t))
      (outdenting-row t logical-outdenting?)
-     (when-not (or (util/mobile?) (mobile-util/is-native-platform?))
+     (when-not (or (util/mobile?) (mobile-util/native-platform?))
        (shortcut-tooltip-row t enable-shortcut-tooltip?))
-     (when-not (or (util/mobile?) (mobile-util/is-native-platform?))
+     (when-not (or (util/mobile?) (mobile-util/native-platform?))
        (tooltip-row t enable-tooltip?))
      (timetracking-row t enable-timetracking?)
      (journal-row t enable-journals?)
@@ -610,7 +610,7 @@
     [:div.panel-wrap.is-advanced
      (when (and util/mac? (util/electron?)) (app-auto-update-row t))
      (usage-diagnostics-row t instrument-disabled?)
-     (when-not (mobile-util/is-native-platform?) (developer-mode-row t developer-mode?))
+     (when-not (mobile-util/native-platform?) (developer-mode-row t developer-mode?))
      (when (util/electron?) (plugin-system-switcher-row))
      (when (util/electron?) (https-user-agent-row https-agent-opts))
      (clear-cache-row t)
@@ -648,7 +648,7 @@
         (for [[label text icon]
               [[:general (t :settings-page/tab-general) (ui/icon "adjustments" {:style {:font-size 20}})]
                [:editor (t :settings-page/tab-editor) (ui/icon "writing" {:style {:font-size 20}})]
-               (when-not (mobile-util/is-native-platform?)
+               (when-not (mobile-util/native-platform?)
                  [:git (t :settings-page/tab-version-control) (ui/icon "history" {:style {:font-size 20}})])
                [:advanced (t :settings-page/tab-advanced) (ui/icon "bulb" {:style {:font-size 20}})]
                (when plugins-of-settings

+ 18 - 14
src/main/frontend/components/sidebar.cljs

@@ -1,40 +1,44 @@
 (ns frontend.components.sidebar
   (:require [cljs-drag-n-drop.core :as dnd]
             [clojure.string :as string]
+            [frontend.commands :as commands]
             [frontend.components.command-palette :as command-palette]
             [frontend.components.header :as header]
             [frontend.components.journal :as journal]
+            [frontend.components.onboarding :as onboarding]
+            [frontend.components.plugins :as plugins]
             [frontend.components.repo :as repo]
             [frontend.components.right-sidebar :as right-sidebar]
+            [frontend.components.select :as select]
+            [frontend.components.svg :as svg]
             [frontend.components.theme :as theme]
             [frontend.components.widgets :as widgets]
-            [frontend.components.plugins :as plugins]
-            [frontend.components.select :as select]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
-            [frontend.db.model :as db-model]
-            [frontend.components.svg :as svg]
             [frontend.db-mixins :as db-mixins]
+            [frontend.db.model :as db-model]
+            [frontend.extensions.pdf.assets :as pdf-assets]
+            [frontend.extensions.srs :as srs]
+            [frontend.handler.config :as config-handler]
             [frontend.handler.editor :as editor-handler]
-            [frontend.handler.route :as route-handler]
+            [frontend.handler.history :as history]
+            [frontend.handler.mobile.swipe :as swipe]
             [frontend.handler.page :as page-handler]
+            [frontend.handler.route :as route-handler]
             [frontend.handler.user :as user-handler]
             [frontend.mixins :as mixins]
+            [frontend.mobile.camera :as mobile-camera]
+            [frontend.mobile.footer :as footer]
+            [frontend.mobile.util :as mobile-util]
             [frontend.modules.shortcut.data-helper :as shortcut-dh]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
-            [reitit.frontend.easy :as rfe]
             [goog.dom :as gdom]
             [goog.object :as gobj]
-            [rum.core :as rum]
-            [frontend.extensions.srs :as srs]
-            [frontend.extensions.pdf.assets :as pdf-assets]
-            [frontend.mobile.util :as mobile-util]
-            [frontend.handler.mobile.swipe :as swipe]
-            [frontend.components.onboarding :as onboarding]
-            [frontend.mobile.footer :as footer]))
+            [reitit.frontend.easy :as rfe]
+            [rum.core :as rum]))
 
 (rum/defc nav-content-item
   [name {:keys [class]} child]
@@ -524,7 +528,7 @@
                :db-restoring?       db-restoring?
                :main-content        main-content})
 
-        (when (and (mobile-util/is-native-platform?)
+        (when (and (mobile-util/native-platform?)
                    current-repo
                    (not (state/sub :modal/show?)))
           (footer/footer))]

+ 2 - 2
src/main/frontend/components/widgets.cljs

@@ -12,8 +12,8 @@
   []
   [:div.flex.flex-col
    [:h1.title (t :on-boarding/add-graph)]
-   (let [nfs-supported? (or (nfs/supported?) (mobile-util/is-native-platform?))]
-     (if (mobile-util/is-native-platform?)
+   (let [nfs-supported? (or (nfs/supported?) (mobile-util/native-platform?))]
+     (if (mobile-util/native-platform?)
        [:div.text-sm
         (ui/button "Open a local directory"
           :on-click #(page-handler/ls-dir-files! shortcut/refresh!))

+ 2 - 2
src/main/frontend/config.cljs

@@ -321,7 +321,7 @@
     (and (util/electron?) (local-db? repo-url))
     (get-local-dir repo-url)
 
-    (and (mobile-util/is-native-platform?) (local-db? repo-url))
+    (and (mobile-util/native-platform?) (local-db? repo-url))
     (let [dir (get-local-dir repo-url)]
       (if (string/starts-with? dir "file:")
         dir
@@ -334,7 +334,7 @@
 
 (defn get-repo-path
   [repo-url path]
-  (if (and (or (util/electron?) (mobile-util/is-native-platform?))
+  (if (and (or (util/electron?) (mobile-util/native-platform?))
            (local-db? repo-url))
     path
     (util/node-path.join (get-repo-dir repo-url) path)))

+ 2 - 2
src/main/frontend/db/conn.cljs

@@ -22,7 +22,7 @@
 (defn get-repo-name
   [repo]
   (cond
-    (mobile-util/is-native-platform?)
+    (mobile-util/native-platform?)
     (text/get-graph-name-from-path repo)
 
     (config/local-db? repo)
@@ -35,7 +35,7 @@
   "repo-path: output of `get-repo-name`"
   [repo-path]
   (if (or (util/electron?)
-          (mobile-util/is-native-platform?))
+          (mobile-util/native-platform?))
     (text/get-file-basename repo-path)
     repo-path))
 

+ 1 - 1
src/main/frontend/extensions/excalidraw.cljs

@@ -149,5 +149,5 @@
     (when-not (and (config/local-db? repo)
                    (not granted?)
                    (not (util/electron?))
-                   (not (mobile-util/is-native-platform?)))
+                   (not (mobile-util/native-platform?)))
       (draw-container option))))

+ 1 - 1
src/main/frontend/extensions/video/youtube.cljs

@@ -109,7 +109,7 @@
 (defn gen-youtube-ts-macro []
   (if-let [player (get-player (state/get-input))]
     (util/format "{{youtube-timestamp %s}}" (Math/floor (.getCurrentTime ^js player)))
-    (when (mobile-util/is-native-platform?)
+    (when (mobile-util/native-platform?)
       (notification/show!
        "Please embed a YouTube video at first, then use this icon.
 Remember: You can paste a raw YouTube url as embedded video on mobile."

+ 5 - 5
src/main/frontend/fs.cljs

@@ -31,7 +31,7 @@
       (and (util/electron?) (not bfs-local?))
       node-record
 
-      (mobile-util/is-native-platform?)
+      (mobile-util/native-platform?)
       mobile-record
 
       (local-db? dir)
@@ -105,7 +105,7 @@
 
     :else
     (let [[old-path new-path]
-          (map #(if (or (util/electron?) (mobile-util/is-native-platform?))
+          (map #(if (or (util/electron?) (mobile-util/native-platform?))
                   %
                   (str (config/get-repo-dir repo) "/" %))
                [old-path new-path])]
@@ -121,7 +121,7 @@
     (util/electron?)
     node-record
 
-    (mobile-util/is-native-platform?)
+    (mobile-util/native-platform?)
     mobile-record
 
     :else
@@ -132,7 +132,7 @@
   (let [record (get-record)]
     (p/let [result (protocol/open-dir record ok-handler)]
       (if (or (util/electron?)
-              (mobile-util/is-native-platform?))
+              (mobile-util/native-platform?))
         (let [[dir & paths] (bean/->clj result)]
           [(:path dir) paths])
         result))))
@@ -141,7 +141,7 @@
   [path-or-handle ok-handler]
   (let [record (get-record)
         electron? (util/electron?)
-        mobile? (mobile-util/is-native-platform?)]
+        mobile? (mobile-util/native-platform?)]
     (p/let [result (protocol/get-files record path-or-handle ok-handler)]
       (if (or electron? mobile?)
         (let [result (bean/->clj result)]

+ 2 - 2
src/main/frontend/handler.cljs

@@ -92,7 +92,7 @@
            (and (not (seq (db/get-files config/local-repo)))
                 ;; Not native local directory
                 (not (some config/local-db? (map :url repos)))
-                (not (mobile-util/is-native-platform?)))
+                (not (mobile-util/native-platform?)))
            ;; will execute `(state/set-db-restoring! false)` inside
            (repo-handler/setup-local-repo-if-not-exists!)
 
@@ -191,7 +191,7 @@
     (p/let [repos (get-repos)]
       (state/set-repos! repos)
       (restore-and-setup! repos db-schema)
-      (when (mobile-util/is-native-platform?)
+      (when (mobile-util/native-platform?)
         (p/do! (mobile-util/hide-splash))))
 
     (reset! db/*sync-search-indice-f search/sync-search-indice!)

+ 21 - 27
src/main/frontend/handler/editor.cljs

@@ -1,13 +1,15 @@
 (ns frontend.handler.editor
   (:require ["/frontend/utils" :as utils]
+            ["path" :as path]
             [cljs.core.match :refer [match]]
             [clojure.set :as set]
             [clojure.string :as string]
             [clojure.walk :as w]
             [dommy.core :as dom]
             [frontend.commands :as commands
-             :refer [*angle-bracket-caret-pos *show-block-commands
-                     *show-commands *slash-caret-pos]]
+             :refer [*angle-bracket-caret-pos
+                     *show-block-commands *show-commands
+                     *slash-caret-pos]]
             [frontend.config :as config]
             [frontend.date :as date]
             [frontend.db :as db]
@@ -25,12 +27,12 @@
             [frontend.handler.notification :as notification]
             [frontend.handler.repeated :as repeated]
             [frontend.handler.route :as route-handler]
-            [frontend.image :as image]
             [frontend.idb :as idb]
+            [frontend.image :as image]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.outliner.core :as outliner-core]
-            [frontend.modules.outliner.tree :as tree]
             [frontend.modules.outliner.transaction :as outliner-tx]
+            [frontend.modules.outliner.tree :as tree]
             [frontend.search :as search]
             [frontend.state :as state]
             [frontend.template :as template]
@@ -40,19 +42,18 @@
             [frontend.util.clock :as clock]
             [frontend.util.cursor :as cursor]
             [frontend.util.drawer :as drawer]
+            [frontend.util.keycode :as keycode]
+            [frontend.util.list :as list]
             [frontend.util.marker :as marker]
-            [frontend.util.property :as property]
             [frontend.util.priority :as priority]
+            [frontend.util.property :as property]
             [frontend.util.thingatpt :as thingatpt]
-            [frontend.util.list :as list]
             [goog.dom :as gdom]
             [goog.dom.classes :as gdom-classes]
             [goog.object :as gobj]
             [lambdaisland.glogi :as log]
             [medley.core :as medley]
-            [promesa.core :as p]
-            [frontend.util.keycode :as keycode]
-            ["path" :as path]))
+            [promesa.core :as p]))
 
 ;; FIXME: should support multiple images concurrently uploading
 
@@ -1414,7 +1415,7 @@
       (util/electron?)
       (str "assets://" repo-dir path)
 
-      (mobile-util/is-native-platform?)
+      (mobile-util/native-platform?)
       (mobile-util/convert-file-src (str repo-dir path))
 
       :else
@@ -2605,7 +2606,7 @@
         ;; FIXME: On mobile, a backspace click to call keydown-backspace-handler
         ;; does not work sometimes in an empty block, hence the empty block
         ;; can't be deleted. Need to figure out why and find a better solution.
-        (and (mobile-util/is-native-platform?)
+        (and (mobile-util/native-platform?)
              (= key "Backspace")
              (= value ""))
         (do
@@ -2788,23 +2789,14 @@
   [id]
   (fn [_e]
     (let [input (gdom/getElement id)]
+      (util/scroll-editor-cursor input)
       (close-autocomplete-if-outside input))))
 
-(defonce mobile-toolbar-height 40)
 (defn editor-on-height-change!
   [id]
-  (fn [box-height ^js row-height]
-    (let [row-height (:rowHeight (js->clj row-height :keywordize-keys true))
-          input (gdom/getElement id)
-          caret (cursor/get-caret-pos input)
-          cursor-bottom (if caret (+ row-height (:top caret)) box-height)
-          box-top (gobj/get (.getBoundingClientRect input) "top")
-          cursor-y (+ cursor-bottom box-top)
-          vw-height (.-height js/window.visualViewport)]
-      (when (<  vw-height (+ cursor-y mobile-toolbar-height))
-        (let [main-node (gdom/getElement "main-content-container")
-              scroll-top (.-scrollTop main-node)]
-          (set! (.-scrollTop main-node) (+ scroll-top row-height)))))))
+  (fn [_box-height ^js _row-height]
+    (let [input (gdom/getElement id)]
+      (util/scroll-editor-cursor input))))
 
 (defn editor-on-change!
   [block id search-timeout]
@@ -2817,7 +2809,9 @@
                 (js/setTimeout
                  #(edit-box-on-change! e block id)
                  timeout)))
-      (edit-box-on-change! e block id))))
+      (let [input (gdom/getElement id)]
+        (edit-box-on-change! e block id)
+        (util/scroll-editor-cursor input)))))
 
 (defn- paste-text-parseable
   [format text]
@@ -2882,12 +2876,12 @@
       (and (util/url? text)
            (or (string/includes? text "youtube.com")
                (string/includes? text "youtu.be"))
-           (mobile-util/is-native-platform?))
+           (mobile-util/native-platform?))
       (commands/simple-insert! (state/get-edit-input-id) (util/format "{{youtube %s}}" text) nil)
 
       (and (util/url? text)
            (string/includes? text "twitter.com")
-           (mobile-util/is-native-platform?))
+           (mobile-util/native-platform?))
       (commands/simple-insert! (state/get-edit-input-id) (util/format "{{twitter %s}}" text) nil)
 
       (and (text/block-ref? text)

+ 2 - 5
src/main/frontend/handler/editor/lifecycle.cljs

@@ -3,7 +3,6 @@
             [frontend.handler.editor.keyboards :as keyboards-handler]
             [frontend.state :as state]
             [frontend.util :as util]
-            [frontend.mobile.util :as mobile-util]
             [goog.dom :as gdom]))
 
 (defn did-mount!
@@ -20,10 +19,8 @@
     (js/setTimeout #(keyboards-handler/esc-save! state) 100)
 
     (when-let [element (gdom/getElement id)]
-      (.focus element)
-      (when (or (mobile-util/is-native-platform?)
-                (util/mobile?))
-        (util/make-el-cursor-position-into-center-viewport element))))
+      (util/scroll-editor-cursor element :to-vw-center? true)
+      (.focus element)))
   state)
 
 (defn did-remount!

+ 19 - 10
src/main/frontend/handler/events.cljs

@@ -135,7 +135,7 @@
   [repo]
   (when
    (and (not (util/electron?))
-        (not (mobile-util/is-native-platform?)))
+        (not (mobile-util/native-platform?)))
     (fn [close-fn]
       [:div
        [:p
@@ -280,15 +280,24 @@
     (reset! st/*inited? true)
     (st/consume-pending-shortcuts!)))
 
-
-(defmethod handle :mobile/keyboard-will-show [[_]]
-  (when (and (state/get-left-sidebar-open?)
-             (state/editing?))
-    (state/set-left-sidebar-open! false)))
-
-(defmethod handle :mobile/keyboard-did-show [[_]]
-  (when-let [input (state/get-input)]
-    (util/make-el-cursor-position-into-center-viewport input)))
+(defmethod handle :mobile/keyboard-will-show [[_ keyboard-height]]
+  (let [main-node (util/app-scroll-container-node)]
+    (state/set-state! :mobile/show-tabbar? false)
+    (state/set-state! :mobile/show-toolbar? true)
+    (when (mobile-util/native-ios?)
+      (reset! util/keyboard-height keyboard-height)
+      (set! (.. main-node -style -marginBottom) (str keyboard-height "px"))
+      (js/setTimeout (fn []
+                       (let [toolbar (.querySelector main-node "#mobile-editor-toolbar")]
+                         (set! (.. toolbar -style -bottom) (str keyboard-height "px"))))
+                     100))))
+
+(defmethod handle :mobile/keyboard-will-hide [[_]]
+  (let [main-node (util/app-scroll-container-node)]
+    (state/set-state! :mobile/show-toolbar? false)
+    (state/set-state! :mobile/show-tabbar? true)
+    (when (mobile-util/native-ios?)
+     (set! (.. main-node -style -marginBottom) "0px"))))
 
 (defmethod handle :plugin/consume-updates [[_ id pending? updated?]]
   (let [downloading? (:plugin/updates-downloading? @state/state)]

+ 3 - 3
src/main/frontend/handler/page.cljs

@@ -152,7 +152,7 @@
       (db/transact! [[:db.fn/retractEntity [:file/path file-path]]])
       (->
        (p/let [_ (and (config/local-db? repo)
-                      (mobile-util/is-native-platform?)
+                      (mobile-util/native-platform?)
                       (fs/delete-file! repo file-path file-path {}))
                _ (fs/unlink! repo (config/get-repo-path repo file-path) nil)])
        (p/catch (fn [err]
@@ -582,7 +582,7 @@
                      page)
         (let [journal? (date/valid-journal-title? page)
               ref-file-path (str
-                             (if (or (util/electron?) (mobile-util/is-native-platform?))
+                             (if (or (util/electron?) (mobile-util/native-platform?))
                                (-> (config/get-repo-dir (state/get-current-repo))
                                    js/decodeURI
                                    (string/replace #"/+$" "")
@@ -716,7 +716,7 @@
                (not (state/loading-files? repo)))
       (state/set-today! (date/today))
       (when (or (config/local-db? repo)
-                (and (= "local" repo) (not (mobile-util/is-native-platform?))))
+                (and (= "local" repo) (not (mobile-util/native-platform?))))
         (let [title (date/today)
               today-page (util/page-name-sanity-lc title)
               template (state/get-default-journal-template)

+ 1 - 1
src/main/frontend/handler/ui.cljs

@@ -135,7 +135,7 @@
 
 (defn exec-js-if-exists-&-allowed!
   [t]
-  (when-not (mobile/is-native-platform?)
+  (when-not (mobile/native-platform?)
     (when-let [href (or
                      (state/get-custom-js-link)
                      (config/get-custom-js-path))]

+ 2 - 2
src/main/frontend/handler/web/nfs.cljs

@@ -119,7 +119,7 @@
   [ok-handler]
   (let [path-handles (atom {})
         electron? (util/electron?)
-        mobile-native? (mobile-util/is-native-platform?)
+        mobile-native? (mobile-util/native-platform?)
         nfs? (and (not electron?)
                   (not mobile-native?))
         *repo (atom nil)]
@@ -277,7 +277,7 @@
            handle-path (str config/local-handle-prefix dir-name)
            path-handles (atom {})
            electron? (util/electron?)
-           mobile-native? (mobile-util/is-native-platform?)
+           mobile-native? (mobile-util/native-platform?)
            nfs? (and (not electron?)
                      (not mobile-native?))]
        (when re-index?

+ 13 - 5
src/main/frontend/mobile/core.cljs

@@ -2,6 +2,7 @@
   (:require [frontend.mobile.util :as mobile-util]
             [frontend.state :as state]
             ["@capacitor/app" :refer [^js App]]
+            ["@capacitor/keyboard" :refer [^js Keyboard]]
             ;; ["@capacitor/keyboard" :refer [^js Keyboard]]
             #_:clj-kondo/ignore
             ["@capacitor/status-bar" :refer [^js StatusBar]]
@@ -19,9 +20,7 @@
   ;; Keyboard watcher
   ;; (.addListener Keyboard "keyboardWillShow"
   ;;               #(state/pub-event! [:mobile/keyboard-will-show]))
-  ;; (.addListener Keyboard "keyboardDidShow"
-  ;;               #(state/pub-event! [:mobile/keyboard-did-show]))
-  )
+)
 
 (defn init!
   []
@@ -50,7 +49,7 @@
   (when (mobile-util/native-ios?)
     (ios-init))
 
-  (when (mobile-util/is-native-platform?)
+  (when (mobile-util/native-platform?)
     (.addListener mobile-util/fs-watcher "watcher"
                   (fn [event]
                     (state/pub-event! [:file-watcher/changed event])))
@@ -65,5 +64,14 @@
                         (when is-active?
                           (editor-handler/save-current-block!))))))
 
+    (.addListener Keyboard "keyboardWillShow"
+                  (fn [^js info]
+                    (let [keyboard-height (.-keyboardHeight info)]
+                      (state/pub-event! [:mobile/keyboard-will-show keyboard-height]))))
+
+    (.addListener Keyboard "keyboardWillHide"
+                  (fn []
+                    (state/pub-event! [:mobile/keyboard-will-hide])))
+    
     (.addEventListener js/window "sendIntentReceived"
-                       #(intent/handle-received))))
+                       #(intent/handle-received))))

+ 7 - 9
src/main/frontend/mobile/footer.cljs

@@ -1,12 +1,12 @@
 (ns frontend.mobile.footer
-  (:require [frontend.ui :as ui]
-            [rum.core :as rum]
-            [frontend.state :as state]
+  (:require [clojure.string :as string]
+            [frontend.date :as date]
+            [frontend.handler.editor :as editor-handler]
             [frontend.mobile.record :as record]
+            [frontend.state :as state]
+            [frontend.ui :as ui]
             [frontend.util :as util]
-            [frontend.handler.editor :as editor-handler]
-            [clojure.string :as string]
-            [frontend.date :as date]))
+            [rum.core :as rum]))
 
 (rum/defc mobile-bar-command [command-handler icon]
   [:div
@@ -46,9 +46,7 @@
 
 (rum/defc footer < rum/reactive
   []
-  (when-not (or (state/sub :editor/editing?)
-                (state/sub :block/component-editing-mode?)
-                (state/sub :editor/editing-page-title?))
+  (when (state/sub :mobile/show-tabbar?)
     [:div.cp__footer.w-full.bottom-0.justify-between
      (audio-record-cp)
      (mobile-bar-command #(state/toggle-document-mode!) "notes")

+ 4 - 52
src/main/frontend/mobile/util.cljs

@@ -6,15 +6,15 @@
 (defn platform []
   (.getPlatform Capacitor))
 
-(defn is-native-platform? []
+(defn native-platform? []
   (.isNativePlatform Capacitor))
 
 (defn native-ios? []
-  (and (is-native-platform?)
+  (and (native-platform?)
        (= (platform) "ios")))
 
 (defn native-android? []
-  (and (is-native-platform?)
+  (and (native-platform?)
        (= (platform) "android")))
 
 (defn convert-file-src [path-str]
@@ -25,7 +25,7 @@
   (defonce download-icloud-files (registerPlugin "DownloadiCloudFiles"))
   (defonce ios-file-container (registerPlugin "FileContainer")))
 ;; NOTE: both iOS and android share the same FsWatcher API
-(when (is-native-platform?)
+(when (native-platform?)
   (defonce fs-watcher (registerPlugin "FsWatcher")))
 
 (defn sync-icloud-repo [repo-dir]
@@ -39,45 +39,6 @@
 (defn hide-splash []
   (.hide SplashScreen))
 
-(def idevice-info
-  (atom
-   {:iPadPro12.9    {:width 1024 :height 1366 :statusbar 40}
-    :iPadPro11      {:width 834  :height 1194 :statusbar 40}
-    :iPadPro10.5    {:width 834  :height 1112 :statusbar 40}
-    :iPadAir10.5    {:width 834  :height 1112 :statusbar 40}
-    :iPadAir10.9    {:width 820  :height 1180 :statusbar 40}
-    :iPad10.2       {:width 810  :height 1080 :statusbar 40}
-    :iPadPro9.7     {:width 768  :height 1024 :statusbar 40}
-    :iPadmini9.7    {:width 768  :height 1024 :statusbar 40}
-    :iPadAir9.7     {:width 768  :height 1024 :statusbar 40}
-    :iPad9.7        {:width 768  :height 1024 :statusbar 40}
-    :iPadmini8.3        {:width 744  :height 1133 :statusbar 40}
-    :iPhone7Plus        {:width 476  :height 847  :statusbar 20}
-    :iPhone6sPlus   {:width 476  :height 847  :statusbar 20}
-    :iPhone6Plus        {:width 476  :height 847  :statusbar 20}
-    :iPhone13ProMax {:width 428  :height 926  :statusbar 47}
-    :iPhone12ProMax {:width 428  :height 926  :statusbar 47}
-    :iPhone11ProMax {:width 414  :height 896  :statusbar 44}
-    :iPhone11       {:width 414  :height 896  :statusbar 48}
-    :iPhoneXSMax        {:width 414  :height 896  :statusbar 48}
-    :iPhoneXR       {:width 414  :height 896  :statusbar 48}
-    :iPhone8Plus        {:width 414  :height 736  :statusbar 20}
-    :iPhone13Pro        {:width 390  :height 844  :statusbar 47}
-    :iPhone13       {:width 390  :height 844  :statusbar 47}
-    :iPhone12       {:width 390  :height 844  :statusbar 47}
-    :iPhone12Pro        {:width 390  :height 844  :statusbar 47}
-    :iPhone11Pro        {:width 375  :height 812  :statusbar 44}
-    :iPhoneXS       {:width 375  :height 812  :statusbar 44}
-    :iPhoneX        {:width 375  :height 812  :statusbar 44}
-    :iPhone8        {:width 375  :height 667  :statusbar 20}
-    :iPhone7        {:width 375  :height 667  :statusbar 20}
-    :iPhone6s       {:width 375  :height 667  :statusbar 20}
-    :iPhone6        {:width 375  :height 667  :statusbar 20}
-    :iPhone13mini   {:width 375  :height 812  :statusbar 44}
-    :iPhone12mini   {:width 375  :height 812  :statusbar 44}
-    :iPhoneSE4      {:width 320  :height 568  :statusbar 20}
-    :iPodtouch5     {:width 320  :height 568  :statusbar 20}}))
-
 (defn get-idevice-model
   []
   (when (native-ios?)
@@ -119,12 +80,3 @@
   []
   (when-let [model (get-idevice-model)]
     (string/starts-with? (first model) "iPad")))
-
-(defn get-idevice-statusbar-height
-  []
-  (let [[model landscape?] (get-idevice-model)
-        model (when-not (= model "Not a known Apple device!")
-                (keyword model))]
-    (if (and model landscape?)
-      20
-      (:statusbar (model @idevice-info)))))

+ 1 - 1
src/main/frontend/modules/instrumentation/sentry.cljs

@@ -18,7 +18,7 @@
    :initialScope {:tags
                   {:platform (cond
                                (util/electron?) "electron"
-                               (mobile-util/is-native-platform?) "mobile"
+                               (mobile-util/native-platform?) "mobile"
                                :else "web")
                    :publishing cfg/publishing?}}
    :integrations [(new posthog/SentryIntegration posthog "logseq" 5311485)

+ 9 - 7
src/main/frontend/state.cljs

@@ -58,12 +58,13 @@
      :modal/close-btn?                      nil
      :modal/subsets                         []
 
+     
      ;; right sidebar
      :ui/fullscreen?                        false
      :ui/settings-open?                     false
      :ui/sidebar-open?                      false
      :ui/left-sidebar-open?                 (boolean (storage/get "ls-left-sidebar-open?"))
-     :ui/theme                              (or (storage/get :ui/theme) (if (mobile-util/is-native-platform?) "light" "dark"))
+     :ui/theme                              (or (storage/get :ui/theme) (if (mobile-util/native-platform?) "light" "dark"))
      :ui/system-theme?                      ((fnil identity (or util/mac? util/win32? false)) (storage/get :ui/system-theme?))
      :ui/wide-mode?                         (storage/get :ui/wide-mode)
 
@@ -145,6 +146,10 @@
      :electron/updater                      {}
      :electron/user-cfgs                    nil
 
+     ;; mobile
+     :mobile/show-toolbar?                  false
+     :mobile/show-tabbar?                   true
+
      ;; plugin
      :plugin/enabled                        (and (util/electron?)
                                                  ;; true false :theme-only
@@ -280,7 +285,7 @@
 (defn get-current-repo
   []
   (or (:git/current-repo @state)
-      (when-not (mobile-util/is-native-platform?)
+      (when-not (mobile-util/native-platform?)
         "local")))
 
 (defn get-config
@@ -837,10 +842,7 @@
              (util/set-change-value input content))
 
            (when move-cursor?
-             (cursor/move-cursor-to input pos))
-
-           (when (or (util/mobile?) (mobile-util/is-native-platform?))
-             (util/make-el-center-if-near-top input))))))))
+             (cursor/move-cursor-to input pos))))))))
 
 (defn clear-edit!
   []
@@ -1168,7 +1170,7 @@
 
 (defn enable-tooltip?
   []
-  (if (or (util/mobile?) (mobile-util/is-native-platform?))
+  (if (or (util/mobile?) (mobile-util/native-platform?))
     false
     (get (get (sub-config) (get-current-repo))
          :ui/enable-tooltip?

+ 2 - 2
src/main/frontend/ui.cljs

@@ -44,7 +44,7 @@
        (util/safari?)
        (js/window.scrollTo 0 0)))
 
-(defonce icon-size (if (mobile-util/is-native-platform?) 23 20))
+(defonce icon-size (if (mobile-util/native-platform?) 23 20))
 
 (rum/defc ls-textarea
   < rum/reactive
@@ -675,7 +675,7 @@
                                              (assoc :on-mouse-down on-mouse-down
                                                     :class "cursor"))
        [:div.flex.flex-row.items-center
-        (when-not (mobile-util/is-native-platform?)
+        (when-not (mobile-util/native-platform?)
           [:a.block-control.opacity-50.hover:opacity-100.mr-2
            (cond->
             {:style    {:width       14

+ 46 - 38
src/main/frontend/util.cljc

@@ -13,7 +13,7 @@
             [cljs-time.coerce :as tc]
             [cljs-time.core :as t]
             [dommy.core :as d]
-            [frontend.mobile.util :refer [is-native-platform?]]
+            [frontend.mobile.util :refer [native-platform? native-ios?]]
             [goog.dom :as gdom]
             [goog.object :as gobj]
             [goog.string :as gstring]
@@ -82,7 +82,7 @@
 
 #?(:cljs
    (def nfs? (and (not (electron?))
-                  (not (is-native-platform?)))))
+                  (not (native-platform?)))))
 
 #?(:cljs
    (defn file-protocol?
@@ -1338,42 +1338,50 @@
             (catch js/Error _e
               false)))))
 
-#?(:cljs
-   (defn make-el-into-center-viewport
-     [^js/HTMLElement el]
-     (when el
-       (.scrollIntoView el #js {:block "center" :behavior "smooth"}))))
-
-#?(:cljs
-   (defn make-el-cursor-position-into-center-viewport
-     [^js/HTMLElement el]
-     (when el
-       (let [main-node (gdom/getElement "main-content-container")
-             pos (get-selection-start el)
-             cursor-top (some-> (gdom/getElement "mock-text")
-                                gdom/getChildren
-                                array-seq
-                                (nth-safe pos)
-                                .-offsetTop)
-             box-caret (.getBoundingClientRect el)
-             box-top (.-top box-caret)
-             box-bottom (.-bottom box-caret)
-             vw-height (or (.-height js/window.visualViewport)
-                           (.-clientHeight js/document.documentElement))
-             scroll-top (.-scrollTop main-node)
-             cursor-y (if cursor-top (+ cursor-top box-top) box-bottom)
-             scroll (- cursor-y (/ vw-height 2))]
-         (when (> scroll 0)
-           (set! (.-scrollTop main-node) (+ scroll-top scroll)))))))
-
-#?(:cljs
-   (defn make-el-center-if-near-top
-     ([^js/HTMLElement el]
-      (make-el-center-if-near-top el 80))
-     ([^js/HTMLElement el offset]
-      (let [target-top (.-top (.getBoundingClientRect el))]
-        (when (<= target-top (or (safe-parse-int offset) 0))
-          (make-el-into-center-viewport el))))))
+(def keyboard-height (atom nil))
+#?(:cljs
+   (defn scroll-editor-cursor
+     [^js/HTMLElement el & {:keys [to-vw-one-quarter? to-vw-center?]}]
+     (when (and el (native-platform?))
+       (let [box-rect    (.getBoundingClientRect el)
+             box-top     (.-top box-rect)
+             box-bottom  (.-bottom box-rect)
+
+             main-node   (app-scroll-container-node)
+             scroll-top  (.-scrollTop main-node)
+
+             current-pos (get-selection-start el)
+             cursor-top  (some-> (gdom/getElement "mock-text")
+                                 gdom/getChildren
+                                 array-seq
+                                 (nth-safe current-pos)
+                                 .-offsetTop)
+
+             cursor-y    (if cursor-top (+ cursor-top box-top) box-bottom)
+             vw-height   (or (.-height js/window.visualViewport)
+                             (.-clientHeight js/document.documentElement))
+             scroll      (- cursor-y (- vw-height (+ @keyboard-height 40)))]
+         (cond
+           (and to-vw-one-quarter? (> cursor-y (* vw-height 0.4)))
+           (set! (.-scrollTop main-node) (+ scroll-top (- cursor-y (/ vw-height 4))))
+
+           (and to-vw-center? (> cursor-y (/ vw-height 2)))
+           (.scrollBy main-node (bean/->js {:top (- cursor-y (/ vw-height 2))}))
+
+           (and (< cursor-y 86) (>= cursor-y 62))
+           (.scrollBy main-node (bean/->js {:top -24}))
+
+           (< cursor-y 56)
+           (let [_ (.scrollIntoView el true)
+                 main-node (app-scroll-container-node)
+                 scroll-top (.-scrollTop main-node)]
+             (set! (.-scrollTop main-node) (- scroll-top (/ vw-height 4))))
+
+           (> scroll 0)
+           (set! (.-scrollTop main-node) (+ scroll-top 24))
+
+           :else
+           nil)))))
 
 #?(:cljs
    (defn sm-breakpoint?