Merge branch 'feat/db' into feat/capacitor-new

This commit is contained in:
charlie
2025-05-20 10:50:00 +08:00
30 changed files with 379 additions and 296 deletions

View File

@@ -43,8 +43,8 @@ on:
# type: boolean
# required: true
# default: true
schedule: # Every workday at the 2 P.M. (UTC) we run a scheduled nightly build
- cron: '0 14 * * MON-FRI'
# schedule: # Every workday at the 2 P.M. (UTC) we run a scheduled nightly build
# - cron: '0 14 * * MON-FRI'
env:
CLOJURE_VERSION: '1.11.1.1413'

View File

@@ -83,10 +83,10 @@ jobs:
ls -lR ./public
- name: Run e2e tests
run: cd clj-e2e && bb dev
run: cd clj-e2e && timeout 30m bb dev
env:
DEBUG: "pw:api"
- name: Collect screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v4

View File

@@ -10,7 +10,7 @@ android {
applicationId "com.logseq.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 84
versionCode 87
versionName "0.11.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {

View File

@@ -12,6 +12,7 @@
[logseq.e2e.plugins-basic-test]
[logseq.e2e.reference-basic-test]
[logseq.e2e.rtc-basic-test]
[logseq.e2e.rtc-extra-test]
[logseq.e2e.util :as util]
[wally.main :as w]
[wally.repl :as repl]))

View File

@@ -43,7 +43,7 @@
(k/enter)
(is (string/includes? (util/get-edit-content) "[["))
(util/exit-edit)
(is (= "b1" (util/get-text ".block-ref"))))))
(is (= "b1" (.textContent (second (w/query "a.page-ref"))))))))
(deftest link-test
(testing "/link"

View File

@@ -43,7 +43,7 @@
(b/wait-editor-text "b2")
(b/paste)
(util/exit-edit)
(b/assert-blocks-visible ["b1b2" "b2b1"])))
(b/assert-blocks-visible ["b1[[b2]]" "b2[[b1]]"])))
(deftest parent-reference
(testing "parent reference"
@@ -59,7 +59,7 @@
(b/wait-editor-text "b2")
(b/paste)
(util/exit-edit)
(b/assert-blocks-visible ["b1b2" "b2b1"])))
(b/assert-blocks-visible ["b1[[b2]]" "b2[[b1]]"])))
(deftest cycle-reference
(testing "cycle reference"
@@ -80,6 +80,6 @@
(assert/assert-editor-mode)
(b/paste)
(util/exit-edit)
(b/assert-blocks-visible ["b1b3b2" "b2b1b3" "b3b2b1"])))
(b/assert-blocks-visible ["b1[[b3[[b2]]]]" "b2[[b1[[b3]]]]" "b3[[b2[[b1]]]]"])))
;; TODO: page references

View File

