mirror of
https://github.com/logseq/logseq.git
synced 2026-05-27 06:04:23 +00:00
chore: short names for ionic components
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
[capacitor.components.settings :as settings]
|
||||
[capacitor.components.ui :as ui]
|
||||
[capacitor.handler :as handler]
|
||||
[capacitor.ionic :as ionic]
|
||||
[capacitor.ionic :as ion]
|
||||
[capacitor.state :as state]
|
||||
[clojure.string :as string]
|
||||
[frontend.components.journal :as journal]
|
||||
@@ -35,7 +35,7 @@
|
||||
(db-conn/get-short-repo-name current-repo)
|
||||
"Select a Graph")]
|
||||
[:<>
|
||||
(ionic/ion-button
|
||||
(ion/button
|
||||
{:fill "clear"
|
||||
:mode "ios"
|
||||
:class "border-none w-full rounded-lg"
|
||||
@@ -62,18 +62,18 @@
|
||||
|
||||
(rum/defc bottom-tabs
|
||||
[]
|
||||
(ionic/ion-tab-bar
|
||||
(ion/tab-bar
|
||||
{:slot "bottom"}
|
||||
(ionic/ion-tab-button
|
||||
(ion/tab-button
|
||||
{:tab "home"
|
||||
:selected true}
|
||||
(ionic/tabler-icon "home" {:size 22}) "Journals")
|
||||
(ionic/ion-tab-button
|
||||
(ion/tabler-icon "home" {:size 22}) "Journals")
|
||||
(ion/tab-button
|
||||
{:tab "search"}
|
||||
(ionic/tabler-icon "search" {:size 22}) "Search")
|
||||
(ionic/ion-tab-button
|
||||
(ion/tabler-icon "search" {:size 22}) "Search")
|
||||
(ion/tab-button
|
||||
{:tab "settings"}
|
||||
(ionic/tabler-icon "settings" {:size 22}) "Settings")))
|
||||
(ion/tabler-icon "settings" {:size 22}) "Settings")))
|
||||
|
||||
(rum/defc journals-list < rum/reactive db-mixins/query
|
||||
[]
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
[:div.py-4
|
||||
[:h1.text-4xl.flex.gap-1.items-center.mb-4.pt-2.font-mono
|
||||
(ionic/tabler-icon "file" {:size 30}) "Contents"]
|
||||
(ion/tabler-icon "file" {:size 30}) "Contents"]
|
||||
(cc-blocks/page-blocks "Contents")])
|
||||
|
||||
(rum/defc keep-keyboard-open
|
||||
@@ -103,8 +103,8 @@
|
||||
|
||||
(rum/defc journals []
|
||||
(let [[reload set-reload!] (hooks/use-state 0)]
|
||||
(ionic/ion-content
|
||||
(ionic/ion-refresher
|
||||
(ion/content
|
||||
(ion/refresher
|
||||
{:slot "fixed"
|
||||
:pull-factor 0.5
|
||||
:pull-min 100
|
||||
@@ -114,7 +114,7 @@
|
||||
(fn [] (.complete (.-detail e))
|
||||
(set-reload! (inc reload)))
|
||||
1000))}
|
||||
(ionic/ion-refresher-content))
|
||||
(ion/refresher-content))
|
||||
|
||||
[:div.pt-4.px-4
|
||||
[:main#app-container-wrapper.ls-fold-button-on-right
|
||||
@@ -126,68 +126,68 @@
|
||||
(rum/defc home < rum/reactive
|
||||
[]
|
||||
(let [db-restoring? (fstate/sub :db/restoring?)]
|
||||
(ionic/ion-page
|
||||
(ion/page
|
||||
{:id "app-main-content"}
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ionic/ion-buttons {:slot "start"}
|
||||
(app-graphs-select))
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
(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)))))))]
|
||||
(ion/buttons {:slot "end"}
|
||||
(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!)))))
|
||||
(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 24})])
|
||||
(ui/open-modal!
|
||||
(fn [{:keys [close!]}]
|
||||
(ion/datetime
|
||||
{:presentation "date"
|
||||
:onIonChange (fn [^js e]
|
||||
(let [val (.-value (.-detail e))]
|
||||
(apply-date! val)
|
||||
(close!)))}))))))}
|
||||
[:span {:slot "icon-only"} (ion/tabler-icon "calendar-month" {:size 24})])
|
||||
|
||||
(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" {:size 24})])))))
|
||||
(ion/button {:fill "clear"}
|
||||
(ion/nav-link
|
||||
{:routerDirection "forward"
|
||||
:class "w-full"
|
||||
:component settings/page}
|
||||
[:span {:slot "icon-only"} (ion/tabler-icon "dots" {:size 24})])))))
|
||||
|
||||
;; main content
|
||||
(if db-restoring?
|
||||
(ionic/ion-content
|
||||
(ion/content
|
||||
[:strong.flex.justify-center.items-center.py-24
|
||||
(ionic/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
|
||||
(ion/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
|
||||
(journals)))))
|
||||
|
||||
(rum/defc search
|
||||
[]
|
||||
(ionic/ion-page
|
||||
(ion/page
|
||||
{:id "search-tab"}
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
"Search"))
|
||||
[:div.flex.flex-1.p-4 "Search results"]))
|
||||
|
||||
(rum/defc settings
|
||||
[]
|
||||
(ionic/ion-page
|
||||
(ion/page
|
||||
{:id "settings-tab"}
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
"Settings"))
|
||||
[:div.flex.flex-1.p-4 "TODO..."]))
|
||||
|
||||
@@ -201,20 +201,20 @@
|
||||
(set-nav-root! nav))
|
||||
#())
|
||||
[(rum/deref nav-ref)])
|
||||
(ionic/ion-tabs
|
||||
(ionic/ion-tab
|
||||
(ion/tabs
|
||||
(ion/tab
|
||||
{:tab "home"}
|
||||
(ionic/ion-nav {:ref nav-ref
|
||||
:root home ;;settings/page
|
||||
:animated true
|
||||
:swipeGesture true}))
|
||||
(ionic/ion-tab
|
||||
(ion/nav {:ref nav-ref
|
||||
:root home ;;settings/page
|
||||
:animated true
|
||||
:swipeGesture true}))
|
||||
(ion/tab
|
||||
{:tab "search"}
|
||||
(ionic/ion-content
|
||||
(ion/content
|
||||
(search)))
|
||||
(ionic/ion-tab
|
||||
(ion/tab
|
||||
{:tab "settings"}
|
||||
(ionic/ion-content
|
||||
(ion/content
|
||||
(settings)))
|
||||
(bottom-tabs)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns capacitor.components.blocks
|
||||
(:require [capacitor.components.common :as cc-common]
|
||||
[capacitor.components.editor :as cc-editor]
|
||||
[capacitor.ionic :as ionic]
|
||||
[capacitor.ionic :as ion]
|
||||
[capacitor.state :as state]
|
||||
[clojure.string :as string]
|
||||
[dommy.core :as dom]
|
||||
@@ -38,50 +38,50 @@
|
||||
#())
|
||||
[])
|
||||
|
||||
(ionic/ion-page
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ionic/ion-buttons {:slot "end"}
|
||||
(when (not (nil? (:db/id block)))
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:class "opacity-80 text-red-500"
|
||||
:on-click (fn []
|
||||
(-> (editor-handler/delete-block-aux! block)
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!)))))}
|
||||
(ionic/tabler-icon "trash" {:size 26}))))
|
||||
(ionic/ion-title (or title "Untitled"))))
|
||||
(ion/page
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
(ion/buttons {:slot "end"}
|
||||
(when (not (nil? (:db/id block)))
|
||||
(ion/button {:fill "clear"
|
||||
:class "opacity-80 text-red-500"
|
||||
:on-click (fn []
|
||||
(-> (editor-handler/delete-block-aux! block)
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!)))))}
|
||||
(ion/tabler-icon "trash" {:size 26}))))
|
||||
(ion/title (or title "Untitled"))))
|
||||
|
||||
(ionic/ion-content {:class "ion-padding"}
|
||||
[:div.py-2
|
||||
(ionic/ion-textarea {:placeholder "block content"
|
||||
:ref *input
|
||||
:class "bg-gray-100"
|
||||
:auto-grow true
|
||||
:autofocus true
|
||||
:value (:block/title block)})]
|
||||
[:div.flex.py-2.justify-between
|
||||
(ionic/ion-button
|
||||
{:on-click #(close!)
|
||||
:fill "clear"}
|
||||
"Cancel")
|
||||
(ionic/ion-button
|
||||
{:on-click (fn []
|
||||
(let [new? (nil? (:db/id block))
|
||||
val (.-value (.querySelector (rum/deref *input) "textarea"))]
|
||||
(if-let [page (and new? (:block/page block))]
|
||||
(-> (editor-handler/api-insert-new-block! val {:page (:db/id page)
|
||||
:sibling? true})
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!))))
|
||||
(-> (editor-handler/save-block! (fstate/get-current-repo)
|
||||
(:block/uuid block) val)
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!)))))))
|
||||
:class ""} "Save")]))))
|
||||
(ion/content {:class "ion-padding"}
|
||||
[:div.py-2
|
||||
(ion/textarea {:placeholder "block content"
|
||||
:ref *input
|
||||
:class "bg-gray-100"
|
||||
:auto-grow true
|
||||
:autofocus true
|
||||
:value (:block/title block)})]
|
||||
[:div.flex.py-2.justify-between
|
||||
(ion/button
|
||||
{:on-click #(close!)
|
||||
:fill "clear"}
|
||||
"Cancel")
|
||||
(ion/button
|
||||
{:on-click (fn []
|
||||
(let [new? (nil? (:db/id block))
|
||||
val (.-value (.querySelector (rum/deref *input) "textarea"))]
|
||||
(if-let [page (and new? (:block/page block))]
|
||||
(-> (editor-handler/api-insert-new-block! val {:page (:db/id page)
|
||||
:sibling? true})
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!))))
|
||||
(-> (editor-handler/save-block! (fstate/get-current-repo)
|
||||
(:block/uuid block) val)
|
||||
(p/then (fn []
|
||||
(close!)
|
||||
(reload-page!)))))))
|
||||
:class ""} "Save")]))))
|
||||
|
||||
;; handlers
|
||||
(defn insert-new-block!
|
||||
@@ -310,34 +310,34 @@
|
||||
#())
|
||||
[])
|
||||
|
||||
(ionic/ion-page
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ionic/ion-buttons {:slot "start"}
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ionic/tabler-icon "arrow-left" {:size 26})))
|
||||
(ion/page
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
(ion/buttons {:slot "start"}
|
||||
(ion/button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ion/tabler-icon "arrow-left" {:size 26})))
|
||||
|
||||
(ionic/ion-buttons {:slot "end"}
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:class "opacity-80"
|
||||
:on-click rerender!}
|
||||
(ionic/tabler-icon "refresh" {:size 26}))
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:class "opacity-80 text-red-500"
|
||||
:on-click (fn []
|
||||
(page-handler/<delete! (:block/uuid block)
|
||||
(fn []
|
||||
(.pop nav)
|
||||
(when (fn? reload-pages!)
|
||||
(reload-pages!)))
|
||||
{:error-handler (fn [^js e]
|
||||
(js/console.error e))}))}
|
||||
(ionic/tabler-icon "trash" {:size 26})))
|
||||
(ion/buttons {:slot "end"}
|
||||
(ion/button {:fill "clear"
|
||||
:class "opacity-80"
|
||||
:on-click rerender!}
|
||||
(ion/tabler-icon "refresh" {:size 26}))
|
||||
(ion/button {:fill "clear"
|
||||
:class "opacity-80 text-red-500"
|
||||
:on-click (fn []
|
||||
(page-handler/<delete! (:block/uuid block)
|
||||
(fn []
|
||||
(.pop nav)
|
||||
(when (fn? reload-pages!)
|
||||
(reload-pages!)))
|
||||
{:error-handler (fn [^js e]
|
||||
(js/console.error e))}))}
|
||||
(ion/tabler-icon "trash" {:size 26})))
|
||||
|
||||
(ionic/ion-title title)))
|
||||
(ion/title title)))
|
||||
|
||||
(ionic/ion-content {:class "ion-padding"}
|
||||
(if loading?
|
||||
[:p.text-xl.text-center "Loading ..."]
|
||||
(page-blocks-classic page))))))
|
||||
(ion/content {:class "ion-padding"}
|
||||
(if loading?
|
||||
[:p.text-xl.text-center "Loading ..."]
|
||||
(page-blocks-classic page))))))
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
(ns capacitor.components.editor
|
||||
(:require [rum.core :as rum]
|
||||
[capacitor.components.ui :as ui]
|
||||
(:require [capacitor.components.ui :as ui]
|
||||
[capacitor.ionic :as ion]
|
||||
[cljs-bean.core :as bean]
|
||||
[capacitor.ionic :as ionic]
|
||||
[frontend.util.cursor :as cursor]
|
||||
[frontend.util :as util]
|
||||
[frontend.handler.notification :as notification]))
|
||||
[frontend.util.cursor :as cursor]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(rum/defc editor-aux
|
||||
[content {:keys [on-outside! on-save! on-delete! on-focused! on-keydown! on-keyup! on-bounded!]}]
|
||||
@@ -13,26 +12,26 @@
|
||||
(let [*input (rum/use-ref nil)]
|
||||
|
||||
(rum/use-layout-effect!
|
||||
(fn []
|
||||
(js/requestAnimationFrame
|
||||
(fn []
|
||||
(when-let [^js input (some-> (rum/deref *input))]
|
||||
(.focus input)
|
||||
(when on-focused!
|
||||
(on-focused! input))
|
||||
(fn []
|
||||
(js/requestAnimationFrame
|
||||
(fn []
|
||||
(when-let [^js input (some-> (rum/deref *input))]
|
||||
(.focus input)
|
||||
(when on-focused!
|
||||
(on-focused! input))
|
||||
;(.scrollIntoView input #js {:behavior "smooth", :block "start"})
|
||||
)))
|
||||
#())
|
||||
[])
|
||||
)))
|
||||
#())
|
||||
[])
|
||||
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
(let [handle-outside! (fn [^js e]
|
||||
(when-not (some-> e (.-target) (.closest ".editor-aux-input"))
|
||||
(on-outside! e)))]
|
||||
(js/window.addEventListener "pointerdown" handle-outside!)
|
||||
#(js/window.removeEventListener "pointerdown" handle-outside!)))
|
||||
[])
|
||||
(fn []
|
||||
(let [handle-outside! (fn [^js e]
|
||||
(when-not (some-> e (.-target) (.closest ".editor-aux-input"))
|
||||
(on-outside! e)))]
|
||||
(js/window.addEventListener "pointerdown" handle-outside!)
|
||||
#(js/window.removeEventListener "pointerdown" handle-outside!)))
|
||||
[])
|
||||
|
||||
(let [save-handle!
|
||||
(fn [opts]
|
||||
@@ -47,44 +46,43 @@
|
||||
(on-delete! content opts))))
|
||||
debounce-save-handle! (util/debounce save-handle! 128)]
|
||||
(ui/textarea
|
||||
{:class "editor-aux-input bg-gray-200 border-none resize-none"
|
||||
:ref *input
|
||||
:on-change (fn [] (debounce-save-handle!))
|
||||
:on-key-down (fn [^js e]
|
||||
(let [ekey (.-key e)
|
||||
target (.-target e)
|
||||
enter? (= ekey "Enter")
|
||||
esc? (= ekey "Escape")
|
||||
backspace? (= ekey "Backspace")
|
||||
arrow-up? (= ekey "ArrowUp")
|
||||
arrow-down? (= ekey "ArrowDown")]
|
||||
{:class "editor-aux-input bg-gray-200 border-none resize-none"
|
||||
:ref *input
|
||||
:on-change (fn [] (debounce-save-handle!))
|
||||
:on-key-down (fn [^js e]
|
||||
(let [ekey (.-key e)
|
||||
target (.-target e)
|
||||
enter? (= ekey "Enter")
|
||||
esc? (= ekey "Escape")
|
||||
backspace? (= ekey "Backspace")
|
||||
arrow-up? (= ekey "ArrowUp")
|
||||
arrow-down? (= ekey "ArrowDown")]
|
||||
|
||||
(when (or (nil? on-keydown!)
|
||||
(not (false? (on-keydown! e))))
|
||||
(cond
|
||||
(or arrow-up? arrow-down?)
|
||||
(when-let [{:keys [isFirstLine isLastLine]} (some-> (.checkCursorLine js/window.externalsjs target) (bean/->clj))]
|
||||
(when (and on-bounded! (or (and arrow-up? isFirstLine)
|
||||
(and arrow-down? isLastLine)))
|
||||
(on-bounded! (if arrow-up? :up :down) target)
|
||||
(util/stop e)))
|
||||
(when (or (nil? on-keydown!)
|
||||
(not (false? (on-keydown! e))))
|
||||
(cond
|
||||
(or arrow-up? arrow-down?)
|
||||
(when-let [{:keys [isFirstLine isLastLine]} (some-> (.checkCursorLine js/window.externalsjs target) (bean/->clj))]
|
||||
(when (and on-bounded! (or (and arrow-up? isFirstLine)
|
||||
(and arrow-down? isLastLine)))
|
||||
(on-bounded! (if arrow-up? :up :down) target)
|
||||
(util/stop e)))
|
||||
|
||||
(or (and enter? (cursor/end? target)) esc?)
|
||||
(do (save-handle! {:enter? enter? :esc? esc?})
|
||||
(util/stop e))
|
||||
(or (and enter? (cursor/end? target)) esc?)
|
||||
(do (save-handle! {:enter? enter? :esc? esc?})
|
||||
(util/stop e))
|
||||
|
||||
(and backspace?
|
||||
(cursor/start? target)
|
||||
(not (util/input-text-selected? target)))
|
||||
(do (delete-handle! {})
|
||||
(util/stop e))
|
||||
))))
|
||||
:on-key-up (fn [^js e]
|
||||
(when on-keyup!
|
||||
(on-keyup! e)))
|
||||
:default-value content}))))
|
||||
(and backspace?
|
||||
(cursor/start? target)
|
||||
(not (util/input-text-selected? target)))
|
||||
(do (delete-handle! {})
|
||||
(util/stop e))))))
|
||||
:on-key-up (fn [^js e]
|
||||
(when on-keyup!
|
||||
(on-keyup! e)))
|
||||
:default-value content}))))
|
||||
|
||||
(rum/defc content-aux
|
||||
[content & opts]
|
||||
|
||||
[:div.content-aux-container content])
|
||||
[:div.content-aux-container content])
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
(ns capacitor.components.settings
|
||||
(:require [capacitor.handler :as handler]
|
||||
[capacitor.components.nav-utils :as cc-util]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
(:require [capacitor.components.nav-utils :as cc-util]
|
||||
[capacitor.handler :as handler]
|
||||
[capacitor.ionic :as ion]
|
||||
[capacitor.state :as state]
|
||||
[capacitor.ionic :as ionic]))
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(rum/defc create-page-input
|
||||
[{:keys [close! reload-pages!]}]
|
||||
(ionic/ion-alert
|
||||
{:is-open true
|
||||
:header "Create new page"
|
||||
:onWillDismiss (fn [^js e]
|
||||
(let [^js detail (.-detail e)]
|
||||
(when-let [val (and (= "confirm" (.-role detail))
|
||||
(aget (.-values (.-data detail)) 0))]
|
||||
(-> (handler/<create-page! val)
|
||||
(p/finally reload-pages!)))
|
||||
(close!)))
|
||||
:onDidPresent (fn [^js e]
|
||||
(let [^js target (.-target e)]
|
||||
(when-let [input (.querySelector target "input")]
|
||||
(js/setTimeout #(.focus input)))))
|
||||
:buttons [#js {:text "Cancel"
|
||||
:role "cancel"}
|
||||
#js {:text "Confirm"
|
||||
:role "confirm"}]
|
||||
:inputs [#js {:placeholder "page name"
|
||||
:auto-focus true}]}))
|
||||
(ion/alert
|
||||
{:is-open true
|
||||
:header "Create new page"
|
||||
:onWillDismiss (fn [^js e]
|
||||
(let [^js detail (.-detail e)]
|
||||
(when-let [val (and (= "confirm" (.-role detail))
|
||||
(aget (.-values (.-data detail)) 0))]
|
||||
(-> (handler/<create-page! val)
|
||||
(p/finally reload-pages!)))
|
||||
(close!)))
|
||||
:onDidPresent (fn [^js e]
|
||||
(let [^js target (.-target e)]
|
||||
(when-let [input (.querySelector target "input")]
|
||||
(js/setTimeout #(.focus input)))))
|
||||
:buttons [#js {:text "Cancel"
|
||||
:role "cancel"}
|
||||
#js {:text "Confirm"
|
||||
:role "confirm"}]
|
||||
:inputs [#js {:placeholder "page name"
|
||||
:auto-focus true}]}))
|
||||
|
||||
(rum/defc all-pages
|
||||
[]
|
||||
@@ -37,21 +37,20 @@
|
||||
[page-input-open? set-page-input-open?] (rum/use-state false)]
|
||||
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
(set-all-pages! (handler/local-all-pages))
|
||||
#())
|
||||
[reload])
|
||||
(fn []
|
||||
(set-all-pages! (handler/local-all-pages))
|
||||
#())
|
||||
[reload])
|
||||
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
(let [pages (filterv (fn [page]
|
||||
(let [ident (some-> (:block/tags page) first :db/ident)]
|
||||
(not (contains? #{:logseq.class/Journal :logseq.class/Property} ident))))
|
||||
all-pages)]
|
||||
(set-filtered-pages! pages))
|
||||
#())
|
||||
[all-pages])
|
||||
|
||||
(fn []
|
||||
(let [pages (filterv (fn [page]
|
||||
(let [ident (some-> (:block/tags page) first :db/ident)]
|
||||
(not (contains? #{:logseq.class/Journal :logseq.class/Property} ident))))
|
||||
all-pages)]
|
||||
(set-filtered-pages! pages))
|
||||
#())
|
||||
[all-pages])
|
||||
|
||||
[:<>
|
||||
(when page-input-open?
|
||||
@@ -64,8 +63,8 @@
|
||||
[:small.text-xs.pl-2.opacity-50 (count filtered-pages)]]
|
||||
|
||||
[:div.flex.gap-1
|
||||
(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-page-input-open? true)}
|
||||
[:span {:slot "icon-only"} (ionic/tabler-icon "file-plus" {:size 22})])
|
||||
(ion/button {:size "small" :fill "clear" :on-click #(set-page-input-open? true)}
|
||||
[:span {:slot "icon-only"} (ion/tabler-icon "file-plus" {:size 22})])
|
||||
;(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-reload! (inc reload))}
|
||||
; [:span {:slot "icon-only"} (ionic/tabler-icon "refresh")])
|
||||
]]
|
||||
@@ -76,43 +75,41 @@
|
||||
[:li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
|
||||
{:on-click #(cc-util/nav-to-block! page {:reload-pages! (fn [] (set-reload! (inc reload)))})}
|
||||
(case ident
|
||||
:logseq.class/Property (ionic/tabler-icon "letter-t")
|
||||
:logseq.class/Page (ionic/tabler-icon "file")
|
||||
:logseq.class/Journal (ionic/tabler-icon "calendar")
|
||||
(ionic/tabler-icon "hash"))
|
||||
:logseq.class/Property (ion/tabler-icon "letter-t")
|
||||
:logseq.class/Page (ion/tabler-icon "file")
|
||||
:logseq.class/Journal (ion/tabler-icon "calendar")
|
||||
(ion/tabler-icon "hash"))
|
||||
[:span.pl-1 (:block/title page)]
|
||||
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]
|
||||
]]))
|
||||
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]]]))
|
||||
|
||||
(rum/defc page
|
||||
[]
|
||||
(let [[^js nav] (state/use-nav-root)]
|
||||
(ionic/ion-page
|
||||
(ionic/ion-header
|
||||
(ionic/ion-toolbar
|
||||
(ionic/ion-buttons {:slot "start"}
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ionic/tabler-icon "arrow-left" {:size 26})))
|
||||
(ion/page
|
||||
(ion/header
|
||||
(ion/toolbar
|
||||
(ion/buttons {:slot "start"}
|
||||
(ion/button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ion/tabler-icon "arrow-left" {:size 26})))
|
||||
|
||||
(ionic/ion-buttons {:slot "end"}
|
||||
(ionic/ion-button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ionic/tabler-icon "share" {:size 26})))
|
||||
(ion/buttons {:slot "end"}
|
||||
(ion/button {:fill "clear"
|
||||
:on-click #(.pop nav)}
|
||||
(ion/tabler-icon "share" {:size 26})))
|
||||
|
||||
(ionic/ion-title "Settings")))
|
||||
(ion/title "Settings")))
|
||||
|
||||
(ionic/ion-content {:class "ion-padding"}
|
||||
(ionic/ion-refresher
|
||||
{:slot "fixed"
|
||||
:pull-factor 0.5
|
||||
:pull-min 100
|
||||
:pull-max 200
|
||||
:on-ion-refresh (fn [^js e]
|
||||
(js/setTimeout
|
||||
#(.complete (.-detail e))
|
||||
3000))}
|
||||
(ionic/ion-refresher-content))
|
||||
(ion/content {:class "ion-padding"}
|
||||
(ion/refresher
|
||||
{:slot "fixed"
|
||||
:pull-factor 0.5
|
||||
:pull-min 100
|
||||
:pull-max 200
|
||||
:on-ion-refresh (fn [^js e]
|
||||
(js/setTimeout
|
||||
#(.complete (.-detail e))
|
||||
3000))}
|
||||
(ion/refresher-content))
|
||||
|
||||
(all-pages)
|
||||
))))
|
||||
(all-pages)))))
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
(ns capacitor.components.ui
|
||||
(:require [cljs-bean.core :as bean]
|
||||
(:require [capacitor.ionic :as ion]
|
||||
[cljs-bean.core :as bean]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.rum :as r]
|
||||
[frontend.state :as fstate]
|
||||
[medley.core :as medley]
|
||||
[react-transition-group :refer [CSSTransition TransitionGroup]]
|
||||
[react-textarea-autosize :as TextareaAutosize]
|
||||
[goog.object :as gobj]
|
||||
[rum.core :as rum]
|
||||
[capacitor.ionic :as ionic]))
|
||||
[medley.core :as medley]
|
||||
[react-textarea-autosize :as TextareaAutosize]
|
||||
[react-transition-group :refer [CSSTransition TransitionGroup]]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(defonce transition-group (r/adapt-class TransitionGroup))
|
||||
(defonce css-transition (r/adapt-class CSSTransition))
|
||||
@@ -16,21 +16,21 @@
|
||||
|
||||
(rum/defc safe-page-container
|
||||
[content {:keys [header-content page-props content-props]}]
|
||||
(ionic/ion-page
|
||||
(merge {:class "app-safe-page"} page-props)
|
||||
(some-> header-content (ionic/ion-header))
|
||||
(ionic/ion-content
|
||||
(merge {:class "ion-padding"} content-props)
|
||||
content)))
|
||||
(ion/page
|
||||
(merge {:class "app-safe-page"} page-props)
|
||||
(some-> header-content (ion/header))
|
||||
(ion/content
|
||||
(merge {:class "ion-padding"} content-props)
|
||||
content)))
|
||||
|
||||
(rum/defc notification-clear-all
|
||||
[]
|
||||
[:div.ui__notifications-content
|
||||
[:div.pointer-events-auto.notification-clear
|
||||
(ionic/ion-button
|
||||
{:on-click (fn []
|
||||
(notification/clear-all!))}
|
||||
"clear all")]])
|
||||
(ion/button
|
||||
{:on-click (fn []
|
||||
(notification/clear-all!))}
|
||||
"clear all")]])
|
||||
|
||||
(rum/defc notification-content
|
||||
[state content status uid]
|
||||
@@ -39,20 +39,20 @@
|
||||
(if (keyword? status)
|
||||
(case status
|
||||
:success
|
||||
(ionic/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
|
||||
(ion/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
|
||||
|
||||
:warning
|
||||
(ionic/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
|
||||
(ion/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
|
||||
|
||||
:error
|
||||
(ionic/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
|
||||
(ion/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
|
||||
|
||||
(ionic/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
|
||||
(ion/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
|
||||
status)]
|
||||
[:div.ui__notifications-content
|
||||
{:style
|
||||
(when (or (= state "exiting")
|
||||
(= state "exited"))
|
||||
(= state "exited"))
|
||||
{:z-index -1})}
|
||||
[:div.max-w-sm.w-full.shadow-lg.rounded-lg.pointer-events-auto.notification-area
|
||||
{:class (case state
|
||||
@@ -73,38 +73,38 @@
|
||||
content]]
|
||||
[:div.flex-shrink-0.flex {:style {:margin-top -9
|
||||
:margin-right -18}}
|
||||
(ionic/ion-button
|
||||
{:fill "clear"
|
||||
:mode "ios"
|
||||
:shape "round"
|
||||
:on-click (fn []
|
||||
(notification/clear! uid))}
|
||||
[:span {:slot "icon-only"}
|
||||
(ionic/tabler-icon "x")])]]]]]])))
|
||||
(ion/button
|
||||
{:fill "clear"
|
||||
:mode "ios"
|
||||
:shape "round"
|
||||
:on-click (fn []
|
||||
(notification/clear! uid))}
|
||||
[:span {:slot "icon-only"}
|
||||
(ion/tabler-icon "x")])]]]]]])))
|
||||
|
||||
(rum/defc install-notifications < rum/reactive
|
||||
[]
|
||||
(let [contents (fstate/sub :notification/contents)]
|
||||
(transition-group
|
||||
{:class-name "notifications ui__notifications"}
|
||||
(let [notifications
|
||||
(map (fn [el]
|
||||
(let [k (first el)
|
||||
v (second el)]
|
||||
(css-transition
|
||||
{:timeout 100
|
||||
:key (name k)}
|
||||
(fn [state]
|
||||
(notification-content state (:content v) (:status v) k)))))
|
||||
contents)
|
||||
clear-all (when (> (count contents) 3)
|
||||
(css-transition
|
||||
{:timeout 100
|
||||
:k "clear-all"}
|
||||
(fn [_state]
|
||||
(notification-clear-all))))
|
||||
items (if clear-all (cons clear-all notifications) notifications)]
|
||||
(doall items)))))
|
||||
{:class-name "notifications ui__notifications"}
|
||||
(let [notifications
|
||||
(map (fn [el]
|
||||
(let [k (first el)
|
||||
v (second el)]
|
||||
(css-transition
|
||||
{:timeout 100
|
||||
:key (name k)}
|
||||
(fn [state]
|
||||
(notification-content state (:content v) (:status v) k)))))
|
||||
contents)
|
||||
clear-all (when (> (count contents) 3)
|
||||
(css-transition
|
||||
{:timeout 100
|
||||
:k "clear-all"}
|
||||
(fn [_state]
|
||||
(notification-clear-all))))
|
||||
items (if clear-all (cons clear-all notifications) notifications)]
|
||||
(doall items)))))
|
||||
|
||||
(defonce *modals (atom []))
|
||||
(defonce ^:private *id (atom 0))
|
||||
@@ -115,45 +115,45 @@
|
||||
(let [{:keys [class header]} modal-props]
|
||||
(case type
|
||||
:alert
|
||||
(ionic/ion-alert
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:header (or title header)
|
||||
:message content
|
||||
:backdropDismiss false
|
||||
:onWillDismiss (fn [^js e]
|
||||
(when on-action
|
||||
(on-action (bean/->clj (.-detail e))))
|
||||
(close!))
|
||||
:buttons (bean/->js (or buttons (:buttons modal-props)))
|
||||
:inputs (bean/->js (or inputs (:inputs modal-props) []))}))
|
||||
(ion/alert
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:header (or title header)
|
||||
:message content
|
||||
:backdropDismiss false
|
||||
:onWillDismiss (fn [^js e]
|
||||
(when on-action
|
||||
(on-action (bean/->clj (.-detail e))))
|
||||
(close!))
|
||||
:buttons (bean/->js (or buttons (:buttons modal-props)))
|
||||
:inputs (bean/->js (or inputs (:inputs modal-props) []))}))
|
||||
|
||||
:action-sheet
|
||||
(ionic/ion-action-sheet
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:header (or content title header)
|
||||
:onWillDismiss (fn [^js e]
|
||||
(when on-action
|
||||
(on-action (bean/->clj (.-detail e))))
|
||||
(close!))
|
||||
:buttons (bean/->js (or buttons (:buttons modal-props)))}))
|
||||
(ion/action-sheet
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:header (or content title header)
|
||||
:onWillDismiss (fn [^js e]
|
||||
(when on-action
|
||||
(on-action (bean/->clj (.-detail e))))
|
||||
(close!))
|
||||
:buttons (bean/->js (or buttons (:buttons modal-props)))}))
|
||||
|
||||
;; default
|
||||
(ionic/ion-modal
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:onWillDismiss (fn [] (close!))
|
||||
:class (str class (when (not (true? as-page?)) " ion-datetime-button-overlay"))})
|
||||
(if (fn? content)
|
||||
(content) content)))))
|
||||
(ion/modal
|
||||
(merge modal-props
|
||||
{:is-open true
|
||||
:onWillDismiss (fn [] (close!))
|
||||
:class (str class (when (not (true? as-page?)) " ion-datetime-button-overlay"))})
|
||||
(if (fn? content)
|
||||
(content) content)))))
|
||||
|
||||
(defn get-modal
|
||||
([] (some-> @*modals last))
|
||||
([id]
|
||||
(when id
|
||||
(some->> (medley/indexed @*modals)
|
||||
(filter #(= id (:id (second %)))) (first)))))
|
||||
(filter #(= id (:id (second %)))) (first)))))
|
||||
|
||||
(defn- upsert-modal!
|
||||
[config]
|
||||
@@ -170,11 +170,11 @@
|
||||
(defn open-modal!
|
||||
[content & {:keys [id type] :as props}]
|
||||
(upsert-modal!
|
||||
(merge props
|
||||
{:id (or id (gen-id))
|
||||
:type (or type :default) ;; :alert :confirm :page
|
||||
:as-page? (= type :page)
|
||||
:content content})))
|
||||
(merge props
|
||||
{:id (or id (gen-id))
|
||||
:type (or type :default) ;; :alert :confirm :page
|
||||
:as-page? (= type :page)
|
||||
:content content})))
|
||||
|
||||
(defn close-modal!
|
||||
([] (some-> @*modals (last) :id (close-modal!)))
|
||||
@@ -187,4 +187,4 @@
|
||||
:let [close! #(close-modal! id)
|
||||
props' (assoc props :close! close!)]]
|
||||
(x-modal props'
|
||||
(if (fn? content) (content props') content)))]))
|
||||
(if (fn? content) (content props') content)))]))
|
||||
|
||||
@@ -6,40 +6,40 @@
|
||||
|
||||
;(def define-custom-component ionicLoader/defineCustomElements)
|
||||
(def ^js ionic-react ionicReact)
|
||||
(def ^js ionic-camera (.-Camera ionicCamera))
|
||||
(def ^js ionic-camera-result-type (.-CameraResultType ionicCamera))
|
||||
(def ^js camera (.-Camera ionicCamera))
|
||||
(def ^js camera-result-type (.-CameraResultType ionicCamera))
|
||||
|
||||
(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))
|
||||
(defonce ion-content (shui-util/react->rum (.-IonContent ionic-react) true))
|
||||
(defonce ion-header (shui-util/react->rum (.-IonHeader ionic-react) true))
|
||||
(defonce ion-back-button (shui-util/react->rum (.-IonBackButton ionic-react) false))
|
||||
(defonce ion-buttons (shui-util/react->rum (.-IonButtons ionic-react) true))
|
||||
(defonce ion-toolbar (shui-util/react->rum (.-IonToolbar ionic-react) true))
|
||||
(defonce ion-loading (shui-util/react->rum (.-IonLoading ionic-react) true))
|
||||
(defonce ion-title (shui-util/react->rum (.-IonTitle ionic-react) true))
|
||||
(defonce ion-button (shui-util/react->rum (.-IonButton ionic-react) true))
|
||||
(defonce ion-alert (shui-util/react->rum (.-IonAlert ionic-react) true))
|
||||
(defonce ion-input (shui-util/react->rum (.-IonInput ionic-react) true))
|
||||
(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) 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))
|
||||
(defonce ion-label (shui-util/react->rum (.-IonLabel ionic-react) false))
|
||||
(defonce ion-list (shui-util/react->rum (.-IonList ionic-react) false))
|
||||
(defonce ion-item (shui-util/react->rum (.-IonItem ionic-react) false))
|
||||
(defonce ion-datetime (shui-util/react->rum (.-IonDatetime ionic-react) false))
|
||||
(defonce ion-datetime-button (shui-util/react->rum (.-IonDatetimeButton ionic-react) false))
|
||||
(defonce ion-refresher (shui-util/react->rum (.-IonRefresher ionic-react) false))
|
||||
(defonce ion-refresher-content (shui-util/react->rum (.-IonRefresherContent ionic-react) false))
|
||||
(defonce ion-menu (shui-util/react->rum (.-IonMenu ionic-react) false))
|
||||
(defonce ion-menu-button (shui-util/react->rum (.-IonMenuButton ionic-react) false))
|
||||
(defonce ion-action-sheet (shui-util/react->rum (.-IonActionSheet ionic-react) false))
|
||||
(defonce app (shui-util/react->rum (.-IonApp ionic-react) true))
|
||||
(defonce page (shui-util/react->rum (.-IonPage ionic-react) true))
|
||||
(defonce nav (shui-util/react->rum (.-IonNav ionic-react) true))
|
||||
(defonce nav-link (shui-util/react->rum (.-IonNavLink ionic-react) true))
|
||||
(defonce content (shui-util/react->rum (.-IonContent ionic-react) true))
|
||||
(defonce header (shui-util/react->rum (.-IonHeader ionic-react) true))
|
||||
(defonce back-button (shui-util/react->rum (.-IonBackButton ionic-react) false))
|
||||
(defonce buttons (shui-util/react->rum (.-IonButtons ionic-react) true))
|
||||
(defonce toolbar (shui-util/react->rum (.-IonToolbar ionic-react) true))
|
||||
(defonce loading (shui-util/react->rum (.-IonLoading ionic-react) true))
|
||||
(defonce title (shui-util/react->rum (.-IonTitle ionic-react) true))
|
||||
(defonce button (shui-util/react->rum (.-IonButton ionic-react) true))
|
||||
(defonce alert (shui-util/react->rum (.-IonAlert ionic-react) true))
|
||||
(defonce input (shui-util/react->rum (.-IonInput ionic-react) true))
|
||||
(defonce textarea (shui-util/react->rum (.-IonTextarea ionic-react) true))
|
||||
(defonce icon (shui-util/react->rum (.-IonIcon ionic-react) true))
|
||||
(defonce badge (shui-util/react->rum (.-IonBadge ionic-react) true))
|
||||
(defonce tabs (shui-util/react->rum (.-IonTabs ionic-react) false))
|
||||
(defonce tab (shui-util/react->rum (.-IonTab ionic-react) false))
|
||||
(defonce tab-bar (shui-util/react->rum (.-IonTabBar ionic-react) false))
|
||||
(defonce tab-button (shui-util/react->rum (.-IonTabButton ionic-react) false))
|
||||
(defonce modal (shui-util/react->rum (.-IonModal ionic-react) false))
|
||||
(defonce label (shui-util/react->rum (.-IonLabel ionic-react) false))
|
||||
(defonce list (shui-util/react->rum (.-IonList ionic-react) false))
|
||||
(defonce item (shui-util/react->rum (.-IonItem ionic-react) false))
|
||||
(defonce datetime (shui-util/react->rum (.-IonDatetime ionic-react) false))
|
||||
(defonce datetime-button (shui-util/react->rum (.-IonDatetimeButton ionic-react) false))
|
||||
(defonce refresher (shui-util/react->rum (.-IonRefresher ionic-react) false))
|
||||
(defonce refresher-content (shui-util/react->rum (.-IonRefresherContent ionic-react) false))
|
||||
(defonce menu (shui-util/react->rum (.-IonMenu ionic-react) false))
|
||||
(defonce menu-button (shui-util/react->rum (.-IonMenuButton ionic-react) false))
|
||||
(defonce action-sheet (shui-util/react->rum (.-IonActionSheet ionic-react) false))
|
||||
|
||||
Reference in New Issue
Block a user