diff --git a/android/app/src/main/assets/capacitor.config.json b/android/app/src/main/assets/capacitor.config.json index d188e8a97cb..4882e518a90 100644 --- a/android/app/src/main/assets/capacitor.config.json +++ b/android/app/src/main/assets/capacitor.config.json @@ -10,6 +10,9 @@ "androidScaleType": "CENTER_CROP", "splashImmersive": false, "backgroundColor": "#002b36" + }, + "Keyboard": { + "resize": "none" } }, "ios": { diff --git a/capacitor.config.ts b/capacitor.config.ts index 2fbd42eec8e..d41e12112ae 100644 --- a/capacitor.config.ts +++ b/capacitor.config.ts @@ -13,6 +13,10 @@ const config: CapacitorConfig = { splashImmersive: false, backgroundColor: "#002b36" }, + + Keyboard: { + resize: "none" + } }, ios: { scheme: "Logseq" diff --git a/ios/App/App/capacitor.config.json b/ios/App/App/capacitor.config.json index f301a40bb2b..0e68ee3dd25 100644 --- a/ios/App/App/capacitor.config.json +++ b/ios/App/App/capacitor.config.json @@ -10,6 +10,9 @@ "androidScaleType": "CENTER_CROP", "splashImmersive": false, "backgroundColor": "#002b36" + }, + "Keyboard": { + "resize": "none" } }, "ios": { diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 2a58616f9d4..a317ed2d04c 100644 --- a/src/main/frontend/components/block.cljs +++ b/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 diff --git a/src/main/frontend/components/header.cljs b/src/main/frontend/components/header.cljs index 8d98ac861bf..1ebcbea0a94 100644 --- a/src/main/frontend/components/header.cljs +++ b/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? diff --git a/src/main/frontend/components/header.css b/src/main/frontend/components/header.css index 1133e5fc518..2fea64d0a27 100644 --- a/src/main/frontend/components/header.css +++ b/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 { diff --git a/src/main/frontend/components/onboarding/setups.cljs b/src/main/frontend/components/onboarding/setups.cljs index 327ce88e0bb..eaa52ba0e8c 100644 --- a/src/main/frontend/components/onboarding/setups.cljs +++ b/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 [] diff --git a/src/main/frontend/components/page.cljs b/src/main/frontend/components/page.cljs index 0a103b574b6..64f8d85a880 100644 --- a/src/main/frontend/components/page.cljs +++ b/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] diff --git a/src/main/frontend/components/page_menu.cljs b/src/main/frontend/components/page_menu.cljs index d6cf781c1f9..b88dc6e6a17 100644 --- a/src/main/frontend/components/page_menu.cljs +++ b/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! diff --git a/src/main/frontend/components/repo.cljs b/src/main/frontend/components/repo.cljs index 4c90f7d43a3..d024ba07b6d 100644 --- a/src/main/frontend/components/repo.cljs +++ b/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 diff --git a/src/main/frontend/components/settings.cljs b/src/main/frontend/components/settings.cljs index 01f84e7d6a9..e63a117346c 100644 --- a/src/main/frontend/components/settings.cljs +++ b/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 diff --git a/src/main/frontend/components/sidebar.cljs b/src/main/frontend/components/sidebar.cljs index 72f3bf62472..74baa9c42da 100644 --- a/src/main/frontend/components/sidebar.cljs +++ b/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))] diff --git a/src/main/frontend/components/widgets.cljs b/src/main/frontend/components/widgets.cljs index c6ec4da6ef5..6a9185725d9 100644 --- a/src/main/frontend/components/widgets.cljs +++ b/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!)) diff --git a/src/main/frontend/config.cljs b/src/main/frontend/config.cljs index 1ffa68f92b3..aec3240b962 100644 --- a/src/main/frontend/config.cljs +++ b/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))) diff --git a/src/main/frontend/db/conn.cljs b/src/main/frontend/db/conn.cljs index 72aafc0dd47..5b9dc096ee7 100644 --- a/src/main/frontend/db/conn.cljs +++ b/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)) diff --git a/src/main/frontend/extensions/excalidraw.cljs b/src/main/frontend/extensions/excalidraw.cljs index 7481a7b3774..42e0335e3df 100644 --- a/src/main/frontend/extensions/excalidraw.cljs +++ b/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)))) diff --git a/src/main/frontend/extensions/video/youtube.cljs b/src/main/frontend/extensions/video/youtube.cljs index 4be10323416..1eba6742f7c 100644 --- a/src/main/frontend/extensions/video/youtube.cljs +++ b/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." diff --git a/src/main/frontend/fs.cljs b/src/main/frontend/fs.cljs index af7232d71a9..391b8ae1ca6 100644 --- a/src/main/frontend/fs.cljs +++ b/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)] diff --git a/src/main/frontend/handler.cljs b/src/main/frontend/handler.cljs index b784ecab7ad..a4f05586868 100644 --- a/src/main/frontend/handler.cljs +++ b/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!) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 1b0cca5b96a..146e4f21320 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/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) diff --git a/src/main/frontend/handler/editor/lifecycle.cljs b/src/main/frontend/handler/editor/lifecycle.cljs index d7ae20de139..2a8a096ba04 100644 --- a/src/main/frontend/handler/editor/lifecycle.cljs +++ b/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! diff --git a/src/main/frontend/handler/events.cljs b/src/main/frontend/handler/events.cljs index e29d4802881..31327756683 100644 --- a/src/main/frontend/handler/events.cljs +++ b/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)] diff --git a/src/main/frontend/handler/page.cljs b/src/main/frontend/handler/page.cljs index 63dc45a85f1..1bfbbe3ebd7 100644 --- a/src/main/frontend/handler/page.cljs +++ b/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) diff --git a/src/main/frontend/handler/ui.cljs b/src/main/frontend/handler/ui.cljs index 12f5ab64ecc..cf808835ade 100644 --- a/src/main/frontend/handler/ui.cljs +++ b/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))] diff --git a/src/main/frontend/handler/web/nfs.cljs b/src/main/frontend/handler/web/nfs.cljs index f6da0b7e00c..1cf2ff684cc 100644 --- a/src/main/frontend/handler/web/nfs.cljs +++ b/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? diff --git a/src/main/frontend/mobile/core.cljs b/src/main/frontend/mobile/core.cljs index 6127394043b..3ba95a148b0 100644 --- a/src/main/frontend/mobile/core.cljs +++ b/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)))) \ No newline at end of file + #(intent/handle-received)))) diff --git a/src/main/frontend/mobile/footer.cljs b/src/main/frontend/mobile/footer.cljs index 1005675d05c..677bbb898cd 100644 --- a/src/main/frontend/mobile/footer.cljs +++ b/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") diff --git a/src/main/frontend/mobile/util.cljs b/src/main/frontend/mobile/util.cljs index f3f4808c35e..dffc847af77 100644 --- a/src/main/frontend/mobile/util.cljs +++ b/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))))) diff --git a/src/main/frontend/modules/instrumentation/sentry.cljs b/src/main/frontend/modules/instrumentation/sentry.cljs index 28f90748f65..ed393a74a13 100644 --- a/src/main/frontend/modules/instrumentation/sentry.cljs +++ b/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) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index a2bb9c6d890..d37804c0529 100644 --- a/src/main/frontend/state.cljs +++ b/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? diff --git a/src/main/frontend/ui.cljs b/src/main/frontend/ui.cljs index 96b6f05a71e..4275619c327 100644 --- a/src/main/frontend/ui.cljs +++ b/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 diff --git a/src/main/frontend/util.cljc b/src/main/frontend/util.cljc index 5e2730f3cb7..994e7c13c28 100644 --- a/src/main/frontend/util.cljc +++ b/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?