enhance(capacitor): direction keys management for the block editor

This commit is contained in:
charlie
2025-05-22 17:58:00 +08:00
parent 05ca8fd883
commit 1ef089b3eb
3 changed files with 66 additions and 5 deletions

View File

@@ -3,6 +3,7 @@
[clojure.string :as string]
[frontend.db.model :as db-model]
[frontend.util.cursor :as cursor]
[dommy.core :as dom]
[promesa.core :as p]
[rum.core :as rum]
[frontend.db.async :as db-async]
@@ -93,6 +94,29 @@
opts {:edit-block? false})]
(editor-handler/api-insert-new-block! content opts')))
(defn dom-prev-block
[^js current-block-node]
(when-let [prev-node (loop [node current-block-node]
(when-let [node (some-> node (.-previousSibling))]
(when node
(if (dom/has-class? node "block-item")
node
(recur node)))))]
(let [uuid' (.-blockid (.-dataset prev-node))]
(db-model/get-block-by-uuid (uuid uuid')))))
(defn dom-next-block
[^js current-block-node]
(when-let [next-node (loop [node current-block-node]
(when-let [node (some-> node (.-nextSibling))]
(when node
(if (dom/has-class? node "block-item")
node
(recur node)))))]
(prn :debug next-node)
(let [uuid' (.-blockid (.-dataset next-node))]
(db-model/get-block-by-uuid (uuid uuid')))))
;; components
(rum/defc block-editor
[block]
@@ -108,6 +132,16 @@
(cursor/move-cursor-to input cursor-at)
(cursor/move-cursor-to-end input))))
:on-bounded!
(fn [dir ^js input]
(case dir
:up (when-let [prev-block (dom-prev-block (.closest input ".block-item"))]
(state/edit-block! prev-block {}))
:down (when-let [next-block (dom-next-block (.closest input ".block-item"))]
(js/console.log next-block)
(state/edit-block! next-block {}))
:dune))
:on-outside!
(fn [^js e]
(let [edit-target? (some-> e (.-target) (cc-common/get-dom-block-uuid))]

View File

@@ -1,13 +1,14 @@
(ns capacitor.components.editor
(:require [rum.core :as rum]
[capacitor.components.ui :as ui]
[cljs-bean.core :as bean]
[capacitor.ionic :as ionic]
[frontend.util.cursor :as cursor]
[frontend.util :as util]
[frontend.handler.notification :as notification]))
(rum/defc editor-aux
[content {:keys [on-outside! on-save! on-delete! on-focused! on-keydown! on-keyup!]}]
[content {:keys [on-outside! on-save! on-delete! on-focused! on-keydown! on-keyup! on-bounded!]}]
(let [*input (rum/use-ref nil)]
@@ -48,25 +49,35 @@
(ui/textarea
{:class "editor-aux-input bg-gray-200 border-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")]
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)))
(or (and enter? (cursor/end? target)) esc?)
(do (save-handle! {:enter? enter? :esc? esc?})
(util/stop e))
(and backspace? (cursor/start? target))
(and backspace?
(cursor/start? target)
(not (util/input-text-selected? target)))
(do (delete-handle! {})
(util/stop e))
:else (debounce-save-handle!)
))))
:on-key-up (fn [^js e]
(when on-keyup!

View File

@@ -55,7 +55,23 @@ const settleStatusBar = async () => {
}
}
function checkCursorLine (textarea) {
const { value, selectionStart } = textarea
const lines = value.split('\n')
const totalLines = lines.length
const textBeforeCursor = value.substring(0, selectionStart)
const currentLine = textBeforeCursor.split('\n').length
const isFirstLine = currentLine === 1
const isLastLine = currentLine === totalLines
return { isFirstLine, isLastLine, currentLine, totalLines }
}
window.externalsjs = {
initGlobalListeners,
settleStatusBar,
checkCursorLine,
}