enhance(ux): use presentingElement cards instead of nav

This commit is contained in:
Tienson Qin
2025-06-03 05:35:19 +08:00
parent 903c1ea856
commit 7c510aaa67
8 changed files with 122 additions and 116 deletions

View File

@@ -12,7 +12,10 @@ import {
IonDatetimeButton, IonRefresher,
IonRefresherContent, IonMenu,
IonMenuButton, IonActionSheet, IonSearchbar,
IonRouterOutlet
IonRouterOutlet, useIonViewDidEnter,
useIonViewDidLeave,
useIonViewWillEnter,
useIonViewWillLeave,
} from '@ionic/react'
declare global {
@@ -33,7 +36,11 @@ const ionicUI = {
IonDatetimeButton, IonRefresher,
IonRefresherContent, IonMenu,
IonMenuButton, IonActionSheet, IonSearchbar,
IonRouterOutlet
IonRouterOutlet,
useIonViewDidEnter,
useIonViewDidLeave,
useIonViewWillEnter,
useIonViewWillLeave,
}
// initialize ionic mode
@@ -43,4 +50,4 @@ window.LSIonic = ionicUI
export {
setupIonicReact,
}
}

View File

@@ -1,14 +1,13 @@
(ns capacitor.components.app
(:require ["../externals.js"]
["@capacitor/app" :refer [App]]
[capacitor.components.search :as search]
[capacitor.components.settings :as settings]
[capacitor.components.ui :as ui-component]
[capacitor.ionic :as ion]
[capacitor.nav :as nav]
[capacitor.state :as state]
[clojure.string :as string]
[frontend.components.journal :as journal]
[frontend.components.page :as page]
[frontend.components.rtc.indicator :as rtc-indicator]
[frontend.config :as config]
[frontend.date :as date]
@@ -88,24 +87,40 @@
[:input.absolute.top-4.left-0.w-1.h-1.opacity-0
{:id "app-keep-keyboard-open-input"}])
(rum/defc journals < rum/reactive
(rum/defc journals
[]
(let [show-action-bar? (fstate/sub :mobile/show-action-bar?)]
(ion/content
(ui-component/classic-app-container-wrap
[:div.pt-3
(journal/all-journals)
(when show-action-bar?
(action-bar/action-bar))]))))
(ui-component/classic-app-container-wrap
[:div.pt-3
(journal/all-journals)]))
(rum/defc home < rum/reactive
{:did-mount (fn [state]
(ui/inject-document-devices-envs!)
state)}
[]
(let [db-restoring? (fstate/sub :db/restoring?)]
(rum/defc modal < rum/reactive
[presenting-element]
(let [{:keys [open? block]} (rum/react state/*modal-data)
show-action-bar? (fstate/sub :mobile/show-action-bar?)]
(ion/modal
{:isOpen (boolean open?)
:presenting-element presenting-element
:onDidDismiss (fn [] (state/set-modal! nil))
:expand "block"}
(ion/content {:class "ion-padding"}
(page/page-cp (db/entity [:block/uuid (:block/uuid block)]))
(mobile-bar/mobile-bar)
(when show-action-bar?
(action-bar/action-bar))))))
(rum/defc home-inner
[db-restoring?]
(let [[current-tab] (state/use-tab)
search? (= current-tab "search")
*page (hooks/use-ref nil)
[presenting-element set-presenting-element!] (hooks/use-state nil)]
(hooks/use-effect!
(fn []
(set-presenting-element! (rum/deref *page)))
[])
(ion/page
{:id "app-main-content"}
{:id "app-main-content"
:ref *page}
(ion/header
(ion/toolbar
(ion/buttons {:slot "start"}
@@ -119,9 +134,9 @@
(let [apply-date! (fn [date]
(let [page-name (date/journal-name (gdate/Date. (js/Date. date)))]
(if-let [journal (db/get-page page-name)]
(nav/nav-to-block! journal)
(state/open-block-modal! journal)
(-> (page-handler/<create! page-name {:redirect? false})
(p/then #(nav/nav-to-block! (db/get-page page-name)))))))]
(p/then #(state/open-block-modal! (db/get-page page-name)))))))]
(if (mobile-util/native-platform?)
(-> (.showDatePicker mobile-util/ui-local)
@@ -156,57 +171,25 @@
])]))))
;; main content
(if db-restoring?
(cond
db-restoring?
(ion/content
[:strong.flex.justify-center.items-center.py-24
(ion/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
(journals)))))
search?
""
:else
(ion/content
(journals)
(modal presenting-element))))))
(rum/defc settings
(rum/defc home < rum/reactive
{:did-mount (fn [state]
(ui/inject-document-devices-envs!)
state)}
[]
(ion/page
{:id "settings-tab"}
(ion/header
(ion/toolbar
"Settings"))
[:div.flex.flex-1.p-4 "TODO..."]))
(rum/defc tabs
[]
(let [nav-ref (hooks/use-ref nil)
[_ set-nav-root!] (state/use-nav-root)]
(hooks/use-effect!
(fn []
(when-let [nav (rum/deref nav-ref)]
(set-nav-root! nav))
#())
[(rum/deref nav-ref)])
(ion/tabs
{:onIonTabsDidChange (fn [^js e]
(state/set-tab! (.-tab (.-detail e))))}
(ion/tab
{:tab "home"}
(ion/nav {:ref nav-ref
:root home ;;settings/page
:animated true
:swipeGesture true}))
(ion/tab
{:tab "search"}
(ion/content
(search/search)))
(ion/tab
{:tab "settings"}
(ion/content
(settings/page)))
(bottom-tabs)
(keep-keyboard-open)
(ui-component/install-notifications)
(ui-component/install-modals)
(shui-toaster/install-toaster)
(shui-dialog/install-modals)
(shui-popup/install-popups))))
(let [db-restoring? (fstate/sub :db/restoring?)]
(home-inner db-restoring?)))
(defn use-theme-effects!
[current-repo]
@@ -228,39 +211,44 @@
(some-> js/window.externalsjs (.settleStatusBar)))
[current-repo]))
(defn use-navigation-effects!
(rum/defc tabs
[current-repo]
(use-theme-effects! current-repo)
(ion/tabs
{:onIonTabsDidChange (fn [^js e]
(state/set-tab! (.-tab (.-detail e))))}
(ion/tab
{:tab "home"}
(ion/content
(home)))
(ion/tab
{:tab "search"}
(ion/content
(search/search)))
(ion/tab
{:tab "settings"}
(ion/content
(settings/page)))
(bottom-tabs)
(keep-keyboard-open)
(ui-component/install-notifications)
(ui-component/install-modals)
(shui-toaster/install-toaster)
(shui-dialog/install-modals)
(shui-popup/install-popups)))
(rum/defc main < rum/reactive
[]
(hooks/use-effect!
(fn []
(let [handle-back!
(fn []
(cond
(seq (ui-component/get-modal))
(ui-component/close-modal!)
(seq (shui-dialog/get-modal (shui-dialog/get-first-modal-id)))
(shui-dialog/close!)
(seq (fstate/get-selection-blocks))
(fstate/clear-selection!)
:else
(-> (nav/nav-length?)
(p/then (fn [len]
(if (= len 1)
(.exitApp App)
(nav/nav-pop!))))))
(fstate/clear-edit!))
^js back-listener (.addListener App "backButton" handle-back!)]
#(.remove back-listener)))
[]))
(rum/defc main []
(let [[current-repo] (frum/use-atom-in fstate/state :git/current-repo)]
(use-theme-effects! current-repo)
(use-navigation-effects!)
[:<>
(tabs)
(mobile-bar/mobile-bar)]))
(let [current-repo (fstate/sub :git/current-repo)
show-action-bar? (fstate/sub :mobile/show-action-bar?)
{:keys [open?]} (rum/react state/*modal-data)]
(ion/app
(tabs current-repo)
(when-not open?
[:<>
(mobile-bar/mobile-bar)
(when show-action-bar?
(action-bar/action-bar))]))))

View File

@@ -117,9 +117,7 @@
(let [block (or source-page source-block)]
(ion/item
{:on-click (fn []
(state/set-tab! "home")
(.select (dom/sel1 "ion-tabs") "home")
(nav/nav-to-block! block))}
(state/open-block-modal! block))}
[:div.flex.flex-col.gap-1.py-1
(when header
[:div.opacity-50.text-sm

View File

@@ -2,6 +2,7 @@
(:require ["react-dom/client" :as rdc]
[capacitor.components.app :as app]
[capacitor.nav :as nav]
[capacitor.state :as state]
[frontend.background-tasks]
[frontend.components.page :as page]
[frontend.components.user.login :as login]
@@ -20,11 +21,7 @@
(.render root (app/main)))
(def routes
[["/login"
{:name :user-login
:view login/page}]
["/page/:name"
[["/page/:name"
{:name :page
:view (fn [route-match]
(page/page-cp (assoc route-match :current-page? true)))}]])
@@ -41,7 +38,8 @@
(let [id-str (get-in route [:path-params :name])]
(when (util/uuid-string? id-str)
(let [page-uuid (uuid id-str)]
(nav/nav-to-block! {:block/uuid page-uuid}))))
(state/set-modal! {:open? true
:block {:block/uuid page-uuid}}))))
:user-login
nil
nil))

View File

@@ -8,6 +8,10 @@
(def ^js ionic-react js/window.LSIonic)
(def ^js camera (.-Camera ionicCamera))
(def ^js camera-result-type (.-CameraResultType ionicCamera))
(def ^js useIonViewDidEnter (.-useIonViewDidEnter ionic-react))
(def ^js useIonViewDidLeave (.-useIonViewDidLeave ionic-react))
(def ^js useIonViewWillEnter (.-useIonViewWillEnter ionic-react))
(def ^js useIonViewWillLeave (.-useIonViewWillLeave ionic-react))
(def tabler-icon shui-icon/root)

View File

@@ -15,6 +15,7 @@
(defn nav-length? []
(some-> ^js @state/*nav-root (.getLength)))
(defn nav-to-block!
[page-or-block]
(nav-push! #(page/page page-or-block)))
(comment
(defn nav-to-block!
[page-or-block]
(nav-push! #(page/page page-or-block))))

View File

@@ -11,3 +11,13 @@
(reset! *tab tab))
(defn use-tab [] (r/use-atom *tab))
(defonce *modal-data (atom nil))
(defn set-modal!
[data]
(reset! *modal-data data))
(defn open-block-modal!
[block]
(set-modal! {:open? true
:block block}))

View File

@@ -94,7 +94,7 @@
#?(:cljs
(defn current-page-scroll
[]
(some-> (js/document.querySelector "ion-nav > .ion-page:not(.ion-page-hidden)")
(some-> (js/document.querySelector ".ion-page:not(.ion-page-hidden)")
(.querySelector "ion-content")
(.-shadowRoot)
(.querySelector "[part=scroll]"))))