fix: undo block deletion needs multiple steps (#8833)

fix: undo block deletion needs multiple steps

---------

Co-authored-by: charlie <xyhp915@qq.com>
pull/8855/head^2
Tienson Qin 2023-03-21 19:35:40 +08:00 committed by GitHub
parent 24735891dc
commit 0eab5ebef4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 37 deletions

View File

@ -224,35 +224,41 @@
(defn edit-block!
([block pos id]
(edit-block! block pos id nil))
([block pos id {:keys [custom-content tail-len move-cursor?]
([block pos id {:keys [custom-content tail-len move-cursor? retry-times]
:or {tail-len 0
move-cursor? true}}]
(when-not config/publishing?
(when-let [block-id (:block/uuid block)]
(let [block (or (db/pull [:block/uuid block-id]) block)
edit-input-id (if (uuid? id)
(get-edit-input-id-with-block-id id)
(-> (str (subs id 0 (- (count id) 36)) block-id)
(string/replace "ls-block" "edit-block")))
content (or custom-content (:block/content block) "")
content-length (count content)
text-range (cond
(vector? pos)
(text-range-by-lst-fst-line content pos)
move-cursor? true
retry-times 0}
:as opts}]
(when-not (> retry-times 2)
(when-not config/publishing?
(when-let [block-id (:block/uuid block)]
(let [block (or (db/pull [:block/uuid block-id]) block)
edit-input-id (if (uuid? id)
(get-edit-input-id-with-block-id id)
(-> (str (subs id 0 (- (count id) 36)) block-id)
(string/replace "ls-block" "edit-block")))
content (or custom-content (:block/content block) "")
content-length (count content)
text-range (cond
(vector? pos)
(text-range-by-lst-fst-line content pos)
(and (> tail-len 0) (>= (count content) tail-len))
(subs content 0 (- (count content) tail-len))
(and (> tail-len 0) (>= (count content) tail-len))
(subs content 0 (- (count content) tail-len))
(or (= :max pos) (<= content-length pos))
content
(or (= :max pos) (<= content-length pos))
content
:else
(subs content 0 pos))
content (-> (property/remove-built-in-properties (:block/format block)
content)
(drawer/remove-logbook))]
(clear-selection!)
(state/set-editing! edit-input-id content block text-range move-cursor?))))))
:else
(subs content 0 pos))
content (-> (property/remove-built-in-properties (:block/format block)
content)
(drawer/remove-logbook))]
(clear-selection!)
(if edit-input-id
(state/set-editing! edit-input-id content block text-range move-cursor?)
;; Block may not be rendered yet
(js/setTimeout (fn [] (edit-block! block pos id (update opts :retry-times inc))) 10))))))))
(defn- another-block-with-same-id-exists?
[current-id block-id]
@ -787,7 +793,11 @@
(edit-block! block pos id
{:custom-content new-value
:tail-len tail-len
:move-cursor? false}))))))
:move-cursor? false})
{:prev-block block
:new-content new-value})))))
(declare save-block!)
(defn delete-block!
([repo]
@ -810,9 +820,18 @@
(when-not (and has-children? left-has-children?)
(when block-parent-id
(let [block-parent (gdom/getElement block-parent-id)
sibling-block (util/get-prev-block-non-collapsed-non-embed block-parent)]
(delete-block-aux! block delete-children?)
(move-to-prev-block repo sibling-block format id value)))))))))
sibling-block (util/get-prev-block-non-collapsed-non-embed block-parent)
{:keys [prev-block new-content]} (move-to-prev-block repo sibling-block format id value)
concat-prev-block? (boolean (and prev-block new-content))
transact-opts (cond->
{:outliner-op :delete-block}
concat-prev-block?
(assoc :concat-data
{:last-edit-block (:block/uuid block)}))]
(outliner-tx/transact! transact-opts
(when concat-prev-block?
(save-block! repo prev-block new-content))
(delete-block-aux! block delete-children?))))))))))
(state/set-editor-op! nil)))
(defn delete-blocks!
@ -2584,9 +2603,17 @@
nil
:else
(do
(delete-block-aux! next-block false)
(state/set-edit-content! input-id (str value "" (:block/content next-block)))
(let [edit-block (state/get-edit-block)
transact-opts {:outliner-op :delete-block
:concat-data {:last-edit-block (:block/uuid edit-block)
:end? true}}
new-content (str value "" (:block/content next-block))
repo (state/get-current-repo)]
(outliner-tx/transact! transact-opts
(save-block! repo edit-block new-content)
(delete-block-aux! next-block false))
(state/set-edit-content! input-id new-content)
(cursor/move-cursor-to input current-pos)))))
(defn keydown-delete-handler

View File

@ -1,5 +1,6 @@
(ns frontend.modules.editor.undo-redo
(:require [datascript.core :as d]
[frontend.db :as db]
[frontend.db.conn :as conn]
[frontend.modules.datascript-report.core :as db-report]
[frontend.state :as state]
@ -103,14 +104,33 @@
(when e
(let [{:keys [txs tx-meta]} e
new-txs (get-txs false txs)
editor-cursor (if (= (get-in e [:editor-cursor :last-edit-block :block/uuid])
(get-in prev-e [:editor-cursor :last-edit-block :block/uuid])) ; same block
undo-delete-concat-block? (and (= :delete-block (:outliner-op tx-meta))
(seq (:concat-data tx-meta)))
editor-cursor (cond
undo-delete-concat-block?
(let [data (:concat-data tx-meta)]
(assoc (:editor-cursor e)
:last-edit-block {:block/uuid (:last-edit-block data)}
:pos (if (:end? data) :max 0)))
;; same block
(= (get-in e [:editor-cursor :last-edit-block :block/uuid])
(get-in prev-e [:editor-cursor :last-edit-block :block/uuid]))
(:editor-cursor prev-e)
:else
(:editor-cursor e))]
(push-redo e)
(transact! new-txs (merge {:undo? true}
tx-meta
(select-keys e [:pagination-blocks-range])))
(when undo-delete-concat-block?
(when-let [block (state/get-edit-block)]
(state/set-edit-content! (state/get-edit-input-id)
(:block/content (db/entity (:db/id block))))))
(when (:whiteboard/transact? tx-meta)
(state/pub-event! [:whiteboard/undo e]))
(assoc e

View File

@ -58,7 +58,10 @@
(not (:skip-transact? opts))
(not (contains? (:file/unlinked-dirs @state/state)
(config/get-repo-dir (state/get-current-repo)))))
;; (prn "[DEBUG] Outliner transact:")
;; (frontend.util/pprint txs)
(try
(let [repo (get opts :repo (state/get-current-repo))
conn (conn/get-db repo false)

View File

@ -1,5 +1,10 @@
(ns frontend.modules.outliner.transaction
#?(:cljs (:require-macros [frontend.modules.outliner.transaction])))
#?(:cljs (:require-macros [frontend.modules.outliner.transaction]))
#?(:cljs (:require [malli.core :as m])))
(def transact-opts [:or :symbol :map])
#?(:cljs (m/=> transact! [:=> [:cat transact-opts :any] :any]))
(defmacro transact!
"Batch all the transactions in `body` to a single transaction, Support nested transact! calls.
@ -18,7 +23,7 @@
(move-blocks! ...)
(delete-blocks! ...))"
[opts & body]
(assert (map? opts))
(assert (or (map? opts) (symbol? opts)) (str "opts is not a map or symbol, type: " (type opts) ))
`(let [transact-data# frontend.modules.outliner.core/*transaction-data*
opts# (if transact-data#
(assoc ~opts :nested-transaction? true)

View File

@ -1119,7 +1119,8 @@ Similar to re-frame subscriptions"
(when container
{:last-edit-block edit-block
:container (gobj/get container "id")
:pos (cursor/pos (gdom/getElement edit-input-id))})))
:pos (or (cursor/pos (gdom/getElement edit-input-id))
(count (:block/content edit-block)))})))
(defn clear-edit!
[]