mirror of https://github.com/logseq/logseq
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
parent
24735891dc
commit
0eab5ebef4
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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!
|
||||||
[]
|
[]
|
||||||
|
|
Loading…
Reference in New Issue