Browse Source

Add bottom tabs

Tienson Qin 5 months ago
parent
commit
a8fa4411c8
2 changed files with 117 additions and 112 deletions
  1. 112 109
      src/main/capacitor/app.cljs
  2. 5 3
      src/main/capacitor/ionic.cljs

+ 112 - 109
src/main/capacitor/app.cljs

@@ -20,8 +20,8 @@
             [frontend.rum :as frum]
             [frontend.state :as fstate]
             [goog.date :as gdate]
-            [logseq.db :as ldb]
             [logseq.shui.dialog.core :as shui-dialog]
+            [logseq.shui.hooks :as hooks]
             [logseq.shui.popup.core :as shui-popup]
             [logseq.shui.toaster.core :as shui-toaster]
             [promesa.core :as p]
@@ -60,28 +60,20 @@
                            (p/then #())))))}
       (ionic/tabler-icon "plus" {:size 24}))]))
 
-(rum/defc app-sidebar []
-  (ionic/ion-menu {:content-id "app-main-content"
-                   :type "push"}
-                  (ionic/ion-header
-                   (ionic/ion-toolbar
-                    [:strong.px-2 {:slot "start"} "Navigations"]))
-                  (ionic/ion-content
-                   [:div.p-4
-                    [:strong "hello, logseq?"]])))
-
-(rum/defc app-tabbar []
-  (ionic/ion-tab-bar {:color "light"
-                      :class "w-full fixed bottom-4"}
-                     (ionic/ion-tab-button {:tab "tab1"
-                                            :selected true
-                                            :on-click #(js/alert "home")}
-                                           (ionic/tabler-icon "home" {:size 22}) "Journals")
-                     (ionic/ion-tab-button {:tab "tab0"
-                                            :selected false}
-                                           (ionic/tabler-icon "circle-plus" {:size 24}) "Capture New")
-                     (ionic/ion-tab-button {:tab "tab2"}
-                                           (ionic/tabler-icon "settings" {:size 22}) "Settings")))
+(rum/defc bottom-tabs
+  []
+  (ionic/ion-tab-bar
+   {:slot "bottom"}
+   (ionic/ion-tab-button
+    {:tab "home"
+     :selected true}
+    (ionic/tabler-icon "home" {:size 22}) "Journals")
+   (ionic/ion-tab-button
+    {:tab "search"}
+    (ionic/tabler-icon "search" {:size 22}) "Search")
+   (ionic/ion-tab-button
+    {:tab "settings"}
+    (ionic/tabler-icon "settings" {:size 22}) "Settings")))
 
 (rum/defc journals-list < rum/reactive db-mixins/query
   []
@@ -109,9 +101,8 @@
   [:input.absolute.top-4.left-0.w-1.h-1.opacity-0
    {:id "app-keep-keyboard-open-input"}])
 
-(rum/defc home []
-  (let [[reload set-reload!] (rum/use-state 0)]
-
+(rum/defc journals []
+  (let [[reload set-reload!] (hooks/use-state 0)]
     (ionic/ion-content
      (ionic/ion-refresher
       {:slot "fixed"
@@ -126,80 +117,111 @@
       (ionic/ion-refresher-content))
 
      [:div.pt-4.px-4
-       ;; (journals-list)
-
       [:main#app-container-wrapper.ls-fold-button-on-right
        [:div#app-container
         [:div#main-container.flex.flex-1
          [:div#main-content-container.w-full
-          (journal/all-journals)]]]]
+          (journal/all-journals)]]]]])))
 
