mirror of
https://github.com/logseq/logseq.git
synced 2026-02-01 22:47:36 +00:00
enhance(capacitor): WIP blocks content and editor
This commit is contained in:
@@ -55,6 +55,7 @@ class UILocal : Plugin() {
|
||||
val selectedDate = Calendar.getInstance().apply {
|
||||
set(selectedYear, selectedMonth, selectedDay)
|
||||
}
|
||||
|
||||
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
val formattedDate = sdf.format(selectedDate.time)
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
[capacitor.ionic :as ionic]
|
||||
[capacitor.state :as state]
|
||||
[capacitor.handler :as handler]
|
||||
[capacitor.pages.utils :as pages-util]
|
||||
[capacitor.pages.blocks :as blocks]
|
||||
[capacitor.components.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]
|
||||
@@ -23,7 +23,7 @@
|
||||
[frontend.mobile.util :as mobile-util]
|
||||
[goog.date :as gdate]
|
||||
[logseq.db :as ldb]
|
||||
[capacitor.pages.settings :as settings]))
|
||||
[capacitor.components.settings :as settings]))
|
||||
|
||||
(rum/defc app-graphs-select
|
||||
[]
|
||||
@@ -87,11 +87,12 @@
|
||||
[:ul.app-journals-list
|
||||
(for [journal-id journals]
|
||||
(let [journal (db-util/entity journal-id)]
|
||||
[:li.flex.py-1.active:opacity-50.flex-col.w-full
|
||||
{:on-click #(pages-util/nav-to-block! journal {:reload-pages! (fn [] ())})}
|
||||
[:h1.font-semibold.opacity-90 (:block/title journal)]
|
||||
[: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
|
||||
(blocks/page-blocks journal)
|
||||
(cc-blocks/page-blocks journal)
|
||||
]))]))
|
||||
|
||||
(rum/defc home []
|
||||
@@ -136,7 +137,7 @@
|
||||
:on-click (fn []
|
||||
(let [apply-date! (fn [date]
|
||||
(let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
|
||||
nav-to-journal! #(pages-util/nav-to-block! % {:reload-pages! (fn [] ())})]
|
||||
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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns capacitor.pages.blocks
|
||||
(ns capacitor.components.blocks
|
||||
(:require [capacitor.state :as state]
|
||||
[frontend.db.model :as db-model]
|
||||
[promesa.core :as p]
|
||||
@@ -8,6 +8,7 @@
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.state :as fstate]
|
||||
[capacitor.components.editor :as cc-editor]
|
||||
[capacitor.ionic :as ionic]))
|
||||
|
||||
(rum/defc edit-block-modal
|
||||
@@ -80,17 +81,43 @@
|
||||
(some-> @state/*nav-root
|
||||
(.push #(edit-block-modal block opts))))
|
||||
|
||||
(defn get-dom-block-uuid
|
||||
[^js el]
|
||||
(some-> el
|
||||
(.closest "[data-blockid]")
|
||||
(.-dataset) (.-blockid)
|
||||
(uuid)))
|
||||
|
||||
(rum/defc block-editor
|
||||
[])
|
||||
[block]
|
||||
(let [content (:block/title block)]
|
||||
(cc-editor/editor-aux content
|
||||
{:on-outside! (fn []
|
||||
(when (= block (:editing-block @state/*state))
|
||||
(state/set-state! :editing-block nil)))})))
|
||||
|
||||
(rum/defc block-content
|
||||
[])
|
||||
[block]
|
||||
(let [content (:block/title block)]
|
||||
(cc-editor/content-aux content {})))
|
||||
|
||||
(rum/defc block-item
|
||||
[block]
|
||||
(when block
|
||||
[:li.text-xl.pr-1 {:on-click #()}
|
||||
[:span (:block/title block)]]))
|
||||
(let [[editing-block set-editing-block!] (state/use-app-state :editing-block)]
|
||||
(when block
|
||||
(let [editing? (and editing-block
|
||||
(= (:block/uuid block) (:block/uuid editing-block)))]
|
||||
|
||||
[:li.text-xl.pr-1.active:opacity-50.block-item
|
||||
{:on-click (fn []
|
||||
(when-not editing?
|
||||
(set-editing-block! block)))
|
||||
:data-blockid (:block/uuid block)}
|
||||
[:div.block-content-or-editor
|
||||
{:class (if editing? "block" "inline")}
|
||||
(if editing?
|
||||
(block-editor block)
|
||||
(block-content block))]]))))
|
||||
|
||||
(rum/defc blocks-list
|
||||
[blocks]
|
||||
44
src/main/capacitor/components/editor.cljs
Normal file
44
src/main/capacitor/components/editor.cljs
Normal file
@@ -0,0 +1,44 @@
|
||||
(ns capacitor.components.editor
|
||||
(:require [rum.core :as rum]
|
||||
[capacitor.ionic :as ionic]
|
||||
[frontend.handler.notification :as notification]))
|
||||
|
||||
(rum/defc editor-aux
|
||||
[content {:keys [on-outside!]}]
|
||||
|
||||
(let [*input (rum/use-ref nil)]
|
||||
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
(let [timer (js/requestAnimationFrame
|
||||
(fn []
|
||||
(when-let [^js input (some-> (rum/deref *input)
|
||||
(.querySelector "textarea"))]
|
||||
(.focus input)
|
||||
(let [len (.-length (.-value input))]
|
||||
(.setSelectionRange input len len))
|
||||
;(.scrollIntoView input #js {:behavior "smooth", :block "start"})
|
||||
)))]
|
||||
#(js/clearTimeout timer)))
|
||||
[])
|
||||
|
||||
(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 "mousedown" handle-outside!)
|
||||
#(js/window.removeEventListener "mousedown" handle-outside!)))
|
||||
[])
|
||||
|
||||
(ionic/ion-textarea
|
||||
{:class "editor-aux-input bg-gray-100 border"
|
||||
:ref *input
|
||||
:auto-grow true
|
||||
:autofocus true
|
||||
:value content})))
|
||||
|
||||
(rum/defc content-aux
|
||||
[content & opts]
|
||||
|
||||
[:p content])
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns capacitor.pages.settings
|
||||
(ns capacitor.components.settings
|
||||
(:require [capacitor.handler :as handler]
|
||||
[capacitor.pages.utils :as pages-util]
|
||||
[capacitor.components.utils :as cc-util]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[capacitor.state :as state]
|
||||
@@ -74,7 +74,7 @@
|
||||
(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)))})}
|
||||
{: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")
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns capacitor.pages.utils
|
||||
(ns capacitor.components.utils
|
||||
(:require [capacitor.state :as state]
|
||||
[capacitor.pages.blocks :as page-blocks]
|
||||
[capacitor.components.ui :as ui]
|
||||
[capacitor.components.blocks :as cc-blocks]
|
||||
[cljs-bean.core :as bean]))
|
||||
|
||||
;; https://ionicframework.com/docs/api/nav#push
|
||||
@@ -16,9 +15,9 @@
|
||||
(defn nav-to-block!
|
||||
[page-or-block opts]
|
||||
(some-> @state/*nav-root
|
||||
(.push #(page-blocks/page page-or-block opts))))
|
||||
(.push #(cc-blocks/page page-or-block opts))))
|
||||
|
||||
(defn nav-to-edit-block!
|
||||
[block opts]
|
||||
(some-> @state/*nav-root
|
||||
(.push #(page-blocks/edit-block-modal block opts))))
|
||||
(.push #(cc-blocks/edit-block-modal block opts))))
|
||||
@@ -1 +1,2 @@
|
||||
(ns capacitor.hooks)
|
||||
(ns capacitor.hooks
|
||||
(:require [rum.core :as rum]))
|
||||
|
||||
@@ -1,14 +1,47 @@
|
||||
(ns capacitor.state
|
||||
(:require [frontend.rum :as r]))
|
||||
(:require [frontend.rum :as r]
|
||||
[frontend.util :as util]))
|
||||
|
||||
(defonce *nav-root (atom nil))
|
||||
(defonce *state
|
||||
(atom {:version 0
|
||||
:last-modified-page-uuid nil}))
|
||||
:last-modified-page-uuid nil
|
||||
:editing-block 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)))
|
||||
|
||||
(defn set-state!
|
||||
[path value & {:keys [path-in-sub-atom]}]
|
||||
(let [path-coll? (coll? path)
|
||||
get-fn (if path-coll? get-in get)
|
||||
s (get-fn @*state path)
|
||||
s-atom? (util/atom? s)
|
||||
path-coll?-in-sub-atom (coll? path-in-sub-atom)]
|
||||
(cond
|
||||
(and s-atom? path-in-sub-atom path-coll?-in-sub-atom)
|
||||
(let [old-v (get-in @s path-in-sub-atom)]
|
||||
(when (not= old-v value)
|
||||
(swap! s assoc-in path-in-sub-atom value)))
|
||||
|
||||
(and s-atom? path-in-sub-atom)
|
||||
(let [old-v (get @s path-in-sub-atom)]
|
||||
(when (not= old-v value)
|
||||
(swap! s assoc path-in-sub-atom value)))
|
||||
|
||||
s-atom?
|
||||
(when (not= @s value)
|
||||
(reset! s value))
|
||||
|
||||
path-coll?
|
||||
(when (not= s value)
|
||||
(swap! *state assoc-in path value))
|
||||
|
||||
:else
|
||||
(when (not= s value)
|
||||
(swap! *state assoc path value))))
|
||||
nil)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user