mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
Merge branch 'feat/db' into feat/capacitor-new
This commit is contained in:
4
.github/workflows/build-desktop-release.yml
vendored
4
.github/workflows/build-desktop-release.yml
vendored
@@ -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'
|
||||
|
||||
4
.github/workflows/clj-e2e.yml
vendored
4
.github/workflows/clj-e2e.yml
vendored
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
38
deps/db/src/logseq/db/common/entity_plus.cljc
vendored
38
deps/db/src/logseq/db/common/entity_plus.cljc
vendored
@@ -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)))))
|
||||
|
||||
54
deps/db/src/logseq/db/frontend/content.cljs
vendored
54
deps/db/src/logseq/db/frontend/content.cljs
vendored
@@ -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)))))))
|
||||
|
||||
29
deps/db/src/logseq/db/sqlite/export.cljs
vendored
29
deps/db/src/logseq/db/sqlite/export.cljs
vendored
@@ -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
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports = {
|
||||
packagerConfig: {
|
||||
name: 'Logseq',
|
||||
icon: './icons/logseq_big_sur.icns',
|
||||
buildVersion: "85",
|
||||
buildVersion: '87',
|
||||
protocols: [
|
||||
{
|
||||
"protocol": "logseq",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])))))]
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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})])))
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)))]
|
||||
|
||||
@@ -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 []
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user