-       ;(contents-playground)
-      ]
-
-      ;; tabbar
-      ;(app-tabbar)
-     )))
-(rum/defc root < rum/reactive
+(rum/defc home < rum/reactive
   []
   (let [db-restoring? (fstate/sub :db/restoring?)]
-    [:<>
-     (ionic/ion-page
-      {:id "app-main-content"}
-      (ionic/ion-header
-       ;; FIXME: iOS camera
-       {:style {:padding-top 25}}
-       (ionic/ion-toolbar
-        (ionic/ion-buttons {:slot "start"}
-                           (app-graphs-select))
-
-        (ionic/ion-buttons {:slot "end"}
-                           (ionic/ion-button
-                            {:size "small" :fill "clear"
-                             :on-click (fn []
-                                         (let [apply-date! (fn [date]
-                                                             (let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
-                                                                   nav-to-journal! #(cc-utils/nav-to-block! % {:reload-pages! (fn [] ())})]
-                                                               (if-let [journal (handler/local-page page-name)]
-                                                                 (nav-to-journal! journal)
-                                                                 (-> (handler/<create-page! page-name)
-                                                                     (p/then #(nav-to-journal! (handler/local-page page-name)))))))]
-
-                                           (if (mobile-util/native-android?)
-                                             (-> (.showDatePicker mobile-util/ui-local)
-                                                 (p/then (fn [^js e] (some-> e (.-value) (apply-date!)))))
-
-                                             (ui/open-modal!
-                                              (fn [{:keys [close!]}]
-                                                (ionic/ion-datetime
-                                                 {:presentation "date"
-                                                  :onIonChange (fn [^js e]
-                                                                 (let [val (.-value (.-detail e))]
-                                                                   (apply-date! val)
-                                                                   (close!)))}))))))}
-                            [:span {:slot "icon-only"} (ionic/tabler-icon "calendar-month" {:size 26})])
-
-                           (ionic/ion-button {:fill "clear"}
-                                             (ionic/ion-nav-link
-                                              {:routerDirection "forward"
-                                               :class "w-full"
-                                               :component settings/page}
-                                              [:span {:slot "icon-only"} (ionic/tabler-icon "dots-circle-horizontal" {:size 26})])))))
+    (ionic/ion-page
+     {:id "app-main-content"}
+     (ionic/ion-header
+      (ionic/ion-toolbar
+       (ionic/ion-buttons {:slot "start"}
+                          (app-graphs-select))
+
+       (ionic/ion-buttons {:slot "end"}
+                          (ionic/ion-button
+                           {:size "small" :fill "clear"
+                            :on-click (fn []
+                                        (let [apply-date! (fn [date]
+                                                            (let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
+                                                                  nav-to-journal! #(cc-utils/nav-to-block! % {:reload-pages! (fn [] ())})]
+                                                              (if-let [journal (handler/local-page page-name)]
+                                                                (nav-to-journal! journal)
+                                                                (-> (handler/<create-page! page-name)
+                                                                    (p/then #(nav-to-journal! (handler/local-page page-name)))))))]
+
+                                          (if (mobile-util/native-android?)
+                                            (-> (.showDatePicker mobile-util/ui-local)
+                                                (p/then (fn [^js e] (some-> e (.-value) (apply-date!)))))
+
+                                            (ui/open-modal!
+                                             (fn [{:keys [close!]}]
+                                               (ionic/ion-datetime
+                                                {:presentation "date"
+                                                 :onIonChange (fn [^js e]
+                                                                (let [val (.-value (.-detail e))]
+                                                                  (apply-date! val)
+                                                                  (close!)))}))))))}
+                           [:span {:slot "icon-only"} (ionic/tabler-icon "calendar-month" {:size 26})])
+
+                          (ionic/ion-button {:fill "clear"}
+                                            (ionic/ion-nav-link
+                                             {:routerDirection "forward"
+                                              :class "w-full"
+                                              :component settings/page}
+                                             [:span {:slot "icon-only"} (ionic/tabler-icon "dots-circle-horizontal" {:size 26})])))))
 
        ;; main content
-      (if db-restoring?
-        (ionic/ion-content
-         [:strong.flex.justify-center.items-center.py-24
-          (ionic/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
-        (home)))]))
+     (if db-restoring?
+       (ionic/ion-content
+        [:strong.flex.justify-center.items-center.py-24
+         (ionic/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
+       (journals)))))
 
-(rum/defc main []
-  (let [nav-ref (rum/use-ref nil)
-        [_ set-nav-root!] (state/use-nav-root)
-        current-repo (frum/use-atom-in fstate/state :git/current-repo)]
+(rum/defc search
+  []
+  (ionic/ion-page
+   {:id "search-tab"}
+   (ionic/ion-header
+    (ionic/ion-toolbar
+     "Search"))
+   [:div.flex.flex-1.p-4 "Search results"]))
+
+(rum/defc settings
+  []
+  (ionic/ion-page
+   {:id "settings-tab"}
+   (ionic/ion-header
+    (ionic/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)])
+    (ionic/ion-tabs
+     (ionic/ion-tab
+      {:tab "home"}
+      (ionic/ion-nav {:ref nav-ref
+                      :root home                            ;;settings/page
+                      :animated true
+                      :swipeGesture true}))
+     (ionic/ion-tab
+      {:tab "search"}
+      (ionic/ion-content
+       (search)))
+     (ionic/ion-tab
+      {:tab "settings"}
+      (ionic/ion-content
+       (settings)))
+     (bottom-tabs))))
 
+(rum/defc main []
+  (let [current-repo (frum/use-atom-in fstate/state :git/current-repo)]
     ;; global
-    (rum/use-effect!
+    (hooks/use-effect!
      (fn []
        (some-> js/window.externalsjs (.settleStatusBar))
        (some-> js/window.externalsjs
@@ -207,7 +229,7 @@
      [current-repo])
 
     ;; navigation
-    (rum/use-effect!
+    (hooks/use-effect!
      (fn []
        (let [handle-back!
              (fn []
@@ -228,23 +250,4 @@
          #(.remove back-listener)))
      [])
 
-    (rum/use-effect!
-     (fn []
-       (set-nav-root! (rum/deref nav-ref))
-       #())
-     [(rum/deref nav-ref)])
-
-    [:> (.-IonApp ionic/ionic-react)
-     [:<>
-      (ionic/ion-nav {:ref nav-ref
-                      :root root                            ;;settings/page
-                      :animated true
-                      :swipeGesture true})
-
-      (keep-keyboard-open)
-      (ui/install-notifications)
-      (ui/install-modals)
-
-      (shui-toaster/install-toaster)
-      (shui-dialog/install-modals)
-      (shui-popup/install-popups)]]))
+    (tabs)))

+ 5 - 3
src/main/capacitor/ionic.cljs

@@ -1,6 +1,6 @@
 (ns capacitor.ionic
-  (:require ["@ionic/react" :as ionicReact]
-            ["@capacitor/camera" :as ionicCamera]
+  (:require ["@capacitor/camera" :as ionicCamera]
+            ["@ionic/react" :as ionicReact]
             [logseq.shui.icon.v2 :as shui-icon]
             [logseq.shui.util :as shui-util]))
 
@@ -11,6 +11,7 @@
 
 (def tabler-icon shui-icon/root)
 
+(defonce ion-app (shui-util/react->rum (.-IonApp ionic-react) true))
 (defonce ion-page (shui-util/react->rum (.-IonPage ionic-react) true))
 (defonce ion-nav (shui-util/react->rum (.-IonNav ionic-react) true))
 (defonce ion-nav-link (shui-util/react->rum (.-IonNavLink ionic-react) true))
@@ -27,7 +28,8 @@
 (defonce ion-textarea (shui-util/react->rum (.-IonTextarea ionic-react) true))
 (defonce ion-icon (shui-util/react->rum (.-IonIcon ionic-react) true))
 (defonce ion-badge (shui-util/react->rum (.-IonBadge ionic-react) true))
-(defonce ion-tabs (shui-util/react->rum (.-IonTabs ionic-react) true))
+(defonce ion-tabs (shui-util/react->rum (.-IonTabs ionic-react) false))
+(defonce ion-tab (shui-util/react->rum (.-IonTab ionic-react) false))
 (defonce ion-tab-bar (shui-util/react->rum (.-IonTabBar ionic-react) false))
 (defonce ion-tab-button (shui-util/react->rum (.-IonTabButton ionic-react) false))
 (defonce ion-modal (shui-util/react->rum (.-IonModal ionic-react) false))