mirror of
https://github.com/logseq/logseq.git
synced 2026-05-24 20:54:09 +00:00
enhance(capacitor): improve block editor
This commit is contained in:
@@ -212,7 +212,7 @@
|
||||
(fn []
|
||||
(cond
|
||||
(not (nil? (state/get-editing-block)))
|
||||
(state/set-editing-block! nil)
|
||||
(state/exit-editing!)
|
||||
|
||||
:else
|
||||
(cc-utils/nav-pop!)))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require [capacitor.state :as state]
|
||||
[clojure.string :as string]
|
||||
[frontend.db.model :as db-model]
|
||||
[frontend.util.cursor :as cursor]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[frontend.db.async :as db-async]
|
||||
@@ -96,43 +97,49 @@
|
||||
(rum/defc block-editor
|
||||
[block]
|
||||
(let [content (:block/title block)
|
||||
exit! #(state/set-state! :editing-block nil)]
|
||||
block-uuid (:block/uuid block)
|
||||
current-repo (fstate/get-current-repo)]
|
||||
|
||||
(cc-editor/editor-aux content
|
||||
{:on-outside!
|
||||
{:on-focused!
|
||||
(fn [^js input]
|
||||
(let [cursor-at (some-> (state/get-editing-opts) :cursor-at)]
|
||||
(if (number? cursor-at)
|
||||
(cursor/move-cursor-to input cursor-at)
|
||||
(cursor/move-cursor-to-end input))))
|
||||
|
||||
:on-outside!
|
||||
(fn [^js e]
|
||||
(let [edit-target? (some-> e (.-target) (cc-common/get-dom-block-uuid))]
|
||||
(when edit-target?
|
||||
(cc-common/keep-keyboard-open e))
|
||||
(when (and (not edit-target?)
|
||||
(= block (:editing-block @state/*state)))
|
||||
(exit!))))
|
||||
(state/exit-editing!))))
|
||||
|
||||
:on-save!
|
||||
(fn [content {:keys [enter?]}]
|
||||
(let [block-uuid (:block/uuid block)
|
||||
current-repo (fstate/get-current-repo)]
|
||||
|
||||
;; update block content
|
||||
(-> (do (when enter? (exit!))
|
||||
;; check block exist?
|
||||
(when-not (db-utils/entity (:db/id block))
|
||||
(throw nil))
|
||||
(editor-handler/save-block! current-repo block-uuid content))
|
||||
(p/then (fn []
|
||||
(state/set-state! [:modified-blocks block-uuid] (js/Date.now))
|
||||
(when enter?
|
||||
;; create new block
|
||||
(cc-common/keep-keyboard-open nil)
|
||||
(-> (insert-new-block! "" {:block-uuid block-uuid})
|
||||
(p/then (fn [new-block]
|
||||
(prn :debug "new block:" new-block)
|
||||
(when-let [parent-block (:block/parent new-block)]
|
||||
(state/set-state! [:modified-pages (:block/uuid parent-block)] (js/Date.now)))
|
||||
;; edit the new block
|
||||
(js/requestAnimationFrame #(state/set-editing-block! new-block))
|
||||
)))
|
||||
)))
|
||||
(p/catch #(notification/show! (str %) :error)))))
|
||||
(fn [content {:keys [enter? esc?]}]
|
||||
;; update block content
|
||||
(-> (do (when (or enter? esc?) (state/exit-editing!))
|
||||
;; check block exist?
|
||||
(when-not (db-utils/entity (:db/id block))
|
||||
(throw nil))
|
||||
(editor-handler/save-block! current-repo block-uuid content))
|
||||
(p/then (fn []
|
||||
(state/set-state! [:modified-blocks block-uuid] (js/Date.now))
|
||||
(when enter?
|
||||
;; create new block
|
||||
(cc-common/keep-keyboard-open nil)
|
||||
(-> (insert-new-block! "" {:block-uuid block-uuid})
|
||||
(p/then (fn [new-block]
|
||||
(prn :debug "new block:" new-block)
|
||||
(when-let [parent-block (:block/parent new-block)]
|
||||
(state/set-state! [:modified-pages (:block/uuid parent-block)] (js/Date.now)))
|
||||
;; edit the new block
|
||||
(js/requestAnimationFrame #(state/edit-block! new-block))
|
||||
)))
|
||||
)))
|
||||
(p/catch #(notification/show! (str %) :error))))
|
||||
|
||||
:on-delete!
|
||||
(fn [content]
|
||||
@@ -140,18 +147,21 @@
|
||||
parent-block (:block/parent block)]
|
||||
(cond
|
||||
(and (nil? prev-block) (nil? parent-block)) nil
|
||||
|
||||
:else
|
||||
(let [has-children? (seq (:block/_parent block))]
|
||||
(when-not has-children?
|
||||
(p/do!
|
||||
(editor-handler/delete-block-aux! block)
|
||||
(state/set-state! [:modified-blocks (:block/uuid block)] (js/Date.now))
|
||||
(when (and (false? (some-> content (string/trim) (string/blank?))) prev-block)
|
||||
(editor-handler/save-block! current-repo prev-block
|
||||
(str (:block/title prev-block) content)))
|
||||
(when prev-block
|
||||
(cc-common/keep-keyboard-open nil)
|
||||
(js/requestAnimationFrame #(state/set-editing-block! prev-block)))
|
||||
(when (false? (some-> content (string/trim) (string/blank?)))
|
||||
(notification/show! "concat prev block content!!")
|
||||
)))))
|
||||
(state/set-state! [:modified-blocks (:block/uuid prev-block)] (js/Date.now))
|
||||
(js/requestAnimationFrame #(state/edit-block! prev-block
|
||||
{:cursor-at (count (:block/title prev-block))})))))))
|
||||
(prn :debug "delete node:" (:db/id block) (:block/title prev-block))
|
||||
))
|
||||
})))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
[frontend.handler.notification :as notification]))
|
||||
|
||||
(rum/defc editor-aux
|
||||
[content {:keys [on-outside! on-save! on-delete!]}]
|
||||
[content {:keys [on-outside! on-save! on-delete! on-focused! on-keydown! on-keyup!]}]
|
||||
|
||||
(let [*input (rum/use-ref nil)]
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
(fn []
|
||||
(when-let [^js input (some-> (rum/deref *input))]
|
||||
(.focus input)
|
||||
(let [len (.-length (.-value input))]
|
||||
(.setSelectionRange input len len))
|
||||
(when on-focused!
|
||||
(on-focused! input))
|
||||
;(.scrollIntoView input #js {:behavior "smooth", :block "start"})
|
||||
)))
|
||||
#())
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
(let [save-handle!
|
||||
(fn [opts]
|
||||
(let [content (.-value (rum/deref *input))]
|
||||
(when-let [content (some-> (rum/deref *input) (.-value))]
|
||||
(when on-save!
|
||||
(prn :debug "save block content:" content opts)
|
||||
(on-save! content opts))))
|
||||
@@ -52,19 +52,25 @@
|
||||
(let [ekey (.-key e)
|
||||
target (.-target e)
|
||||
enter? (= ekey "Enter")
|
||||
esc? (= ekey "Escape")
|
||||
backspace? (= ekey "Backspace")]
|
||||
|
||||
(cond
|
||||
(and enter? (cursor/end? target))
|
||||
(do (save-handle! {:enter? true})
|
||||
(util/stop e))
|
||||
(when (or (nil? on-keydown!)
|
||||
(not (false? (on-keydown! e))))
|
||||
(cond
|
||||
(or (and enter? (cursor/end? target)) esc?)
|
||||
(do (save-handle! {:enter? enter? :esc? esc?})
|
||||
(util/stop e))
|
||||
|
||||
(and backspace? (cursor/start? target))
|
||||
(do (delete-handle! {})
|
||||
(util/stop e))
|
||||
(and backspace? (cursor/start? target))
|
||||
(do (delete-handle! {})
|
||||
(util/stop e))
|
||||
|
||||
:else (debounce-save-handle!)
|
||||
)))
|
||||
:else (debounce-save-handle!)
|
||||
))))
|
||||
:on-key-up (fn [^js e]
|
||||
(when on-keyup!
|
||||
(on-keyup! e)))
|
||||
:default-value content}))))
|
||||
|
||||
(rum/defc content-aux
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
(defonce *state
|
||||
(atom {:version 0
|
||||
:editing-block nil
|
||||
:editing-opts nil
|
||||
:modified-pages {}
|
||||
:modified-blocks {} ;; {:uuid timestamp}
|
||||
:modified-blocks {} ;; {:uuid timestamp}
|
||||
}))
|
||||
|
||||
(defn use-nav-root [] (r/use-atom *nav-root))
|
||||
@@ -50,5 +51,14 @@
|
||||
(defn get-editing-block []
|
||||
(:editing-block @*state))
|
||||
|
||||
(defn set-editing-block! [block]
|
||||
(set-state! :editing-block block))
|
||||
(defn edit-block!
|
||||
([block] (edit-block! block nil))
|
||||
([block opts]
|
||||
(set-state! :editing-block block)
|
||||
(set-state! :editing-opts opts)))
|
||||
|
||||
(defn exit-editing! []
|
||||
(edit-block! nil nil))
|
||||
|
||||
(defn get-editing-opts []
|
||||
(:editing-opts @*state))
|
||||
|
||||
Reference in New Issue
Block a user