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

View File

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

View File

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

View File

@ -1,5 +1,10 @@
(ns frontend.modules.outliner.transaction (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! (defmacro transact!
"Batch all the transactions in `body` to a single transaction, Support nested transact! calls. "Batch all the transactions in `body` to a single transaction, Support nested transact! calls.
@ -18,7 +23,7 @@
(move-blocks! ...) (move-blocks! ...)
(delete-blocks! ...))" (delete-blocks! ...))"
[opts & body] [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* `(let [transact-data# frontend.modules.outliner.core/*transaction-data*
opts# (if transact-data# opts# (if transact-data#
(assoc ~opts :nested-transaction? true) (assoc ~opts :nested-transaction? true)

View File

@ -1119,7 +1119,8 @@ Similar to re-frame subscriptions"
(when container (when container
{:last-edit-block edit-block {:last-edit-block edit-block
:container (gobj/get container "id") :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! (defn clear-edit!
[] []