@@ -1,8 +1,47 @@
(ns logseq.e2e.rtc-extra-test
(:require
[clojure.test :refer [deftest testing is use-fixtures]]))
[clojure.test :refer [deftest testing is use-fixtures run-tests]]
[com.climate.claypoole :as cp]
[logseq.e2e.fixtures :as fixtures :refer [*page1 *page2]]
[logseq.e2e.graph :as graph]
[logseq.e2e.util :as util]
[wally.main :as w]
[wally.repl :as repl]
[logseq.e2e.block :as b]))
(use-fixtures :once fixtures/open-2-pages)
(deftest name-test
(testing "Context of the test assertions"
(is true)))
(defn- offline
[offline?]
(.setOffline (.context (w/get-page)) offline?))
(defn- wait-for-ops-synced
[]
(w/wait-for "button.cloud.on.queuing" {:timeout 1000})
(w/wait-for "button.cloud.on.idle" {:timeout 5000}))
(deftest rtc-extra-test
(let [graph-name (str "rtc-extra-test-graph-" (.toEpochMilli (java.time.Instant/now)))]
(testing "open 2 app instances, add a rtc graph, check this graph available on other instance"
(cp/prun!
2
#(w/with-page %
(util/login-test-account))
[@*page1 @*page2])
(w/with-page @*page1
(graph/new-graph graph-name true))
(w/with-page @*page2
(graph/wait-for-remote-graph graph-name)
(graph/switch-graph graph-name true)))
(testing "rtc-stop app1, update app2, then rtc-start on app1"
(w/with-page @*page1
(offline true))
(w/with-page @*page2
(dotimes [_i 3]
(b/new-blocks (map #(str "b" %) (range 10)))
(wait-for-ops-synced))
;; TODO: more operations
(repl/pause)
)
)
))

View File

@@ -21,7 +21,7 @@
;; File graph only attributes. Can these be removed if this is only called in db graphs?
:block/pre-block? :block/scheduled :block/deadline :block/type :block/name :block/marker
:block.temp/ast-title :block.temp/search?
:block.temp/ast-title
:block.temp/fully-loaded? :block.temp/ast-body
:db/valueType :db/cardinality :db/ident :db/index
@@ -91,18 +91,16 @@
db-based? (db-based-graph? db)]
(if (and db-based? (entity-util/journal? e))
(get-journal-title db e)
(let [search? (get (.-kv e) :block.temp/search?)]
(or
(when-not (and search? (keyword-identical? k :block/title))
(get (.-kv e) k))
(let [result (lookup-entity e k default-value)
;; Replace title for pages only, otherwise it'll recursively
;; replace block id refs if there're cycle references of blocks
refs (:block/refs e)
result' (if (and (string? result) refs)
(db-content/id-ref->title-ref result refs search?)
result)]
(or result' default-value)))))))
(or
(get (.-kv e) k)
(let [result (lookup-entity e k default-value)
;; Replace title for pages only, otherwise it'll recursively
;; replace block id refs if there're cycle references of blocks
refs (:block/refs e)
result' (if (and (string? result) refs)
(db-content/id-ref->title-ref result refs)
result)]
(or result' default-value))))))
(defn- lookup-kv-with-default-value
[db ^Entity e k default-value]
@@ -162,12 +160,12 @@
;; cache :block/title
:block/title
(or (when-not (get (.-kv e) :block.temp/search?)
(:block.temp/cached-title @(.-cache e)))
(let [title (get-block-title e k default-value)]
(vreset! (.-cache e) (assoc @(.-cache e)
:block.temp/cached-title title))
title))
(or
(:block.temp/cached-title @(.-cache e))
(let [title (get-block-title e k default-value)]
(vreset! (.-cache e) (assoc @(.-cache e)
:block.temp/cached-title title))
title))
:block/_parent
(->> (lookup-entity e k default-value)
@@ -191,7 +189,7 @@
(let [v @(.-cache this)
v' (if (:block/title v)
(assoc v :block/title
(db-content/id-ref->title-ref (:block/title v) (:block/refs this) (:block.temp/search? this)))
(db-content/id-ref->title-ref (:block/title v) (:block/refs this)))
v)]
(concat (seq v')
(seq (.-kv this)))))

View File

@@ -4,8 +4,7 @@
[datascript.core :as d]
[logseq.common.util :as common-util]
[logseq.common.util.page-ref :as page-ref]
[logseq.db.common.entity-util :as common-entity-util]
[logseq.db.frontend.entity-util :as entity-util]))
[logseq.db.common.entity-util :as common-entity-util]))
;; [[uuid]]
(def id-ref-pattern
@@ -41,22 +40,25 @@
(defn id-ref->title-ref
"Convert id ref backs to page name refs using refs."
[content* refs* search?]
(let [refs (filter common-entity-util/page? refs*)
[content* refs* & {:keys [replace-block-id?]
:or {replace-block-id? false}}]
(let [refs (if replace-block-id?
;; The caller need to handle situations including
;; mutual references and circle references.
refs*
(filter common-entity-util/page? refs*))
content (str content*)]
(if (re-find id-ref-pattern content)
(reduce
(fn [content ref]
(if (:block/title ref)
(if (or (entity-util/page? ref) search?)
(let [content' (if (not (string/includes? (:block/title ref) " "))
(string/replace content
(str "#" (page-ref/->page-ref (:block/uuid ref)))
(str "#" (:block/title ref)))
content)]
(string/replace content' (page-ref/->page-ref (:block/uuid ref))
(page-ref/->page-ref (:block/title ref))))
content)
(let [content' (if (not (string/includes? (:block/title ref) " "))
(string/replace content
(str "#" (page-ref/->page-ref (:block/uuid ref)))
(str "#" (:block/title ref)))
content)]
(string/replace content' (page-ref/->page-ref (:block/uuid ref))
(page-ref/->page-ref (:block/title ref))))
content))
content
(sort-refs refs))
@@ -125,7 +127,7 @@
[db item eid]
(if-let [content (:block/title item)]
(let [refs (:block/refs (d/entity db eid))]
(assoc item :block/title (id-ref->title-ref content refs false)))
(assoc item :block/title (id-ref->title-ref content refs)))
item))
(defn replace-tags-with-id-refs
@@ -164,3 +166,27 @@
content
(sort-refs tags))
(string/trim)))
(defn recur-replace-uuid-in-block-title
"Convert id ref (recursively) backs to page name refs, returns replaced title"
([ent]
(recur-replace-uuid-in-block-title ent 10))
([ent max-depth]
(let [ref-set (loop [result-refs (:block/refs ent)
current-refs (:block/refs ent)
depth 0]
(if (or (>= depth max-depth) (empty? current-refs))
result-refs
(let [next-refs (set (mapcat :block/refs current-refs))
result-refs' (apply conj result-refs next-refs)]
(if (= (count result-refs') (count result-refs))
result-refs
(recur (apply conj result-refs next-refs) next-refs (inc depth))))))
opts {:replace-block-id? true}]
(loop [result (id-ref->title-ref (:block/title ent) ref-set opts)
last-result nil
depth 0]
(if (or (>= depth max-depth)
(= last-result result))
result
(recur (id-ref->title-ref result ref-set opts) result (inc depth)))))))

View File

@@ -814,18 +814,23 @@
(defn- patch-invalid-keywords
"Fixes invalids keywords whose name start with a number e.g. :user.property/2ndsomething"
[m]
(walk/postwalk
(fn [e]
(if (and (keyword? e) (some-> (namespace e) (string/starts-with? "user.")))
;; Copied from create-db-ident-from-name since this may be shortlived
(let [sanitized-kw (keyword (namespace e)
(->> (string/replace-first (name e) #"^(\d)" "NUM-$1")
(filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
(apply str)))]
;; (when (not= sanitized-kw e) (prn :sanitize e :-> sanitized-kw))
(if (not= sanitized-kw e) sanitized-kw e))
e))
m))
(let [initial-version (:kv/value (first (filter #(= :logseq.kv/graph-initial-schema-version (:db/ident %))
(::kv-values m))))]
;; Only ignore patch if initial version is > 64.8 since this fix started with 64.9
(if (some-> initial-version (db-schema/compare-schema-version {:major 64 :minor 8}) pos?)
m
(walk/postwalk
(fn [e]
(if (and (keyword? e) (some-> (namespace e) (string/starts-with? "user.")))
;; Copied from create-db-ident-from-name since this may be shortlived
(let [sanitized-kw (keyword (namespace e)
(->> (string/replace-first (name e) #"^(\d)" "NUM-$1")
(filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
(apply str)))]
;; (when (not= sanitized-kw e) (prn :sanitize e :-> sanitized-kw))
(if (not= sanitized-kw e) sanitized-kw e))
e))
m))))
(defn- ensure-export-is-valid
"Checks that export map is usable by sqlite.build including checking that

View File

@@ -5,7 +5,7 @@ module.exports = {
packagerConfig: {
name: 'Logseq',
icon: './icons/logseq_big_sur.icns',
buildVersion: "85",
buildVersion: '87',
protocols: [
{
"protocol": "logseq",

View File

@@ -58,7 +58,7 @@ $SED -i 's/defonce version ".*"/defonce version "'${NEW_VERSION}'"/g' src/main/f
$SED -i 's/"version": ".*"/"version": "'${NEW_VERSION}'"/g' resources/package.json
$SED -i 's/versionName ".*"/versionName "'${NEW_VERSION}'"/g' android/app/build.gradle
$SED -i 's/versionCode .*/versionCode '${NEW_VERSION_CODE}'/g' android/app/build.gradle
$SED -i 's/buildVersion: .*/buildVersion: '${NEW_VERSION_CODE}',/g' resources/forge.config.js
$SED -i 's/buildVersion: .*/buildVersion: "'${NEW_VERSION_CODE}'",/g' resources/forge.config.js
$SED -i 's/MARKETING_VERSION = .*;/MARKETING_VERSION = '${NEW_VERSION}';/g' ios/App/App.xcodeproj/project.pbxproj
git --no-pager diff -U0

View File

@@ -13,12 +13,12 @@
[frontend.handler.notification :as notification]
[frontend.handler.plugin :as plugin-handler]
[frontend.handler.property.file :as property-file]
[frontend.util.ref :as ref]
[frontend.search :as search]
[frontend.state :as state]
[frontend.util :as util]
[frontend.util.cursor :as cursor]
[frontend.util.file-based.priority :as priority]
[frontend.util.ref :as ref]
[goog.dom :as gdom]
[goog.object :as gobj]
[logseq.common.config :as common-config]
@@ -473,7 +473,7 @@
commands)
;; Allow user to modify or extend, should specify how to extend.
(state/get-commands)
(when-let [plugin-commands (seq (some->> (state/get-plugins-slash-commands)
(mapv #(vec (concat % [nil :icon/puzzle])))))]

View File

@@ -29,27 +29,6 @@
:else
content))
(defn- recur-replace-uuid-in-block-title
"Return block-title"
[ent max-depth]
(let [ref-set (loop [result-refs (:block/refs ent)
current-refs (:block/refs ent)
depth 0]
(if (or (>= depth max-depth) (empty? current-refs))
result-refs
(let [next-refs (set (mapcat :block/refs current-refs))
result-refs' (apply conj result-refs next-refs)]
(if (= (count result-refs') (count result-refs))
result-refs
(recur (apply conj result-refs next-refs) next-refs (inc depth))))))]
(loop [result (db-content/id-ref->title-ref (:block/title ent) ref-set true)
last-result nil
depth 0]
(if (or (>= depth max-depth)
(= last-result result))
result
(recur (db-content/id-ref->title-ref result ref-set true) result (inc depth))))))
(defn- transform-content
[repo db {:block/keys [collapsed? format pre-block? title page properties] :as b} level {:keys [heading-to-list?]} context]
(let [db-based? (sqlite-util/db-based-graph? repo)
@@ -60,7 +39,7 @@
markdown? (= :markdown format)
title (if db-based?
;; replace [[uuid]] with block's content
(recur-replace-uuid-in-block-title (d/entity db (:db/id b)) 10)
(db-content/recur-replace-uuid-in-block-title (d/entity db (:db/id b)))
title)
content (or title "")
page-first-child? (= (:db/id b) (ldb/get-first-child db (:db/id page)))

View File

@@ -656,7 +656,7 @@
All page-names are sanitized except page-name-in-block"
[state
{:keys [contents-page? whiteboard-page? html-export? other-position? show-unique-title? stop-click-event?
{:keys [contents-page? whiteboard-page? other-position? show-unique-title? stop-click-event?
on-context-menu]
:or {stop-click-event? true}
:as config}
@@ -705,12 +705,13 @@
(reset! *mouse-down? true))))
:on-pointer-up (fn [e]
(when @*mouse-down?
(util/stop e)
(state/clear-edit!)
(when-not (or (:disable-click? config)
(:disable-redirect? config))
(when-not (:disable-click? config)
(open-page-ref config page-entity e page-name contents-page?))
(reset! *mouse-down? false)))
:on-key-up (fn [e] (when (and e (= (.-key e) "Enter") (not other-position?))
(util/stop e)
(state/clear-edit!)
(open-page-ref config page-entity e page-name contents-page?)))}
on-context-menu
@@ -730,7 +731,7 @@
(last child)
(let [{:keys [content children]} (last child)
page-name (subs content 2 (- (count content) 2))]
(rum/with-key (page-reference html-export? page-name (assoc config :children children) nil) page-name))))
(rum/with-key (page-reference (assoc config :children children) page-name nil) page-name))))
(let [page-component (cond
(and label
(string? label)
@@ -945,26 +946,22 @@
config (assoc config :block entity)]
(cond
entity
(if (or (ldb/page? entity) (not (:block/page entity)))
(let [page-name (some-> (:block/title entity) util/page-name-sanity-lc)
whiteboard-page? (model/whiteboard-page? entity)
inner (page-inner (assoc config :whiteboard-page? whiteboard-page?) entity children label)
modal? (shui-dialog/has-modal?)]
(if (and (not (util/mobile?))
(not= page-name (:id config))
(not (false? preview?))
(not disable-preview?)
(not modal?))
(page-preview-trigger (assoc config :children inner) entity)
inner))
(block-reference config (:block/uuid entity)
(if (string? label)
(gp-mldoc/inline->edn label (mldoc/get-default-config :markdown))
label)))
(let [page-name (some-> (:block/title entity) util/page-name-sanity-lc)
whiteboard-page? (model/whiteboard-page? entity)
inner (page-inner (assoc config :whiteboard-page? whiteboard-page?) entity children label)
modal? (shui-dialog/has-modal?)]
(if (and (not (util/mobile?))
(not= page-name (:id config))
(not (false? preview?))
(not disable-preview?)
(not modal?))
(page-preview-trigger (assoc config :children inner) entity)
inner))
(and (:block/name page) show-non-exists-page?)
(page-inner config (merge
{:block/title (:block/name page)
{:block/title (or (:block/title page)
(:block/name page))
:block/name (:block/name page)}
page) children label)
@@ -979,8 +976,9 @@
(rum/defc page-cp
[config page]
(rum/with-key (page-cp-inner config page)
(or (str (:db/id page)) (str (:block/uuid page)) (:block/name page))))
(let [id (or (:db/id page) (:block/uuid page) (:block/name page))]
(rum/with-key (page-cp-inner config page)
(str id))))
(rum/defc asset-reference
[config title path]
@@ -1070,58 +1068,62 @@
(declare block-positioned-properties)
(rum/defc page-reference < rum/reactive db-mixins/query
"Component for page reference"
[html-export? uuid-or-title* {:keys [nested-link? show-brackets? id] :as config} label]
[{:keys [html-export? nested-link? show-brackets? id] :as config*} uuid-or-title* label]
(when uuid-or-title*
(let [uuid-or-title (if (string? uuid-or-title*)
(string/trim uuid-or-title*)
(let [str-id (string/trim uuid-or-title*)]
(if (util/uuid-string? str-id)
(parse-uuid str-id)
str-id))
uuid-or-title*)
show-brackets? (if (some? show-brackets?) show-brackets? (state/show-brackets?))
contents-page? (= "contents" (string/lower-case (str id)))
block* (db/get-page uuid-or-title)
block (or (some-> (:db/id block*) db/sub-block) block*)
config' (assoc config
:label (mldoc/plain->text label)
:contents-page? contents-page?
:show-icon? true?)
asset? (some? (:logseq.property.asset/type block))
page? (ldb/page? block)
brackets? (and (or show-brackets? nested-link?)
(not html-export?)
(not contents-page?)
page?)]
(when-not (= (:db/id block) (:db/id (:block config)))
(cond
(and asset? (img-audio-video? block))
(asset-cp config block)
self-reference? (when (set? (:ref-set config*))
(contains? (:ref-set config*) uuid-or-title))]
(when-not self-reference?
(let [config (update config* :ref-set (fn [s]
(let [bid (:block/uuid (:block config*))]
(if (nil? s)
#{bid}
(conj s bid uuid-or-title)))))
show-brackets? (if (some? show-brackets?) show-brackets? (state/show-brackets?))
contents-page? (= "contents" (string/lower-case (str id)))
block* (db/get-page uuid-or-title)
block (or (some-> (:db/id block*) db/sub-block) block*)
config' (assoc config
:label (mldoc/plain->text label)
:contents-page? contents-page?
:show-icon? true?)
asset? (some? (:logseq.property.asset/type block))
brackets? (and (or show-brackets? nested-link?)
(not html-export?)
(not contents-page?))]
(when-not (= (:db/id block) (:db/id (:block config)))
(cond
(and asset? (img-audio-video? block))
(asset-cp config block)
(or page? (:block/tags block))
[:span.page-reference
{:data-ref (str uuid-or-title)}
(when brackets?
[:span.text-gray-500.bracket page-ref/left-brackets])
(when (and (config/db-based-graph?) (ldb/class-instance? (db/entity :logseq.class/Task) block))
[:div.inline-block
{:style {:margin-right 1
:margin-top -2
:vertical-align "middle"}
:on-pointer-down (fn [e]
(util/stop e))}
(block-positioned-properties config block :block-left)])
(page-cp config' (if (uuid? uuid-or-title)
{:block/uuid uuid-or-title}
{:block/name uuid-or-title}))
(when brackets?
[:span.text-gray-500.bracket page-ref/right-brackets])]
(and (string? uuid-or-title) (string/ends-with? uuid-or-title ".excalidraw"))
[:div.draw {:on-click (fn [e]
(.stopPropagation e))}
(excalidraw uuid-or-title (:block/uuid config))]
(and (string? uuid-or-title) (string/ends-with? uuid-or-title ".excalidraw"))
[:div.draw {:on-click (fn [e]
(.stopPropagation e))}
(excalidraw uuid-or-title (:block/uuid config))]
:else
(page-cp config' (if (uuid? uuid-or-title)
{:block/uuid uuid-or-title}
{:block/name uuid-or-title})))))))
:else
[:span.page-reference
{:data-ref (str uuid-or-title)}
(when brackets?
[:span.text-gray-500.bracket page-ref/left-brackets])
(when (and (config/db-based-graph?) (ldb/class-instance? (db/entity :logseq.class/Task) block))
[:div.inline-block
{:style {:margin-right 1
:margin-top -2
:vertical-align "middle"}
:on-pointer-down (fn [e]
(util/stop e))}
(block-positioned-properties config block :block-left)])
(page-cp config' (if (uuid? uuid-or-title)
{:block/uuid uuid-or-title}
{:block/name uuid-or-title}))
(when brackets?
[:span.text-gray-500.bracket page-ref/right-brackets])])))))))
(defn- latex-environment-content
[name option content]
@@ -1342,13 +1344,18 @@
(set-block! block)))
[])
(when-not self-reference?
(if block
(cond
(config/db-based-graph?)
(page-reference config block-id label)
block
(let [config' (update config :ref-set (fn [s]
(let [bid (:block/uuid (:block config))]
(if (nil? s)
#{bid}
(conj s bid block-id)))))]
(block-reference-aux config' block label))
:else
(invalid-node-ref block-id)))))
(defn- render-macro
@@ -1477,7 +1484,7 @@
(block-reference config id label))
(not (string/includes? s "."))
(page-reference (:html-export? config) s config label)
(page-reference config s label)
(path/protocol-url? s)
(->elem :a {:href s
@@ -1509,9 +1516,9 @@
(map-inline config label)))
:else
(page-reference (:html-export? config) s config label)))
(page-reference config s label)))
(defn- link-cp [config html-export? link]
(defn- link-cp [config link]
(let [{:keys [url label title metadata full_text]} link]
(match url
["Block_ref" id]
@@ -1535,7 +1542,7 @@
(let [label* (if (seq (mldoc/plain->text label)) label nil)]
(if (and (string? page) (string/blank? page))
[:span (ref/->page-ref page)]
(page-reference (:html-export? config) page config label*)))))
(page-reference config page label*)))))
["Embed_data" src]
(image-link config url src nil metadata full_text)
@@ -1557,7 +1564,7 @@
block (db/entity [:block/uuid id])]
(if (:block/pre-block? block)
(let [page (:block/page block)]
(page-reference html-export? (:block/name page) config label))
(page-reference config (:block/name page) label))
(block-reference config (:link path) label)))
(= protocol "file")
@@ -1979,7 +1986,7 @@
(nested-link config html-export? link)
["Link" link]
(link-cp config html-export? link)
(link-cp config link)
[(:or "Verbatim" "Code") s]
[:code s]
@@ -2054,7 +2061,6 @@
selected? (contains? selected block-id)]
(when-not selected?
(util/clear-selection!)
(state/conj-selection-block! (gdom/getElement block-id) :down)
(editor-handler/highlight-block! uuid)))
(editor-handler/block->data-transfer! uuid event false)
@@ -2173,7 +2179,7 @@
(reset! *bullet-dragging? true)
(util/stop-propagation event)
(bullet-drag-start event block uuid block-id))
:on-drag-end (fn [_]
:on-drag-end (fn [_e]
(reset! *bullet-dragging? false))
:blockid (str uuid)
:class (str (when collapsed? "bullet-closed")
@@ -3193,7 +3199,6 @@
parents (if more? (take-last level-limit parents) parents)
config (assoc config
:breadcrumb? true
:disable-redirect? true
:disable-preview? true
:stop-click-event? false)]
(when show?

View File

@@ -13,7 +13,7 @@
(when (seq children)
[:ul
(for [child (sort-by :block/title children)]
(let [title [:li.ml-2 (block/page-reference false (:block/uuid child) {:show-brackets? false} nil)]]
(let [title [:li.ml-2 (block/page-reference {:show-brackets? false} (:block/uuid child) nil)]]
(if (seq (:logseq.property/_parent child))
(ui/foldable
title

View File

@@ -930,8 +930,9 @@
nil)
(defn- on-mouse-up
[_e]
(editor-handler/show-action-bar!))
[e]
(when-not (.closest (.-target e) ".block-control-wrap")
(editor-handler/show-action-bar!)))
(rum/defcs ^:large-vars/cleanup-todo root-container < rum/reactive
(mixins/event-mixin

View File

@@ -133,6 +133,20 @@
:other-attrs {:block/link (:db/id page')}}))))
(page-handler/on-chosen-handler input id pos format)))
(defn- matched-pages-with-new-page [partial-matched-pages db-tag? q]
(if (or (db/page-exists? q (if db-tag?
#{:logseq.class/Tag}
;; Page existence here should be the same as entity-util/page?.
;; Don't show 'New page' if a page has any of these tags
db-class/page-classes))
(and db-tag? (some ldb/class? (:block/_alias (db/get-page q)))))
partial-matched-pages
(if db-tag?
(concat [{:block/title (str (t :new-tag) " " q)}]
partial-matched-pages)
(cons {:block/title (str (t :new-page) " " q)}
partial-matched-pages))))
(rum/defc page-search-aux
[id format embed? db-tag? q current-pos input pos]
(let [db-based? (config/db-based-graph? (state/get-current-repo))
@@ -156,25 +170,11 @@
date/nlp-pages)
(take 10))))
;; reorder, shortest and starts-with first.
(let [matched-pages-with-new-page
(fn [partial-matched-pages]
(if (or (db/page-exists? q (if db-tag?
#{:logseq.class/Tag}
;; Page existence here should be the same as entity-util/page?.
;; Don't show 'New page' if a page has any of these tags
db-class/page-classes))
(and db-tag? (some ldb/class? (:block/_alias (db/get-page q)))))
partial-matched-pages
(if db-tag?
(concat [{:block/title (str (t :new-tag) " " q)}]
partial-matched-pages)
(cons {:block/title (str (t :new-page) " " q)}
partial-matched-pages))))]
(if (and (seq matched-pages)
(gstring/caseInsensitiveStartsWith (:block/title (first matched-pages)) q))
(cons (first matched-pages)
(matched-pages-with-new-page (rest matched-pages)))
(matched-pages-with-new-page matched-pages))))]
(if (and (seq matched-pages)
(gstring/caseInsensitiveStartsWith (:block/title (first matched-pages)) q))
(cons (first matched-pages)
(matched-pages-with-new-page (rest matched-pages) db-tag? q))
(matched-pages-with-new-page matched-pages db-tag? q)))]
[:<>
(ui/auto-complete
matched-pages'
@@ -183,7 +183,9 @@
(page-handler/page-not-exists-handler input id q current-pos))
:item-render (fn [block _chosen?]
(let [block' (if-let [id (:block/uuid block)]
(or (db/entity [:block/uuid id]) block)
(if-let [e (db/entity [:block/uuid id])]
(assoc e :block/title (:block/title block))
block)
block)]
[:div.flex.flex-col
(when (and (not (or db-tag? (:page? block) (ldb/page? block)))
@@ -218,10 +220,11 @@
(ui/icon "letter-n" {:size 14}))])
(let [title (if db-tag?
(let [target (first (:block/_alias block'))]
(let [target (first (:block/_alias block'))
title (:block/title block)]
(if (ldb/class? target)
(str (:block/title block') " -> alias: " (:block/title target))
(:block/title block')))
(str title " -> alias: " (:block/title target))
title))
(block-handler/block-unique-title block'))]
(search-handler/highlight-exact-query title q))]]))
:empty-placeholder [:div.text-gray-500.text-sm.px-4.py-2 (if db-tag?

View File

@@ -60,10 +60,7 @@
(when (and (string? page) page)
(let [full-page (->> (take (inc idx) namespace)
util/string-join-path)]
(block/page-reference false
full-page
{}
page))))
(block/page-reference {} full-page page))))
(interpose [:span.mx-2.opacity-30 "/"]))])]
{:default-collapsed? false
:title-trigger? true})])))

View File

@@ -33,6 +33,7 @@
[lambdaisland.glogi :as log]
[logseq.common.util.macro :as macro-util]
[logseq.db :as ldb]
[logseq.db.frontend.content :as db-content]
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.property :as db-property]
[logseq.db.frontend.property.type :as db-property-type]
@@ -748,7 +749,7 @@
id (:db/id node)
[header label] (if (integer? id)
(let [node-title (if (seq (:logseq.property/classes property))
(:block/title node)
(db-content/recur-replace-uuid-in-block-title node)
(block-handler/block-unique-title node))
title (subs node-title 0 256)
node (or (db/entity id) node)
@@ -1092,10 +1093,7 @@
(closed-value-item value opts)
(or (entity-util/page? value)
(and (seq (:block/tags value))
;; FIXME: page-cp should be renamed to node-cp and
;; support this case and maybe other complex cases.
(not (string/includes? (:block/title value) "[["))))
(seq (:block/tags value)))
(when value
(let [opts {:disable-preview? true
:tag? tag?

View File

@@ -38,10 +38,11 @@
(rum/defc block-cp < rum/reactive
[repo idx block]
(let [id (:block/uuid block)]
(page/page-cp {:parameters {:path {:name (str id)}}
:sidebar? true
:sidebar/idx idx
:repo repo})))
[:div.mt-2
(page/page-cp {:parameters {:path {:name (str id)}}
:sidebar? true
:sidebar/idx idx
:repo repo})]))
(defn get-scrollable-container
[]
@@ -68,77 +69,89 @@
:sidebar-key sidebar-key} repo block-id {:indent? false})]
(block-cp repo idx block)]))
(rum/defc search-title < rum/reactive
[*input]
(let [input (rum/react *input)
input' (if (string/blank? input) "Blank input" input)]
[:span.overflow-hidden.text-ellipsis input']))
(rum/defc sidebar-search
[repo block-type init-key input *input]
(rum/with-key
(cmdk/cmdk-block {:initial-input input
:sidebar? true
:on-input-change (fn [new-value]
(reset! *input new-value))
:on-input-blur (fn [new-value]
(state/sidebar-replace-block! [repo input block-type]
[repo new-value block-type]))})
(str init-key)))
(defn- <build-sidebar-item
[repo idx db-id block-type *db-id init-key]
(p/do!
(db-async/<get-block repo db-id)
(let [lookup (cond
(integer? db-id) db-id
(uuid? db-id) [:block/uuid db-id]
:else nil)
entity (when lookup (db/entity repo lookup))
page? (ldb/page? entity)
block-render (fn []
(when entity
(if page?
[[:.flex.items-center.page-title.gap-1
(icon/get-node-icon-cp entity {:class "text-md"})
[:span.overflow-hidden.text-ellipsis (:block/title entity)]]
(page-cp repo (str (:block/uuid entity)))]
(block-with-breadcrumb repo entity idx [repo db-id block-type] false))))]
(case (keyword block-type)
:contents
(when-let [page (db/get-page "Contents")]
[[:.flex.items-center (ui/icon "list-details" {:class "text-md mr-2"}) (t :right-side-bar/contents)]
(page-cp repo (str (:block/uuid page)))])
(->
(p/do!
(when-not (contains? #{:contents :search} block-type)
(db-async/<get-block repo db-id))
(let [lookup (cond
(integer? db-id) db-id
(uuid? db-id) [:block/uuid db-id]
:else nil)
entity (when lookup (db/entity repo lookup))
page? (ldb/page? entity)
block-render (fn []
(when entity
(if page?
[[:.flex.items-center.page-title.gap-1
(icon/get-node-icon-cp entity {:class "text-md"})
[:span.overflow-hidden.text-ellipsis (:block/title entity)]]
(page-cp repo (str (:block/uuid entity)))]
(block-with-breadcrumb repo entity idx [repo db-id block-type] false))))]
(case (keyword block-type)
:contents
(when-let [page (db/get-page "Contents")]
[[:.flex.items-center (ui/icon "list-details" {:class "text-md mr-2"}) (t :right-side-bar/contents)]
(page-cp repo (str (:block/uuid page)))])
:help
[[:.flex.items-center (ui/icon "help" {:class "text-md mr-2"}) (t :right-side-bar/help)] (onboarding/help)]
:help
[[:.flex.items-center (ui/icon "help" {:class "text-md mr-2"}) (t :right-side-bar/help)] (onboarding/help)]
:page-graph
[[:.flex.items-center (ui/icon "hierarchy" {:class "text-md mr-2"}) (t :right-side-bar/page-graph)]
(page/page-graph)]
:page-graph
[[:.flex.items-center (ui/icon "hierarchy" {:class "text-md mr-2"}) (t :right-side-bar/page-graph)]
(page/page-graph)]
:block-ref
(let [lookup (if (integer? db-id) db-id [:block/uuid db-id])]
(when-let [block (db/entity repo lookup)]
[(t :right-side-bar/block-ref)
(block-with-breadcrumb repo block idx [repo db-id block-type] true)]))
:block-ref
(let [lookup (if (integer? db-id) db-id [:block/uuid db-id])]
(when-let [block (db/entity repo lookup)]
[(t :right-side-bar/block-ref)
(block-with-breadcrumb repo block idx [repo db-id block-type] true)]))
:block
(block-render)
:block
(block-render)
:page
(block-render)
:page
(block-render)
:search
[[:.flex.items-center.page-title
(ui/icon "search" {:class "text-md mr-2"})
(let [input (rum/react *db-id)
input' (if (string/blank? input) "Blank input" input)]
[:span.overflow-hidden.text-ellipsis input'])]
(rum/with-key
(cmdk/cmdk-block {:initial-input db-id
:sidebar? true
:on-input-change (fn [new-value]
(reset! *db-id new-value))
:on-input-blur (fn [new-value]
(state/sidebar-replace-block! [repo db-id block-type]
[repo new-value block-type]))})
(str init-key))]
:search
[[:.flex.items-center.page-title
(ui/icon "search" {:class "text-md mr-2"})
(search-title *db-id)]
(sidebar-search repo block-type init-key db-id *db-id)]
:shortcut-settings
[[:.flex.items-center (ui/icon "command" {:class "text-md mr-2"}) (t :help/shortcuts)]
(shortcut-settings)]
:rtc
[[:.flex.items-center (ui/icon "cloud" {:class "text-md mr-2"}) "(Dev) RTC"]
(rtc-debug-ui/rtc-debug-ui)]
:shortcut-settings
[[:.flex.items-center (ui/icon "command" {:class "text-md mr-2"}) (t :help/shortcuts)]
(shortcut-settings)]
:rtc
[[:.flex.items-center (ui/icon "cloud" {:class "text-md mr-2"}) "(Dev) RTC"]
(rtc-debug-ui/rtc-debug-ui)]
:profiler
[[:.flex.items-center (ui/icon "cloud" {:class "text-md mr-2"}) "(Dev) Profiler"]
(profiler/profiler)]
:profiler
[[:.flex.items-center (ui/icon "cloud" {:class "text-md mr-2"}) "(Dev) Profiler"]
(profiler/profiler)]
["" [:span]]))))
["" [:span]])))
(p/catch (fn [error]
(js/console.error error)))))
(defonce *drag-to
(atom nil))

View File

@@ -99,7 +99,7 @@ independent of format as format specific heading characters are stripped"
(let [block (db-utils/entity repo block-id)
ref-tags (distinct (concat (:block/tags block) (:block/refs block)))]
(= (-> block-content
(db-content/id-ref->title-ref ref-tags true)
(db-content/id-ref->title-ref ref-tags)
(db-content/content-id-ref->page ref-tags)
heading-content->route-name)
(string/lower-case external-content))))

View File

@@ -35,7 +35,6 @@
[frontend.modules.outliner.op :as outliner-op]
[frontend.modules.outliner.tree :as tree]
[frontend.modules.outliner.ui :as ui-outliner-tx]
[frontend.util.ref :as ref]
[frontend.search :as search]
[frontend.state :as state]
[frontend.template :as template]
@@ -44,6 +43,7 @@
[frontend.util.file-based.drawer :as drawer]
[frontend.util.keycode :as keycode]
[frontend.util.list :as list]
[frontend.util.ref :as ref]
[frontend.util.text :as text-util]
[frontend.util.thingatpt :as thingatpt]
[goog.dom :as gdom]
@@ -1249,8 +1249,10 @@
(when-let [timeout @*action-bar-timeout]
(js/clearTimeout timeout))
(state/pub-event! [:editor/hide-action-bar])
(let [timeout (js/setTimeout #(state/pub-event! [:editor/show-action-bar]) delay)]
(reset! *action-bar-timeout timeout))))
(when (seq (state/get-selection-blocks))
(let [timeout (js/setTimeout #(state/pub-event! [:editor/show-action-bar]) delay)]
(reset! *action-bar-timeout timeout)))))
(defn- select-block-up-down
[direction]

View File

@@ -269,7 +269,7 @@
;; ask user to choose a folder again when access expires
(p/let [handle (try
(idb/get-item (str "handle/" (js/btoa repo) "/" backup-folder))
(catch :defult _e
(catch :default _e
(throw (ex-info "Backup file handle no longer exists" {:repo repo}))))
[_folder handle] (try
(utils/verifyPermission handle true)

View File

@@ -84,7 +84,7 @@
(let [page (db/get-page page-name)
whiteboard? (db/whiteboard-page? page)]
(if (and (not config/dev?)
(or (ldb/hidden? 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)
(if-let [source (and (not ignore-alias?) (db/get-alias-source-page (state/get-current-repo) (:db/id page)))]

View File

@@ -594,7 +594,8 @@
:fn commit/show-commit-modal!}
:dev/fix-broken-graph {:binding []
:inactive (not (config/db-based-graph? (state/get-current-repo)))
:inactive (not (state/developer-mode?))
:db-graph? true
:fn #(repo-handler/fix-broken-graph! (state/get-current-repo))}
:dev/replace-graph-with-db-file {:binding []

View File

@@ -19,7 +19,7 @@
result (state/<invoke-db-worker :thread-api/search-build-blocks-indice repo)
blocks (if file-based?
(->> result
;; remove built-in properties from content
;; remove built-in properties from content
(map
#(update % :content
(fn [content]

View File

@@ -1877,7 +1877,7 @@ Similar to re-frame subscriptions"
(if (and page
;; TODO: Use config/dev? when it's not a circular dep
(not goog.DEBUG)
(or (ldb/hidden? page)
(or (and (ldb/hidden? page) (not (ldb/property? page)))
(and (ldb/built-in? page) (ldb/private-built-in-page? page))))
(pub-event! [:notification/show {:content "Cannot open an internal page." :status :warning}])
(when db-id

View File

@@ -188,6 +188,21 @@
:db-schema-version (str version-in-db)}}))))
missing-addresses))
(def get-to-delete-unused-addresses-sql
"WITH to_delete(addr) AS (
SELECT value
FROM json_each(?)
),
referenced(addr) AS (
SELECT json_each.value
FROM kvs
JOIN json_each(kvs.addresses)
WHERE kvs.addr NOT IN (SELECT addr FROM to_delete)
AND json_each.value IN (SELECT addr FROM to_delete)
)
SELECT addr FROM to_delete
WHERE addr NOT IN (SELECT addr FROM referenced)")
(defn upsert-addr-content!
"Upsert addr+data-seq. Update sqlite-cli/upsert-addr-content! when making changes"
[db data delete-addrs*]
@@ -198,19 +213,19 @@
(.exec tx #js {:sql "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses"
:bind item}))))
(when (seq delete-addrs)
(.transaction db (fn [tx]
(doseq [addr delete-addrs]
(.exec tx #js {:sql "Delete from kvs WHERE addr = ? AND NOT EXISTS (SELECT 1 FROM json_each(addresses) WHERE value = ?);"
:bind #js [addr]}))))
(let [result (.exec db #js {:sql get-to-delete-unused-addresses-sql
:bind (js/JSON.stringify (clj->js delete-addrs))
:rowMode "array"})
non-refed-addrs (map #(aget % 0) result)]
(when (seq non-refed-addrs)
(.transaction db (fn [tx]
(doseq [addr non-refed-addrs]
(.exec tx #js {:sql "Delete from kvs where addr = ?"
:bind #js [addr]}))))))
(let [missing-addrs (when worker-util/dev?
(seq (find-missing-addresses nil db {:delete-addrs delete-addrs})))]
(if (seq missing-addrs)
(worker-util/post-message :notification [(str "Bug!! Missing addresses: " missing-addrs) :error false])
(when (seq delete-addrs)
(.transaction db (fn [tx]
(doseq [addr delete-addrs]
(.exec tx #js {:sql "Delete from kvs WHERE addr = ? AND NOT EXISTS (SELECT 1 FROM json_each(addresses) WHERE value = ?);"
:bind #js [addr]}))))))))))
(when (seq missing-addrs)
(worker-util/post-message :notification [(str "Bug!! Missing addresses: " missing-addrs) :error false]))))))
(defn restore-data-from-addr
"Update sqlite-cli/restore-data-from-addr when making changes"

View File

@@ -10,6 +10,7 @@
[logseq.common.util :as common-util]
[logseq.common.util.namespace :as ns-util]
[logseq.db :as ldb]
[logseq.db.frontend.content :as db-content]
[logseq.db.sqlite.util :as sqlite-util]
[logseq.graph-parser.text :as text]))
@@ -193,7 +194,8 @@ DROP TRIGGER IF EXISTS blocks_au;
(defn- page-or-object?
[entity]
(and (or (ldb/page? entity) (ldb/object? entity))
(not (ldb/hidden? entity))))
(not (ldb/hidden? entity))
(not (ldb/hidden? (:block/page entity)))))
(defn get-all-fuzzy-supported-blocks
"Only pages and objects are supported now."
@@ -205,7 +207,9 @@ DROP TRIGGER IF EXISTS blocks_au;
(map :e)))
blocks (->> (distinct (concat page-ids object-ids))
(map #(d/entity db %)))]
(remove ldb/hidden? blocks)))
(->> blocks
(remove ldb/hidden?)
(remove #(ldb/hidden? (:block/page %))))))
(defn- sanitize
[content]
@@ -219,13 +223,9 @@ DROP TRIGGER IF EXISTS blocks_au;
(ldb/closed-value? block)
(and (string? title) (> (count title) 10000))
(string/blank? title)) ; empty page or block
;; Should properties be included in the search indice?
;; It could slow down the search indexing, also it can be confusing
;; if the showing properties are not useful to users.
;; (let [content (if (and db-based? (seq (:block/properties block)))
;; (str content (when (not= content "") "\n") (get-db-properties-str db properties))
;; content)])
(let [title (ldb/get-title-with-parents (assoc block :block.temp/search? true))]
(let [title (-> block
(update :block/title ldb/get-title-with-parents)
db-content/recur-replace-uuid-in-block-title)]
(when uuid
{:id (str uuid)
:page (str (or (:block/uuid page) uuid))
@@ -370,11 +370,11 @@ DROP TRIGGER IF EXISTS blocks_au;
set)
blocks-to-add-set)]
{:blocks-to-remove (->>
(keep #(d/entity db-before %) blocks-to-remove-set)
(remove ldb/hidden?))
(keep #(d/entity db-before %) blocks-to-remove-set))
:blocks-to-add (->>
(keep #(d/entity db-after %) blocks-to-add-set')
(remove ldb/hidden?))})))
(remove ldb/hidden?)
(remove #(ldb/hidden? (:block/page %))))})))
(defn- get-affected-blocks
[repo tx-report]