Merge branch 'master' into feat/cliable

This commit is contained in:
Tienson Qin
2026-03-31 21:10:05 +08:00
310 changed files with 25372 additions and 32661 deletions

View File

@@ -6,6 +6,7 @@
[frontend.db :as db]
[frontend.db.async :as db-async]
[frontend.db.model :as db-model]
[frontend.handler.notification :as notification]
[frontend.handler.property.util :as pu]
[frontend.mobile.haptics :as haptics]
[frontend.modules.outliner.op :as outliner-op]
@@ -149,29 +150,31 @@
:as opts}]
(when (and (not config/publishing?) (:block/uuid block))
(let [repo (state/get-current-repo)]
(p/do!
(db-async/<get-block repo (:db/id block) {:children? false})
(when save-code-editor? (state/pub-event! [:editor/save-code-editor]))
(when (not= (:block/uuid block) (:block/uuid (state/get-edit-block)))
(state/clear-edit! {:clear-editing-block? false}))
(when-let [block-id (:block/uuid block)]
(let [block (or (db/entity [:block/uuid block-id]) block)
content (or custom-content (:block/title block) "")
content-length (count content)
text-range (cond
(vector? pos)
(text-range-by-lst-fst-line content pos)
(when-let [block-id (:block/uuid block)]
(let [block (or (db/entity [:block/uuid block-id]) block)]
(if (ldb/recycled? block)
(notification/show! "Recycle is read-only." :warning)
(p/do!
(db-async/<get-block repo (:db/id block) {:children? false})
(when save-code-editor? (state/pub-event! [:editor/save-code-editor]))
(when (not= (:block/uuid block) (:block/uuid (state/get-edit-block)))
(state/clear-edit! {:clear-editing-block? false}))
(let [content (or custom-content (:block/title 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))]
(state/clear-selection!)
(edit-block-aux repo block content text-range (assoc opts :pos pos))))))))
:else
(subs content 0 pos))]
(state/clear-selection!)
(edit-block-aux repo block content text-range (assoc opts :pos pos))))))))))
(defn- get-original-block-by-dom
[node]

View File

@@ -1,6 +1,8 @@
(ns frontend.handler.common.developer
"Common fns for developer related functionality"
(:require [cljs.pprint :as pprint]
(:require ["/frontend/utils" :as utils]
[cljs.pprint :as pprint]
[clojure.string :as string]
[datascript.impl.entity :as de]
[frontend.db :as db]
[frontend.format.mldoc :as mldoc]
@@ -9,6 +11,7 @@
[frontend.persist-db :as persist-db]
[frontend.state :as state]
[frontend.ui :as ui]
[frontend.util :as util]
[frontend.util.page :as page-util]
[logseq.db.frontend.property :as db-property]
[promesa.core :as p]))
@@ -83,10 +86,50 @@
(defn ^:export validate-db []
(state/<invoke-db-worker :thread-api/validate-db (state/get-current-repo)))
(defn- checksum-export-file-name
[repo]
(-> (or repo "graph")
(string/replace #"^/+" "")
(string/replace #"[\\/]+" "_")
(str "_checksum_" (quot (util/time-ms) 1000))))
(defn ^:export recompute-checksum-diagnostics
[]
(if-let [repo (state/get-current-repo)]
(-> (state/<invoke-db-worker :thread-api/recompute-checksum-diagnostics repo)
(p/then (fn [{:keys [recomputed-checksum local-checksum remote-checksum blocks checksum-attrs e2ee?]
:as result}]
(if (map? result)
(let [export-edn {:repo repo
:generated-at (.toISOString (js/Date.))
:e2ee? e2ee?
:recomputed-checksum recomputed-checksum
:local-checksum local-checksum
:remote-checksum remote-checksum
:checksum-attrs checksum-attrs
:blocks blocks}
content (with-out-str (pprint/pprint export-edn))
blob (js/Blob. #js [content] (clj->js {:type "text/edn;charset=utf-8"}))
filename (checksum-export-file-name repo)]
(utils/saveToFile blob filename "edn")
(notification/show!
(str "Checksum recomputed. Recomputed: " recomputed-checksum
", local: " (or local-checksum "<nil>")
", remote: " (or remote-checksum "<nil>")
". Downloaded " filename ".edn with " (count blocks)
" blocks and checksum attrs " (pr-str checksum-attrs) ".")
:success
false))
(notification/show! "Unable to compute checksum diagnostics for current graph." :warning))))
(p/catch (fn [error]
(js/console.error "recompute-checksum-diagnostics failed:" error)
(notification/show! "Failed to compute graph checksum diagnostics." :error))))
(notification/show! "No graph found" :warning)))
(defn import-chosen-graph
[repo]
(p/let [_ (persist-db/<close-db repo)]
(notification/show! (str "Graph updated! Switching to graph ...") :success)
(notification/show! "Graph updated! Switching to graph ..." :success)
(state/pub-event! [:graph/switch repo])))
(defn ^:export replace-graph-with-db-file []

View File

@@ -2,25 +2,26 @@
"Common fns for file and db based page handlers, including create!, delete!
and favorite fns. This ns should be agnostic of file or db concerns but there
is still some file-specific tech debt to remove from create!"
(:require [clojure.set :as set]
[clojure.string :as string]
[datascript.core :as d]
[dommy.core :as dom]
[frontend.db :as db]
[frontend.db.conn :as conn]
[frontend.handler.config :as config-handler]
[frontend.handler.db-based.editor :as db-editor-handler]
[frontend.handler.notification :as notification]
[frontend.handler.route :as route-handler]
[frontend.handler.ui :as ui-handler]
[frontend.modules.outliner.op :as outliner-op]
[frontend.modules.outliner.ui :as ui-outliner-tx]
[frontend.state :as state]
[logseq.common.config :as common-config]
[logseq.common.util :as common-util]
[logseq.common.util.page-ref :as page-ref]
[logseq.db :as ldb]
[promesa.core :as p]))
(:require
[clojure.set :as set]
[clojure.string :as string]
[datascript.core :as d]
[dommy.core :as dom]
[frontend.db :as db]
[frontend.db.conn :as conn]
[frontend.handler.config :as config-handler]
[frontend.handler.db-based.editor :as db-editor-handler]
[frontend.handler.notification :as notification]
[frontend.handler.route :as route-handler]
[frontend.handler.ui :as ui-handler]
[frontend.modules.outliner.op :as outliner-op]
[frontend.modules.outliner.ui :as ui-outliner-tx]
[frontend.state :as state]
[logseq.common.config :as common-config]
[logseq.common.util :as common-util]
[logseq.common.util.page-ref :as page-ref]
[logseq.db :as ldb]
[promesa.core :as p]))
(defn- wrap-tags
"Tags might have multiple words"
@@ -158,18 +159,10 @@
;; =========
(defn after-page-deleted!
[page-name tx-meta]
;; TODO: move favorite && unfavorite to worker too
[page-name]
;; TODO: move favorite && unfavorite to worker too
(when-let [page-block-uuid (:block/uuid (db/get-page page-name))]
(<db-unfavorite-page! page-block-uuid))
(when (and (not= :rename-page (:real-outliner-op tx-meta))
(= (some-> (state/get-current-page) common-util/page-name-sanity-lc)
(common-util/page-name-sanity-lc page-name)))
(route-handler/redirect-to-home!))
;; TODO: why need this?
(ui-handler/re-render-root!))
(<db-unfavorite-page! page-block-uuid)))
(defn after-page-renamed!
[repo {:keys [page-id old-name new-name]}]

View File

@@ -206,6 +206,25 @@
true
(true? graph-e2ee?)))
(defn- <ensure-user-rsa-keys-on-server!
[{:keys [server-rsa-keys-exists?]}]
(if (not= false server-rsa-keys-exists?)
(p/resolved nil)
(if @state/*db-worker
(-> (state/<invoke-db-worker :thread-api/db-sync-ensure-user-rsa-keys
{:ensure-server? true
:server-rsa-keys-exists? false})
(p/catch (fn [error]
(log/error :db-sync/ensure-user-rsa-keys-failed
{:error error
:reason :server-rsa-keys-missing})
nil)))
(do
(log/warn :db-sync/ensure-user-rsa-keys-skipped
{:reason :db-worker-not-ready
:server-rsa-keys-exists? server-rsa-keys-exists?})
(p/resolved nil)))))
(defn- <wait-for-db-worker-ready!
[]
(if @state/*db-worker
@@ -286,6 +305,8 @@
base (http-base)]
(if base
(p/let [_ (js/Promise. user-handler/task--ensure-id&access-token)
_ (state/<invoke-db-worker :thread-api/db-sync-ensure-user-rsa-keys
{:ensure-server? true})
body (coerce-http-request :graphs/create
{:graph-name (string/replace repo config/db-version-prefix "")
:schema-version schema-version
@@ -411,6 +432,8 @@
resp (fetch-json (str base "/graphs")
{:method "GET"}
{:response-schema :graphs/list})
_ (<ensure-user-rsa-keys-on-server! {:server-rsa-keys-exists?
(:user-rsa-keys-exists? resp)})
graphs (:graphs resp)
result (mapv (fn [graph]
(let [graph-e2ee? (if (contains? graph :graph-e2ee?)

View File

@@ -320,6 +320,7 @@
{:outliner-op :insert-blocks}
(save-current-block! {:current-block current-block})
(outliner-op/insert-blocks! [new-block'] current-block {:sibling? sibling?
:right-sibling-id (:db/id (:right-sibling config))
:keep-uuid? keep-uuid?
:ordered-list? ordered-list?
:replace-empty-target? replace-empty-target?
@@ -470,9 +471,9 @@
(defn insert-new-block!
"Won't save previous block content - remember to save!"
([state]
(insert-new-block! state nil))
([_state block-value]
([state right-sibling]
(insert-new-block! state nil right-sibling))
([_state block-value right-sibling]
(->
(when (not config/publishing?)
(when-let [state (get-state)]
@@ -507,7 +508,7 @@
:else
insert-new-block-aux!)
[result-promise sibling? next-block] (insert-fn config block'' value)
[result-promise sibling? next-block] (insert-fn (assoc config :right-sibling right-sibling) block'' value)
edit-block-f (fn []
(let [next-block' (db/entity [:block/uuid (:block/uuid next-block)])
pos 0
@@ -541,71 +542,72 @@
(db/get-page page)
(db/entity [:block/uuid block-uuid]))]
(when block
(let [last-block (when (not sibling?)
(let [children (:block/_parent block)
blocks (db/sort-by-order children)
last-block-id (:db/id (last blocks))]
(when last-block-id
(db/entity last-block-id))))
new-block (-> (select-keys block [:block/page])
(assoc :block/title content))
new-block (assoc new-block :block/page
(if page
(:db/id block)
(:db/id (:block/page new-block))))
new-block (-> new-block
(wrap-parse-block)
(assoc :block/uuid (or custom-uuid (db/new-block-id))))
new-block (merge new-block other-attrs)
block' (db/entity (:db/id block))
[target-block sibling?] (cond
before?
(let [left-or-parent (or (ldb/get-left-sibling block)
(:block/parent block))
sibling? (if (= (:db/id (:block/parent block)) (:db/id left-or-parent))
false sibling?)]
[left-or-parent sibling?])
(if (ldb/recycled? block)
(notification/show! "Recycle is read-only." :warning)
(let [last-block (when (not sibling?)
(let [children (:block/_parent block)
blocks (db/sort-by-order children)
last-block-id (:db/id (last blocks))]
(when last-block-id
(db/entity last-block-id))))
new-block (-> (select-keys block [:block/page])
(assoc :block/title content))
new-block (assoc new-block :block/page
(if page
(:db/id block)
(:db/id (:block/page new-block))))
new-block (-> new-block
(wrap-parse-block)
(assoc :block/uuid (or custom-uuid (db/new-block-id))))
new-block (merge new-block other-attrs)
block' (db/entity (:db/id block))
[target-block sibling?] (cond
before?
(let [left-or-parent (or (ldb/get-left-sibling block)
(:block/parent block))
sibling? (if (= (:db/id (:block/parent block)) (:db/id left-or-parent))
false sibling?)]
[left-or-parent sibling?])
sibling?
[block' sibling?]
sibling?
[block' sibling?]
start?
[block' false]
start?
[block' false]
end?
(if last-block
end?
(if last-block
[last-block true]
[block' false])
last-block
[last-block true]
[block' false])
last-block
[last-block true]
block
[block' sibling?]
block
[block' sibling?]
;; FIXME: assert
:else
nil)]
(when target-block
(p/do!
(let [new-block' (if (seq properties)
(into new-block properties)
new-block)]
(ui-outliner-tx/transact!
{:outliner-op :insert-blocks}
(outliner-insert-block! config target-block new-block'
{:sibling? sibling?
:keep-uuid? true
:ordered-list? ordered-list?
:outliner-op outliner-op
:replace-empty-target? replace-empty-target?})))
(when edit-block?
(if (and replace-empty-target?
(string/blank? (:block/title last-block)))
(edit-block! last-block :max)
(edit-block! new-block :max)))
(when-let [id (:block/uuid new-block)]
(db/entity [:block/uuid id])))))))))
:else
nil)]
(when target-block
(p/do!
(let [new-block' (if (seq properties)
(into new-block properties)
new-block)]
(ui-outliner-tx/transact!
{:outliner-op :insert-blocks}
(outliner-insert-block! config target-block new-block'
{:sibling? sibling?
:keep-uuid? true
:ordered-list? ordered-list?
:outliner-op outliner-op
:replace-empty-target? replace-empty-target?})))
(when edit-block?
(if (and replace-empty-target?
(string/blank? (:block/title last-block)))
(edit-block! last-block :max)
(edit-block! new-block :max)))
(when-let [id (:block/uuid new-block)]
(db/entity [:block/uuid id]))))))))))
(defn get-selected-blocks
[]
@@ -797,9 +799,12 @@
(defn move-blocks!
[blocks target opts]
(when (seq blocks)
(ui-outliner-tx/transact!
{:outliner-op :move-blocks}
(outliner-op/move-blocks! blocks target opts))))
(if (or (some ldb/recycled? blocks)
(ldb/recycled? target))
(notification/show! "Recycle is read-only." :warning)
(ui-outliner-tx/transact!
{:outliner-op :move-blocks}
(outliner-op/move-blocks! blocks target opts)))))
(defn move-selected-blocks
[e]
@@ -976,10 +981,11 @@
(let [repo (state/get-current-repo)
block-uuids (distinct (keep #(when-let [id (dom/attr % "blockid")] (uuid id)) dom-blocks))
lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
blocks (map db/entity lookup-refs)]
(ui-outliner-tx/transact!
{:outliner-op :delete-blocks}
(let [top-level-blocks (block-handler/get-top-level-blocks blocks)]
blocks (map db/entity lookup-refs)
top-level-blocks (block-handler/get-top-level-blocks blocks)]
(when-not (every? ldb/recycled? top-level-blocks)
(ui-outliner-tx/transact!
{:outliner-op :delete-blocks}
(when (seq top-level-blocks)
(let [sorted-blocks (mapcat (fn [block]
(tree/get-sorted-block-and-children repo (:db/id block)))
@@ -1831,6 +1837,14 @@
(let [ids (set (map :db/id blocks))]
(some? (some #(ids (:db/id (:block/parent %))) blocks))))
(defn- unrecycle-tx-data
[root]
[[:db/retract (:db/id root) :logseq.property/deleted-at]
[:db/retract (:db/id root) :logseq.property/deleted-by-ref]
[:db/retract (:db/id root) :logseq.property.recycle/original-parent]
[:db/retract (:db/id root) :logseq.property.recycle/original-page]
[:db/retract (:db/id root) :logseq.property.recycle/original-order]])
(defn paste-blocks
"Given a vec of blocks, insert them into the target page.
keep-uuid?: if true, keep the uuid provided in the block structure."
@@ -1865,6 +1879,13 @@
(or (ldb/get-left-sibling target-block)
(:block/parent (db/entity (:db/id target-block))))
target-block)
existing-blocks (keep (fn [block]
(when-let [id (:block/uuid block)]
(db/entity [:block/uuid id])))
blocks)
move-from-recycle? (and keep-uuid?
(seq existing-blocks)
(every? ldb/recycled? existing-blocks))
sibling? (cond
(and paste-nested-blocks? empty-target?)
(= (:block/parent target-block') (:block/parent target-block))
@@ -1877,20 +1898,32 @@
:else
true)
transact-blocks! #(ui-outliner-tx/transact!
{:outliner-op :insert-blocks
:additional-tx revert-cut-txs}
(when target-block'
(let [format (get target-block' :block/format :markdown)
repo (state/get-current-repo)
blocks' (map (fn [block]
(paste-block-cleanup repo block page exclude-properties format content-update-fn keep-uuid?))
blocks)]
(outliner-op/insert-blocks! blocks' target-block' {:sibling? sibling?
:outliner-op :paste
:outliner-real-op outliner-real-op
:replace-empty-target? replace-empty-target?
:keep-uuid? keep-uuid?}))))]
transact-blocks! #(if move-from-recycle?
(ui-outliner-tx/transact!
{:outliner-op :move-blocks
:additional-tx revert-cut-txs}
(when target-block'
(let [top-level-blocks (block-handler/get-top-level-blocks existing-blocks)
unrecycle-tx (mapcat unrecycle-tx-data top-level-blocks)]
(when (seq unrecycle-tx)
(outliner-op/transact! unrecycle-tx nil))
(outliner-op/move-blocks! top-level-blocks target-block'
{:sibling? sibling?
:outliner-op :paste}))))
(ui-outliner-tx/transact!
{:outliner-op :insert-blocks
:additional-tx revert-cut-txs}
(when target-block'
(let [format (get target-block' :block/format :markdown)
repo (state/get-current-repo)
blocks' (map (fn [block]
(paste-block-cleanup repo block page exclude-properties format content-update-fn keep-uuid?))
blocks)]
(outliner-op/insert-blocks! blocks' target-block' {:sibling? sibling?
:outliner-op :paste
:outliner-real-op outliner-real-op
:replace-empty-target? replace-empty-target?
:keep-uuid? keep-uuid?})))))]
(if ops-only?
(transact-blocks!)
(p/let [_ (when has-unsaved-edits
@@ -1950,51 +1983,26 @@
(insert-template! element-id db-id {}))
([element-id db-id {:keys [target] :as opts}]
(let [repo (state/get-current-repo)]
(p/let [block (db-async/<pull repo db-id)
block (when (:block/uuid block)
(db-async/<get-block repo (:block/uuid block)
{:children? true}))]
(p/let [block (db-async/<get-block repo db-id {:children? false})]
(when (:db/id block)
(let [journal? (ldb/journal? target)
target (or target (state/get-edit-block))
format (get block :block/format :markdown)
block-uuid (:block/uuid block)
blocks (db/get-block-and-children repo block-uuid {:include-property-block? true})
sorted-blocks (let [blocks' (rest blocks)]
(cons
(-> (first blocks')
(assoc :logseq.property/used-template (:db/id block)))
(rest blocks')))
blocks sorted-blocks]
format (get block :block/format :markdown)]
(when element-id
(insert-command! element-id "" format {:end-pattern commands/command-trigger}))
(let [sibling? (:sibling? opts)
sibling?' (cond
(some? sibling?)
sibling?
(try
(p/let [result (ui-outliner-tx/transact!
{:outliner-op :apply-template
:created-from-journal-template? journal?}
(when-not (string/blank? (state/get-edit-content))
(save-current-block!))
(outliner-op/apply-template! db-id target opts))]
(when result (edit-last-block-after-inserted! result)))
(db/has-children? (:block/uuid target))
false
:else
true)]
(when (seq blocks)
(try
(p/let [result (ui-outliner-tx/transact!
{:outliner-op :insert-blocks
:created-from-journal-template? journal?}
(when-not (string/blank? (state/get-edit-content))
(save-current-block!))
(outliner-op/insert-blocks! blocks target
(assoc opts
:sibling? sibling?'
:insert-template? true)))]
(when result (edit-last-block-after-inserted! result)))
(catch :default ^js/Error e
(notification/show!
(util/format "Template insert error: %s" (.-message e))
:error)))))))))))
(catch :default ^js/Error e
(notification/show!
(util/format "Template insert error: %s" (.-message e))
:error)))))))))
(defn template-on-chosen-handler
[element-id]
@@ -2063,7 +2071,7 @@
input (state/get-input)
config (assoc config :keydown-new-block true)
content (gobj/get input "value")
has-right? (ldb/get-right-sibling block)]
right-sibling (ldb/get-right-sibling block)]
(cond
(and (string/blank? content)
(own-order-number-list? block)
@@ -2073,12 +2081,12 @@
(and
(string/blank? content)
(not has-right?)
(not right-sibling)
(not (last-top-level-child? config block)))
(indent-outdent false)
:else
(insert-new-block! state)))))))
(insert-new-block! state right-sibling)))))))
(defn- inside-of-single-block
"When we are in a single block wrapper, we should always insert a new line instead of new block"
@@ -3074,8 +3082,7 @@
(:block/uuid page-entity)))
repo (state/get-current-repo)
_ (db-async/<get-block repo (or block-id page-id)
{:children? true
:include-collapsed-children? true})
{:include-collapsed-children? true})
entity (db/entity [:block/uuid (or block-id page-id)])
result (or (:block/_page entity)
(rest (db/get-block-and-children repo (:block/uuid entity))))
@@ -3151,8 +3158,7 @@
(defn expand-block! [block-id & {:keys [skip-db-collpsing?]}]
(let [repo (state/get-current-repo)]
(p/do!
(db-async/<get-block repo block-id {:children? true
:include-collapsed-children? true})
(db-async/<get-block repo block-id {:include-collapsed-children? true})
(when-not (or skip-db-collpsing? (skip-collapsing-in-db?))
(set-blocks-collapsed! [block-id] false))
(state/set-collapsed-block! block-id false))))
@@ -3492,9 +3498,9 @@
(ui-outliner-tx/transact!
{:outliner-op :save-block}
(property-handler/set-block-property! (:db/id block) :block/tags :logseq.class/Query)
(save-block-inner! block "" {})
(when query-block
(save-block-inner! query-block current-query {}))))))))
(save-block-inner! query-block current-query {}))
(save-block-inner! block "" {})))))))
(defn quick-add-ensure-new-block-exists!
[]

View File

@@ -3,7 +3,6 @@
[frontend.db :as db]
[frontend.handler.editor :as editor-handler]
[frontend.state :as state]
[frontend.undo-redo :as undo-redo]
[frontend.util :as util]
[goog.dom :as gdom]))
@@ -30,9 +29,12 @@
;; skip recording editor info when undo or redo is still running
(when-not (contains? #{:undo :redo} @(:editor/op @state/state))
(let [page-id (:block/uuid (:block/page (db/entity (:db/id (state/get-edit-block)))))
repo (state/get-current-repo)]
repo (state/get-current-repo)
editor-info (state/get-editor-info)]
(when page-id
(undo-redo/record-editor-info! repo (state/get-editor-info)))))
(state/<invoke-db-worker :thread-api/undo-redo-record-editor-info
repo
editor-info))))
(state/set-state! :editor/op nil))
state)

View File

@@ -56,6 +56,12 @@
(defmulti handle first)
(defonce ^:private *search-index-build-timeout (atom nil))
(def ^:private decrypt-aes-key-failed-notification
"Failed to decrypt this graph.")
(defn- decrypt-aes-key-failed?
[error]
(string/includes? (or (ex-message error) (str error)) "decrypt-aes-key"))
(defn- schedule-search-index-build!
[repo]
@@ -132,9 +138,10 @@
(page-handler/create-today-journal!)
(page-handler/<create! page-name opts)))
(defmethod handle :page/deleted [[_ page-name tx-meta]]
(when-not (util/mobile?)
(page-common-handler/after-page-deleted! page-name tx-meta)))
(defmethod handle :page/deleted [[_ page-name _tx-meta]]
(when page-name
(when-not (util/mobile?)
(page-common-handler/after-page-deleted! page-name))))
(defmethod handle :page/renamed [[_ repo data]]
(when-not (util/mobile?)
@@ -384,8 +391,8 @@
(println "RTC download graph failed, error:")
(log/error :rtc-download-graph-failed e)
(shui/popup-hide! :download-rtc-graph)
;; TODO: notify error
))))
(when (decrypt-aes-key-failed? e)
(notification/show! decrypt-aes-key-failed-notification :error false))))))
;; db-worker -> UI
(defmethod handle :db/sync-changes [[_ data]]

View File

@@ -1,8 +1,5 @@
(ns frontend.handler.export.common
"common fns for exporting.
exclude some fns which produce lazy-seq, which can cause strange behaviors
when use together with dynamic var."
(:refer-clojure :exclude [map filter mapcat concat remove])
"Common functions for exporting."
(:require [clojure.string :as string]
[frontend.db.conn :as conn]
[frontend.state :as state]

View File

@@ -1,6 +1,5 @@
(ns frontend.handler.export.opml
"export blocks/pages as opml"
(:refer-clojure :exclude [map filter mapcat concat remove newline])
(:require ["/frontend/utils" :as utils]
[clojure.string :as string]
[clojure.zip :as z]

View File

@@ -4,7 +4,6 @@
[frontend.handler.route :as route-handler]
[frontend.persist-db.browser :as db-browser]
[frontend.state :as state]
[frontend.undo-redo :as undo-redo]
[frontend.util :as util]
[goog.functions :refer [debounce]]
[logseq.db :as ldb]
@@ -12,12 +11,21 @@
(defn- restore-cursor!
[{:keys [editor-cursors block-content undo?]}]
(let [{:keys [block-uuid container-id start-pos end-pos]} (if undo? (first editor-cursors) (or (last editor-cursors) (first editor-cursors)))
(let [cursor (if undo?
(first editor-cursors)
(or (last editor-cursors) (first editor-cursors)))
{:keys [selected-block-uuids selection-direction block-uuid container-id start-pos end-pos]} cursor
selected-blocks (when (seq selected-block-uuids)
(->> selected-block-uuids
(mapcat util/get-blocks-by-id)
vec))
pos (if undo? (or start-pos end-pos) (or end-pos start-pos))]
(when-let [block (db/pull [:block/uuid block-uuid])]
(editor/edit-block! block pos
{:container-id container-id
:custom-content block-content}))))
(if (seq selected-blocks)
(state/exit-editing-and-set-selected-blocks! selected-blocks selection-direction)
(when-let [block (db/pull [:block/uuid block-uuid])]
(editor/edit-block! block pos
{:container-id container-id
:custom-content block-content})))))
(defn- restore-app-state!
[state]
@@ -52,7 +60,7 @@
(state/set-state! [:editor/last-replace-ref-content-tx repo] nil)
(editor/save-current-block!)
(state/clear-editor-action!)
(reset! *last-request (undo-redo/undo repo))
(reset! *last-request (state/<invoke-db-worker :thread-api/undo-redo-undo repo))
(p/let [result @*last-request]
(restore-cursor-and-state! result))))))))
(defonce undo! (debounce undo-aux! 20))
@@ -67,7 +75,7 @@
(when-let [repo (state/get-current-repo)]
(util/stop e)
(state/clear-editor-action!)
(reset! *last-request (undo-redo/redo repo))
(reset! *last-request (state/<invoke-db-worker :thread-api/undo-redo-redo repo))
(p/let [result @*last-request]
(restore-cursor-and-state! result)))))))
(defonce redo! (debounce redo-aux! 20))

View File

@@ -17,6 +17,7 @@
[frontend.handler.notification :as notification]
[frontend.handler.plugin :as plugin-handler]
[frontend.handler.property :as property-handler]
[frontend.handler.route :as route-handler]
[frontend.modules.outliner.op :as outliner-op]
[frontend.modules.outliner.ui :as ui-outliner-tx]
[frontend.state :as state]
@@ -31,11 +32,31 @@
[logseq.common.util.page-ref :as page-ref]
[logseq.db :as ldb]
[logseq.graph-parser.text :as text]
[logseq.outliner.recycle :as outliner-recycle]
[promesa.core :as p]))
(def <create! page-common-handler/<create!)
(def <delete! page-common-handler/<delete!)
(defn get-recycle-page
[]
(db/get-page common-config/recycle-page-name))
(defn open-recycle!
[]
(when-let [page (get-recycle-page)]
(route-handler/redirect-to-page! (:block/uuid page))))
(defn restore-recycled!
[root-uuid]
(when-let [root (db/entity [:block/uuid root-uuid])]
(when-let [tx-data (seq (outliner-recycle/restore-tx-data (db/get-db) root))]
(p/do!
(ui-outliner-tx/transact!
{:outliner-op :restore-recycled}
(outliner-op/transact! tx-data nil))
true))))
(defn <unfavorite-page!
[page-name]
(p/do!

View File

@@ -274,7 +274,7 @@
(notification/show!
(str
(if (= :error type) "[Error]" "")
(str "<" (:id payload) "> ")
"<" (:id payload) "> "
msg) type)))
(when-not fake-error?

View File

@@ -1,6 +1,5 @@
(ns frontend.handler.repo
"System-component-like ns that manages user's repos/graphs"
(:refer-clojure :exclude [clone])
(:require [clojure.string :as string]
[electron.ipc :as ipc]
[frontend.config :as config]
@@ -17,7 +16,6 @@
[frontend.persist-db :as persist-db]
[frontend.search :as search]
[frontend.state :as state]
[frontend.undo-redo :as undo-redo]
[frontend.util :as util]
[frontend.util.text :as text-util]
[logseq.db.frontend.schema :as db-schema]
@@ -52,10 +50,7 @@
(defn start-repo-db-if-not-exists!
[repo & {:as opts}]
(state/set-current-repo! repo)
(db/start-db-conn! repo (assoc opts
:db-graph? true
:listen-handler (fn [conn]
(undo-redo/listen-db-changes! repo conn)))))
(db/start-db-conn! repo (assoc opts :db-graph? true)))
(defn restore-and-setup-repo!
"Restore the db of a graph from the persisted data, and setup. Create a new

View File

@@ -81,6 +81,7 @@
(and (string? page-name) (not (string/blank? page-name))))
(let [page (db/get-page page-name)]
(if (and (not config/dev?)
(not= common-config/recycle-page-name (:block/title page))
(or (and (ldb/hidden? page) (not (ldb/property? page)))
(and (ldb/built-in? page) (ldb/private-built-in-page? page))))
(notification/show! "Cannot go to an internal page." :warning)

View File

@@ -238,6 +238,14 @@
(auto-fill-refresh-token-from-cognito!)
(state/pub-event! [:user/fetch-info-and-graphs]))
(defn- clear-e2ee-password!
[]
(when @state/*db-worker
(-> (state/<invoke-db-worker :thread-api/clear-e2ee-password)
(p/catch (fn [error]
(js/console.warn :clear-e2ee-password-failed error)
nil)))))
(defn ^:export login-with-username-password-e2e
[username' password client-id client-secret]
(let [text-encoder (new js/TextEncoder)
@@ -265,7 +273,9 @@
{:id-token id-token :access-token access-token :refresh-token refresh-token})))))
(defn logout []
(clear-e2ee-password!)
(clear-tokens)
(.clear js/localStorage)
(state/clear-user-info!)
(state/pub-event! [:user/logout])
(reset! flows/*current-login-user :logout))

View File

@@ -4,7 +4,6 @@
[clojure.string :as string]
[frontend.handler.notification :as notification]
[frontend.state :as state]
[frontend.undo-redo :as undo-redo]
[lambdaisland.glogi :as log]
[logseq.db :as ldb]))
@@ -30,9 +29,6 @@
(defmethod handle :sync-db-changes [_ _worker data]
(state/pub-event! [:db/sync-changes data]))
(defmethod handle :clear-undo-history [_ _worker [repo]]
(undo-redo/clear-history! repo))
(defmethod handle :rtc-log [_ _worker log]
(state/pub-event! [:rtc/log log]))