mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
enhance(capacitor): blocks container for journals list
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
[capacitor.state :as state]
|
||||
[capacitor.handler :as handler]
|
||||
[capacitor.pages.utils :as pages-util]
|
||||
[capacitor.pages.blocks :as blocks]
|
||||
[capacitor.components.ui :as ui]
|
||||
[frontend.db.conn :as db-conn]
|
||||
[frontend.db-mixins :as db-mixins]
|
||||
@@ -85,37 +86,15 @@
|
||||
[:ul
|
||||
(for [journal-id journals]
|
||||
(let [journal (db-util/entity journal-id)]
|
||||
[::li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
|
||||
[:li.flex.py-1.active:opacity-50.flex-col.w-full
|
||||
{:on-click #(pages-util/nav-to-block! journal {:reload-pages! (fn [] ())})}
|
||||
(ionic/tabler-icon "calendar")
|
||||
[:span.pl-1 (:block/title journal)]]))]))
|
||||
|
||||
(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}]}))
|
||||
[:h1.text-2xl.font-semibold.opacity-90 (:block/title journal)]
|
||||
;; blocks editor
|
||||
(blocks/page-blocks journal)
|
||||
]))]))
|
||||
|
||||
(rum/defc home []
|
||||
(let [[reload set-reload!] (rum/use-state 0)
|
||||
[page-input-open? set-page-input-open?] (rum/use-state false)]
|
||||
(let [[reload set-reload!] (rum/use-state 0)]
|
||||
|
||||
(ionic/ion-content
|
||||
(ionic/ion-refresher
|
||||
@@ -130,19 +109,8 @@
|
||||
1000))}
|
||||
(ionic/ion-refresher-content))
|
||||
|
||||
(when page-input-open?
|
||||
(create-page-input {:close! #(set-page-input-open? false)
|
||||
:reload-pages! #(set-reload! (inc reload))}))
|
||||
[:div.pt-6.px-6
|
||||
[:div.flex.justify-between.items-center.mt-4
|
||||
[:h1.text-3xl.font-mono.font-bold.py-2 "Journals"]
|
||||
[:flex.gap-1]]
|
||||
|
||||
[:div.pt-4.px-4
|
||||
(journals-list)
|
||||
|
||||
;(when journal-calendar-open?
|
||||
; (journals-calendar-modal {:close! #(set-journal-calendar-open? false)}))
|
||||
|
||||
]
|
||||
|
||||
;; tabbar
|
||||
@@ -231,7 +199,7 @@
|
||||
[:> (.-IonApp ionic/ionic-react)
|
||||
[:<>
|
||||
(ionic/ion-nav {:ref nav-ref
|
||||
:root root ;;settings/page
|
||||
:root root ;;settings/page
|
||||
:animated true
|
||||
:swipeGesture false})
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns capacitor.pages.blocks
|
||||
(:require [capacitor.state :as state]
|
||||
[frontend.db.model :as db-model]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[frontend.db.async :as db-async]
|
||||
@@ -79,12 +80,66 @@
|
||||
(some-> @state/*nav-root
|
||||
(.push #(edit-block-modal block opts))))
|
||||
|
||||
(rum/defc block-editor
|
||||
[])
|
||||
|
||||
(rum/defc block-content
|
||||
[])
|
||||
|
||||
(rum/defc block-item
|
||||
[block]
|
||||
(when block
|
||||
[:li.text-xl.pr-1 {:on-click #()}
|
||||
[:span (:block/title block)]]))
|
||||
|
||||
(rum/defc blocks-list
|
||||
[blocks]
|
||||
(when (seq blocks)
|
||||
[:ul.app-blocks-list
|
||||
(for [block blocks]
|
||||
(block-item block))]))
|
||||
|
||||
(rum/defc blocks-container
|
||||
[root]
|
||||
[:div.app-blocks-container
|
||||
(let [block? (not (db-model/page? root))
|
||||
children (:block/_parent root)
|
||||
blocks (if block? [root] (db-model/sort-by-order children))]
|
||||
;(js/console.log "==>> blocks:" (:block/title root) (count blocks))
|
||||
(blocks-list blocks))])
|
||||
|
||||
(rum/defc page-blocks
|
||||
[page-name-or-entity]
|
||||
(let [[page set-page!] (rum/use-state
|
||||
(if (:db/id page-name-or-entity) page-name-or-entity
|
||||
(db-model/get-page page-name-or-entity)))
|
||||
[p] (state/use-app-state [:last-modified-page-uuid (:block/uuid page)])
|
||||
[_loading? set-loading!] (rum/use-state false)]
|
||||
|
||||
(rum/use-effect!
|
||||
;; sync page blocks
|
||||
(fn []
|
||||
(-> (db-async/<get-block (fstate/get-current-repo) (:block/uuid page))
|
||||
(p/then (fn [page]
|
||||
(set-page! (db-utils/entity (:db/id page)))))
|
||||
(p/finally #()))
|
||||
#())
|
||||
[p])
|
||||
|
||||
(when page
|
||||
[:div.app-page-blocks.mb-4
|
||||
(blocks-container page)])))
|
||||
|
||||
(rum/defc page [block {:keys [reload-pages!]}]
|
||||
(let [[^js nav] (state/use-nav-root)
|
||||
[page set-page!] (rum/use-state (db-utils/entity (:db/id block)))
|
||||
title (or (:block/title block) (:block.temp/cached-title block))
|
||||
[loading? set-loading!] (rum/use-state true)
|
||||
rerender! #(set-page! (db-utils/entity (:db/id block)))]
|
||||
rerender! (fn []
|
||||
(set-page! (db-utils/entity (:db/id block)))
|
||||
(swap! state/*state assoc
|
||||
:last-modified-page-uuid
|
||||
{(:block/uuid block) (js/Date.now)}))]
|
||||
|
||||
(rum/use-effect!
|
||||
;; sync page blocks
|
||||
|
||||
@@ -1,17 +1,40 @@
|
||||
(ns capacitor.pages.settings
|
||||
(:require [capacitor.handler :as handler]
|
||||
[capacitor.pages.utils :as pages-util]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[capacitor.state :as state]
|
||||
[capacitor.ionic :as ionic]))
|
||||
|
||||
(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}]}))
|
||||
|
||||
(rum/defc all-pages
|
||||
[]
|
||||
(let [[all-pages set-all-pages!] (rum/use-state [])
|
||||
[filtered-pages set-filtered-pages!] (rum/use-state [])
|
||||
[reload set-reload!] (rum/use-state 0)
|
||||
[_page-input-open? set-page-input-open?] (rum/use-state false)
|
||||
]
|
||||
[page-input-open? set-page-input-open?] (rum/use-state false)]
|
||||
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
@@ -29,33 +52,37 @@
|
||||
#())
|
||||
[all-pages])
|
||||
|
||||
[:div.flex.flex-col
|
||||
[:div.flex.justify-between.items-center.pt-4
|
||||
[:h1.text-3xl.font-mono.font-bold.py-2
|
||||
"All pages"
|
||||
[: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})])
|
||||
;(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-reload! (inc reload))}
|
||||
; [:span {:slot "icon-only"} (ionic/tabler-icon "refresh")])
|
||||
]]
|
||||
[:<>
|
||||
(when page-input-open?
|
||||
(create-page-input {:close! #(set-page-input-open? false)
|
||||
:reload-pages! #(set-reload! (inc reload))}))
|
||||
[:div.flex.flex-col
|
||||
[:div.flex.justify-between.items-center.pt-4
|
||||
[:h1.text-3xl.font-mono.font-bold.py-2
|
||||
"All pages"
|
||||
[:small.text-xs.pl-2.opacity-50 (count filtered-pages)]]
|
||||
|
||||
[:ul.mb-24.pt-2
|
||||
(for [page filtered-pages]
|
||||
(let [ident (some-> (:block/tags page) first :db/ident)]
|
||||
[:li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
|
||||
{:on-click #(pages-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"))
|
||||
[:span.pl-1 (:block/title page)]
|
||||
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]
|
||||
[: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})])
|
||||
;(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-reload! (inc reload))}
|
||||
; [:span {:slot "icon-only"} (ionic/tabler-icon "refresh")])
|
||||
]]
|
||||
|
||||
]))
|
||||
[:ul.mb-24.pt-2
|
||||
(for [page filtered-pages]
|
||||
(let [ident (some-> (:block/tags page) first :db/ident)]
|
||||
[:li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
|
||||
{:on-click #(pages-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"))
|
||||
[:span.pl-1 (:block/title page)]
|
||||
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]
|
||||
]]))
|
||||
|
||||
(rum/defc page
|
||||
[]
|
||||
|
||||
@@ -2,5 +2,13 @@
|
||||
(:require [frontend.rum :as r]))
|
||||
|
||||
(defonce *nav-root (atom nil))
|
||||
(defonce *state
|
||||
(atom {:version 0
|
||||
:last-modified-page-uuid nil}))
|
||||
|
||||
(defn use-nav-root [] (r/use-atom *nav-root))
|
||||
(defn use-app-state
|
||||
([] (r/use-atom *state))
|
||||
([ks] (r/use-atom-in *state ks)))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user