|
|
@@ -1,30 +1,31 @@
|
|
|
(ns capacitor.app
|
|
|
- (:require ["@capacitor/app" :refer [App]]
|
|
|
+ (:require ["./externals.js"]
|
|
|
+ ["@capacitor/app" :refer [App]]
|
|
|
["@capacitor/status-bar" :refer [StatusBar Style]]
|
|
|
- ["./externals.js"]
|
|
|
- [clojure.string :as string]
|
|
|
- [logseq.shui.dialog.core :as shui-dialog]
|
|
|
- [logseq.shui.popup.core :as shui-popup]
|
|
|
- [logseq.shui.toaster.core :as shui-toaster]
|
|
|
- [rum.core :as rum]
|
|
|
- [frontend.rum :as frum]
|
|
|
- [promesa.core :as p]
|
|
|
- [capacitor.ionic :as ionic]
|
|
|
- [capacitor.state :as state]
|
|
|
- [capacitor.handler :as handler]
|
|
|
- [capacitor.components.nav-utils :as cc-utils]
|
|
|
[capacitor.components.blocks :as cc-blocks]
|
|
|
+ [capacitor.components.nav-utils :as cc-utils]
|
|
|
+ [capacitor.components.settings :as settings]
|
|
|
[capacitor.components.ui :as ui]
|
|
|
- [frontend.db.conn :as db-conn]
|
|
|
+ [capacitor.handler :as handler]
|
|
|
+ [capacitor.ionic :as ionic]
|
|
|
+ [capacitor.state :as state]
|
|
|
+ [clojure.string :as string]
|
|
|
+ [frontend.components.journal :as journal]
|
|
|
+ [frontend.date :as frontend-date]
|
|
|
[frontend.db-mixins :as db-mixins]
|
|
|
- [frontend.state :as fstate]
|
|
|
+ [frontend.db.conn :as db-conn]
|
|
|
[frontend.db.utils :as db-util]
|
|
|
- [frontend.date :as frontend-date]
|
|
|
[frontend.handler.repo :as repo-handler]
|
|
|
[frontend.mobile.util :as mobile-util]
|
|
|
+ [frontend.rum :as frum]
|
|
|
+ [frontend.state :as fstate]
|
|
|
[goog.date :as gdate]
|
|
|
[logseq.db :as ldb]
|
|
|
- [capacitor.components.settings :as settings]))
|
|
|
+ [logseq.shui.dialog.core :as shui-dialog]
|
|
|
+ [logseq.shui.popup.core :as shui-popup]
|
|
|
+ [logseq.shui.toaster.core :as shui-toaster]
|
|
|
+ [promesa.core :as p]
|
|
|
+ [rum.core :as rum]))
|
|
|
|
|
|
(rum/defc app-graphs-select
|
|
|
[]
|
|
|
@@ -35,52 +36,52 @@
|
|
|
"Select a Graph")]
|
|
|
[:<>
|
|
|
(ionic/ion-button
|
|
|
- {:fill "clear" :mode "ios"
|
|
|
- :class "border-none w-full rounded-lg font-semibold pt-2"
|
|
|
- :on-click (fn []
|
|
|
- (ui/open-modal! "Switch graph"
|
|
|
- {:type :action-sheet
|
|
|
- :buttons (for [repo graphs]
|
|
|
- {:text (some-> (:url repo) (string/replace #"^logseq_db_" ""))
|
|
|
- :role (:url repo)})
|
|
|
- :inputs []
|
|
|
- :on-action (fn [e]
|
|
|
- (when-let [url (:role e)]
|
|
|
- (when (string/starts-with? url "logseq_db_")
|
|
|
- (fstate/pub-event! [:graph/switch url]))))}))}
|
|
|
- short-repo-name)
|
|
|
+ {:fill "clear" :mode "ios"
|
|
|
+ :class "border-none w-full rounded-lg font-semibold pt-2"
|
|
|
+ :on-click (fn []
|
|
|
+ (ui/open-modal! "Switch graph"
|
|
|
+ {:type :action-sheet
|
|
|
+ :buttons (for [repo graphs]
|
|
|
+ {:text (some-> (:url repo) (string/replace #"^logseq_db_" ""))
|
|
|
+ :role (:url repo)})
|
|
|
+ :inputs []
|
|
|
+ :on-action (fn [e]
|
|
|
+ (when-let [url (:role e)]
|
|
|
+ (when (string/starts-with? url "logseq_db_")
|
|
|
+ (fstate/pub-event! [:graph/switch url]))))}))}
|
|
|
+ short-repo-name)
|
|
|
|
|
|
(ionic/ion-button
|
|
|
- {:class "relative -left-2 pt-1.5 opacity-50"
|
|
|
- :on-click (fn []
|
|
|
- (when-let [db-name (js/prompt "Create new db")]
|
|
|
- (when-not (string/blank? db-name)
|
|
|
- (-> (repo-handler/new-db! db-name)
|
|
|
- (p/then #())))))}
|
|
|
- (ionic/tabler-icon "plus" {:size 24}))]))
|
|
|
+ {:class "relative -left-2 pt-1.5 opacity-50"
|
|
|
+ :on-click (fn []
|
|
|
+ (when-let [db-name (js/prompt "Create new db")]
|
|
|
+ (when-not (string/blank? db-name)
|
|
|
+ (-> (repo-handler/new-db! db-name)
|
|
|
+ (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?"]])))
|
|
|
+ (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")))
|
|
|
+ (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 journals-list < rum/reactive db-mixins/query
|
|
|
[]
|
|
|
@@ -93,8 +94,7 @@
|
|
|
{:on-click #(cc-utils/nav-to-block! journal {:reload-pages! (fn [] ())})}
|
|
|
(:block/title journal)]
|
|
|
;; blocks editor
|
|
|
- (cc-blocks/page-blocks journal)
|
|
|
- ]))]))
|
|
|
+ (cc-blocks/page-blocks journal)]))]))
|
|
|
|
|
|
(rum/defc contents-playground < rum/reactive db-mixins/query
|
|
|
[]
|
|
|
@@ -108,11 +108,11 @@
|
|
|
[]
|
|
|
(let [*input (rum/use-ref nil)]
|
|
|
(rum/use-effect!
|
|
|
- (fn []
|
|
|
- (let [f (fn []
|
|
|
- (js/requestAnimationFrame #(.focus (rum/deref *input))))]
|
|
|
- (set! (. js/window -keepKeyboardOpen) f)))
|
|
|
- [])
|
|
|
+ (fn []
|
|
|
+ (let [f (fn []
|
|
|
+ (js/requestAnimationFrame #(.focus (rum/deref *input))))]
|
|
|
+ (set! (. js/window -keepKeyboardOpen) f)))
|
|
|
+ [])
|
|
|
[:input.absolute.top-4.left-0.w-1.h-1.opacity-0
|
|
|
{:id "app-keep-keyboard-open-input"
|
|
|
:ref *input}]))
|
|
|
@@ -121,78 +121,81 @@
|
|
|
(let [[reload set-reload!] (rum/use-state 0)]
|
|
|
|
|
|
(ionic/ion-content
|
|
|
- (ionic/ion-refresher
|
|
|
- {:slot "fixed"
|
|
|
- :pull-factor 0.5
|
|
|
- :pull-min 100
|
|
|
- :pull-max 200
|
|
|
- :on-ion-refresh (fn [^js e]
|
|
|
- (js/setTimeout
|
|
|
- (fn [] (.complete (.-detail e))
|
|
|
- (set-reload! (inc reload)))
|
|
|
- 1000))}
|
|
|
- (ionic/ion-refresher-content))
|
|
|
-
|
|
|
- [:div.pt-4.px-4
|
|
|
- (journals-list)
|
|
|
+ (ionic/ion-refresher
|
|
|
+ {:slot "fixed"
|
|
|
+ :pull-factor 0.5
|
|
|
+ :pull-min 100
|
|
|
+ :pull-max 200
|
|
|
+ :on-ion-refresh (fn [^js e]
|
|
|
+ (js/setTimeout
|
|
|
+ (fn [] (.complete (.-detail e))
|
|
|
+ (set-reload! (inc reload)))
|
|
|
+ 1000))}
|
|
|
+ (ionic/ion-refresher-content))
|
|
|
+
|
|
|
+ [:div.pt-4.px-4
|
|
|
+ ;; (journals-list)
|
|
|
+
|
|
|
+ [:div#main-container.flex.flex-1
|
|
|
+ [:div#main-content-container.w-full
|
|
|
+ (journal/all-journals)]]
|
|
|
+
|
|
|
;(contents-playground)
|
|
|
- ]
|
|
|
+ ]
|
|
|
|
|
|
;; tabbar
|
|
|
;(app-tabbar)
|
|
|
- )
|
|
|
- ))
|
|
|
-
|
|
|
+ )))
|
|
|
(rum/defc root < rum/reactive
|
|
|
[]
|
|
|
(let [db-restoring? (fstate/sub :db/restoring?)]
|
|
|
[:<>
|
|
|
(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})])))))
|
|
|
+ {: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})])
|
|
|
+ (home)))]))
|
|
|
|
|
|
(rum/defc main []
|
|
|
(let [nav-ref (rum/use-ref nil)
|
|
|
@@ -201,39 +204,39 @@
|
|
|
|
|
|
;; global
|
|
|
(rum/use-effect!
|
|
|
- (fn []
|
|
|
- (some-> js/window.externalsjs (.settleStatusBar))
|
|
|
- (some-> js/window.externalsjs
|
|
|
- (.initGlobalListeners #js {:onKeyboardHide (fn [] (state/exit-editing!))})))
|
|
|
- [current-repo])
|
|
|
+ (fn []
|
|
|
+ (some-> js/window.externalsjs (.settleStatusBar))
|
|
|
+ (some-> js/window.externalsjs
|
|
|
+ (.initGlobalListeners #js {:onKeyboardHide (fn [] (state/exit-editing!))})))
|
|
|
+ [current-repo])
|
|
|
|
|
|
;; navigation
|
|
|
(rum/use-effect!
|
|
|
- (fn []
|
|
|
- (let [handle-back!
|
|
|
- (fn []
|
|
|
- (cond
|
|
|
- (not (nil? (state/get-editing-block)))
|
|
|
- (state/exit-editing!)
|
|
|
-
|
|
|
- (seq (ui/get-modal))
|
|
|
- nil
|
|
|
-
|
|
|
- :else
|
|
|
- (-> (cc-utils/nav-length?)
|
|
|
- (p/then (fn [len]
|
|
|
- (if (= len 1)
|
|
|
- (.exitApp App)
|
|
|
- (cc-utils/nav-pop!)))))))
|
|
|
- ^js back-listener (.addListener App "backButton" handle-back!)]
|
|
|
- #(.remove back-listener)))
|
|
|
- [])
|
|
|
+ (fn []
|
|
|
+ (let [handle-back!
|
|
|
+ (fn []
|
|
|
+ (cond
|
|
|
+ (not (nil? (state/get-editing-block)))
|
|
|
+ (state/exit-editing!)
|
|
|
+
|
|
|
+ (seq (ui/get-modal))
|
|
|
+ nil
|
|
|
+
|
|
|
+ :else
|
|
|
+ (-> (cc-utils/nav-length?)
|
|
|
+ (p/then (fn [len]
|
|
|
+ (if (= len 1)
|
|
|
+ (.exitApp App)
|
|
|
+ (cc-utils/nav-pop!)))))))
|
|
|
+ ^js back-listener (.addListener App "backButton" handle-back!)]
|
|
|
+ #(.remove back-listener)))
|
|
|
+ [])
|
|
|
|
|
|
(rum/use-effect!
|
|
|
- (fn []
|
|
|
- (set-nav-root! (rum/deref nav-ref))
|
|
|
- #())
|
|
|
- [(rum/deref nav-ref)])
|
|
|
+ (fn []
|
|
|
+ (set-nav-root! (rum/deref nav-ref))
|
|
|
+ #())
|
|
|
+ [(rum/deref nav-ref)])
|
|
|
|
|
|
[:> (.-IonApp ionic/ionic-react)
|
|
|
[:<>
|
|
|
@@ -248,5 +251,4 @@
|
|
|
|
|
|
(shui-toaster/install-toaster)
|
|
|
(shui-dialog/install-modals)
|
|
|
- (shui-popup/install-popups)
|
|
|
- ]]))
|
|
|
+ (shui-popup/install-popups)]]))
|