fix: validate duplicate object when typed all at once

Fixes 2nd buggy case of logseq/db-test#66 where user
types "hello #Task" all at once. Previous fix had only handled
typing #Task after hello was already in the block
pull/11514/head
Gabriel Horner 2024-09-10 16:04:31 -04:00
parent 11ba4b2ad7
commit 30a635702c
3 changed files with 44 additions and 31 deletions

View File

@ -0,0 +1,39 @@
(ns frontend.handler.db-based.page
(:require [logseq.outliner.core :as outliner-core]
[frontend.db :as db]
[frontend.handler.editor :as editor-handler]
[frontend.handler.notification :as notification]
;; ui-outliner-tx macro relying on this
#_:clj-kondo/ignore
[frontend.state :as state]
[frontend.modules.outliner.ui :as ui-outliner-tx]
[promesa.core :as p]))
(defn- valid-tag?
"Returns a boolean indicating whether the new tag passes all valid checks.
When returning false, this fn also displays appropriate notifications to the user"
[repo block tag-entity]
(try
(outliner-core/validate-unique-by-name-tag-and-block-type
(db/get-db repo)
(:block/title block)
(update block :block/tags (fnil conj #{}) tag-entity))
true
(catch :default e
(if (= :notification (:type (ex-data e)))
(let [payload (:payload (ex-data e))]
(notification/show! (:message payload) (:type payload))
false)
(throw e)))))
(defn add-tag [repo block-id tag-entity]
(ui-outliner-tx/transact!
{:outliner-op :save-block}
(p/do!
(editor-handler/save-current-block!)
;; Check after save-current-block to get most up to date block content
(when (valid-tag? repo (db/entity repo [:block/uuid block-id]) tag-entity)
(let [tx-data [[:db/add [:block/uuid block-id] :block/tags (:db/id tag-entity)]
;; TODO: Move this to outliner.core to consistently add refs for tags
[:db/add [:block/uuid block-id] :block/refs (:db/id tag-entity)]]]
(db/transact! repo tx-data {:outliner-op :save-block}))))))

View File

@ -46,7 +46,7 @@
[frontend.handler.property.util :as pu]
[datascript.impl.entity :as de]
[logseq.db.frontend.class :as db-class]
[logseq.outliner.core :as outliner-core]))
[frontend.handler.db-based.page :as db-page-handler]))
(def <create! page-common-handler/<create!)
(def <delete! page-common-handler/<delete!)
@ -314,32 +314,6 @@
(let [current-selected (util/get-selected-text)]
(cursor/move-cursor-forward input (+ 2 (count current-selected))))))
(defn- valid-tag?
"Returns a boolean indicating whether the new tag passes all valid checks.
When returning false, this fn also displays appropriate notifications to the user"
[repo block tag-entity]
(try
(outliner-core/validate-unique-by-name-tag-and-block-type
(db/get-db repo)
(:block/title block)
(update block :block/tags (fnil conj #{}) tag-entity))
true
(catch :default e
(if (= :notification (:type (ex-data e)))
(let [payload (:payload (ex-data e))]
(notification/show! (:message payload) (:type payload))
false)
(throw e)))))
(defn add-tag [repo {block-id :block/uuid :as block} tag-entity]
(when (valid-tag? repo block tag-entity)
(let [tx-data [[:db/add [:block/uuid block-id] :block/tags (:db/id tag-entity)]
;; TODO: Move this to outliner.core to consistently add refs for tags
[:db/add [:block/uuid block-id] :block/refs (:db/id tag-entity)]]]
(ui-outliner-tx/transact! {:outliner-op :save-block}
(editor-handler/save-current-block!)
(db/transact! repo tx-data {:outliner-op :save-block})))))
(defn- tag-on-chosen-handler
[input id pos format current-pos edit-content q db-based?]
(fn [chosen-result ^js e]
@ -394,8 +368,8 @@
nearest-node (some-> (editor-handler/get-nearest-page) string/trim)]
(if (and add-tag-to-nearest-node? (not (string/blank? nearest-node)))
(when-let [e (db/get-page nearest-node)]
(add-tag (state/get-current-repo) e tag-entity))
(add-tag (state/get-current-repo) edit-block tag-entity))))))))
(db-page-handler/add-tag (state/get-current-repo) (:block/uuid e) tag-entity))
(db-page-handler/add-tag (state/get-current-repo) (:block/uuid edit-block) tag-entity))))))))
(when input (.focus input))))))

View File

@ -7,7 +7,7 @@
[logseq.db.sqlite.util :as sqlite-util]
[frontend.db :as db]
[frontend.handler.editor :as editor-handler]
[frontend.handler.page :as page-handler]
[frontend.handler.db-based.page :as db-page-handler]
[datascript.core :as d]
[logseq.graph-parser.text :as text]
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
@ -236,7 +236,7 @@ This can be called in synchronous contexts as no async fns should be invoked"
[repo block-uuid content {:keys [tags]}]
(editor-handler/save-block! repo block-uuid content)
(doseq [tag tags]
(page-handler/add-tag repo block-uuid (db/get-page tag))))
(db-page-handler/add-tag repo block-uuid (db/get-page tag))))
(defn create-page!
[title & {:as opts}]