| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- (ns capacitor.app
- (:require ["@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.ui :as ui]
- [frontend.db.conn :as db-conn]
- [frontend.db-mixins :as db-mixins]
- [frontend.state :as fstate]
- [frontend.db.utils :as db-util]
- [frontend.date :as frontend-date]
- [frontend.handler.repo :as repo-handler]
- [frontend.mobile.util :as mobile-util]
- [goog.date :as gdate]
- [logseq.db :as ldb]
- [capacitor.components.settings :as settings]))
- (rum/defc app-graphs-select
- []
- (let [current-repo (fstate/get-current-repo)
- graphs (fstate/get-repos)
- short-repo-name (if current-repo
- (db-conn/get-short-repo-name current-repo)
- "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)
- (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}))]))
- (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 journals-list < rum/reactive db-mixins/query
- []
- (let [journals (handler/sub-journals)]
- [:ul.app-journals-list
- (for [journal-id journals]
- (let [journal (db-util/entity journal-id)]
- [:li.flex.py-1.flex-col.w-full
- [:h1.font-semibold.opacity-90.active:opacity-50
- {:on-click #(cc-utils/nav-to-block! journal {:reload-pages! (fn [] ())})}
- (:block/title journal)]
- ;; blocks editor
- (cc-blocks/page-blocks journal)
- ]))]))
- (rum/defc contents-playground < rum/reactive db-mixins/query
- []
- [:div.py-4
- [:h1.text-4xl.flex.gap-1.items-center.mb-4.pt-2.font-mono
- (ionic/tabler-icon "file" {:size 30}) "Contents"]
- (cc-blocks/page-blocks "Contents")])
- (rum/defc keep-keyboard-open
- []
- (let [*input (rum/use-ref nil)]
- (rum/use-effect!
- (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}]))
- (rum/defc home []
- (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)
- ;(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})])))))
- ;; 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)))]))
- (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)]
- ;; global
- (rum/use-effect!
- (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!)
- :else
- (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)])
- [:> (.-IonApp ionic/ionic-react)
- [:<>
- (ionic/ion-nav {:ref nav-ref
- :root root ;;settings/page
- :animated true
- :swipeGesture false})
- (keep-keyboard-open)
- (ui/install-notifications)
- (ui/install-modals)
- (shui-toaster/install-toaster)
- (shui-dialog/install-modals)
- (shui-popup/install-popups)
- ]]))
|