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

This commit is contained in:
charlie
2025-04-18 08:51:18 +08:00
11 changed files with 192 additions and 134 deletions

View File

@@ -330,9 +330,7 @@
views
all-files
pages-datoms))]
(prn :debug "db-graph?" db-graph?)
(prn :debug "block/journal-day schema" (str (:block/journal-day (:schema db))))
{:schema (assoc schema :block/journal-day {:db/index true})
{:schema schema
:initial-data data}))
(defn restore-initial-data

View File

@@ -45,7 +45,8 @@
;; for pages
:block/alias {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}
:db/cardinality :db.cardinality/many
:db/index true}
;; todo keywords, e.g. "TODO", "DOING", "DONE"
:block/marker {}

View File

@@ -241,19 +241,16 @@
(if db-based?
(db-based-statuses)
(file-based-statuses))
(mapv (fn [m]
(let [command (if db-based?
[:div.flex.flex-row.items-center.gap-2 m [:div.text-xs.opacity-50 "Status"]]
m)
icon (if db-based?
(case m
(mapv (fn [command]
(let [icon (if db-based?
(case command
"Canceled" "Cancelled"
"Doing" "InProgress50"
m)
command)
"square-asterisk")]
[command (->marker m) (str "Set status to " m) icon]))))]
[command (->marker command) (str "Set status to " command) icon]))))]
(when (seq result)
(map (fn [v] (conj v "TASK")) result))))
(map (fn [v] (conj v "TASK STATUS")) result))))
(defn file-based-priorities
[]
@@ -273,17 +270,17 @@
(db-based-priorities)
(file-based-priorities))
(mapv (fn [item]
(let [command (if db-based?
[:div.flex.flex-row.items-center.gap-2 item [:div.text-xs.opacity-50 "Priority"]]
item)]
[command (->priority item) (str "Set priority to " item)
(let [command item]
[command
(->priority item)
(str "Set priority to " item)
(if db-based?
(str "priorityLvl" item)
(str "circle-letter-" (util/safe-lower-case item)))])))
(with-no-priority)
(vec))]
(when (seq result)
(map (fn [v] (conj v "PRIORITY")) result))))
(map (fn [v] (into v ["PRIORITY"])) result))))
;; Credits to roamresearch.com
@@ -297,8 +294,9 @@
[]
(mapv (fn [level]
(let [heading (str "Heading " level)]
[heading (->heading level) heading (str "h-" level)])) (range 1 7)))
[heading (->heading level) heading (str "h-" level) "Heading"])) (range 1 7)))
(defonce *latest-matched-command (atom ""))
(defonce *matched-commands (atom nil))
(defonce *initial-commands (atom nil))
@@ -474,12 +472,18 @@
(defn init-commands!
[get-page-ref-text]
(let [commands (commands-map get-page-ref-text)]
(reset! *latest-matched-command "")
(reset! *initial-commands commands)
(reset! *matched-commands commands)))
(defn set-matched-commands!
[command matched-commands]
(reset! *latest-matched-command command)
(reset! *matched-commands matched-commands))
(defn reinit-matched-commands!
[]
(reset! *matched-commands @*initial-commands))
(set-matched-commands! "" @*initial-commands))
(defn restore-state
[]

View File

@@ -1068,7 +1068,7 @@
(contains? config/video-formats asset-type))))
(declare block-positioned-properties)
(rum/defc page-reference < rum/reactive
(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]
(when uuid-or-title*
@@ -1077,7 +1077,8 @@
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* (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?

View File

@@ -38,6 +38,8 @@
[react-draggable]
[rum.core :as rum]))
(defonce no-matched-commands [["No matched commands" [[:editor/move-cursor-to-end]]]])
(defn filter-commands
[page? commands]
(if page?
@@ -45,7 +47,7 @@
(or
(= "Add new property" (first item))
(when (= (count item) 5)
(contains? #{"TASK" "PRIORITY"} (last item))))) commands)
(contains? #{"TASK STATUS" "PRIORITY"} (last item))))) commands)
commands))
(rum/defcs commands < rum/reactive
@@ -56,57 +58,59 @@
_ (when (state/get-editor-action)
(reset! *matched matched'))
page? (db/page? (db/entity (:db/id (state/get-edit-block))))
matched (filter-commands page? @*matched)]
matched (or (filter-commands page? @*matched) no-matched-commands)
filtered? (not= matched @commands/*initial-commands)]
(ui/auto-complete
matched
{:get-group-name
(fn [item]
(when (= (count item) 5) (last item)))
(cond->
{:item-render
(fn [item]
(let [command-name (first item)
command-doc (get item 2)
plugin-id (get-in item [1 1 1 :pid])
doc (when (state/show-command-doc?) command-doc)
options (some-> item (get 3))
icon-name (some-> (if (map? options) (:icon options) options) (name))
command-name (if icon-name
[:span.flex.items-center.gap-1
(shui/tabler-icon icon-name)
[:strong.font-normal command-name]]
command-name)]
(cond
(or plugin-id (vector? doc))
[:div.has-help
{:title plugin-id}
command-name
(when doc (ui/tooltip [:small (svg/help-circle)] doc))]
:item-render
(fn [item]
(let [command-name (first item)
command-doc (get item 2)
plugin-id (get-in item [1 1 1 :pid])
doc (when (state/show-command-doc?) command-doc)
options (some-> item (get 3))
icon-name (some-> (if (map? options) (:icon options) options) (name))
command-name (if icon-name
[:span.flex.items-center.gap-1
(shui/tabler-icon icon-name)
[:strong.font-normal command-name]]
command-name)]
(cond
(or plugin-id (vector? doc))
[:div.has-help
{:title plugin-id}
command-name
(when doc (ui/tooltip [:small (svg/help-circle)] doc))]
(string? doc)
[:div {:title doc}
command-name]
(string? doc)
[:div {:title doc}
command-name]
:else
[:div command-name])))
:else
[:div command-name])))
:on-chosen
(fn [chosen-item]
(let [command (first chosen-item)]
(reset! commands/*current-command command)
(let [command-steps (get (into {} matched) command)
restore-slash? (or
(contains? #{"Today" "Yesterday" "Tomorrow" "Current time"} command)
(and
(not (fn? command-steps))
(not (contains? (set (map first command-steps)) :editor/input))
(not (contains? #{"Date picker" "Template" "Deadline" "Scheduled" "Upload an image"} command))))]
(editor-handler/insert-command! id command-steps
format
{:restore? restore-slash?
:command command}))))
:class
"cp__commands-slash"})))
:on-chosen
(fn [chosen-item]
(let [command (first chosen-item)]
(reset! commands/*current-command command)
(let [command-steps (get (into {} matched) command)
restore-slash? (or
(contains? #{"Today" "Yesterday" "Tomorrow" "Current time"} command)
(and
(not (fn? command-steps))
(not (contains? (set (map first command-steps)) :editor/input))
(not (contains? #{"Date picker" "Template" "Deadline" "Scheduled" "Upload an image"} command))))]
(editor-handler/insert-command! id command-steps
format
{:restore? restore-slash?
:command command}))))
:class
"cp__commands-slash"}
(not filtered?)
(assoc :get-group-name
(fn [item]
(when (= (count item) 5) (last item))))))))
(defn- page-on-chosen-handler
[embed? input id q pos format]

View File

@@ -818,7 +818,7 @@
concat-prev-block?
(let [children (:block/_parent (db/entity (:db/id block)))
db-based? (config/db-based-graph? repo)
prev-block-is-not-parent? (not= (:block/uuid (:block/parent block)) (:block/uuid prev-block))
prev-block-is-not-parent? (empty? (:block/_parent prev-block))
delete-prev-block? (and db-based?
prev-block-is-not-parent?
(empty? (:block/tags block))
@@ -1773,23 +1773,25 @@
[property q]
(search/property-value-search property q))
(defn get-matched-commands
(defn get-last-command
[input]
(try
(let [edit-content (or (gobj/get input "value") "")
pos (cursor/pos input)
last-slash-caret-pos (:pos (:pos (state/get-editor-action-data)))
last-command (and last-slash-caret-pos (subs edit-content last-slash-caret-pos pos))]
(when (> pos 0)
(or
(and (= commands/command-trigger (util/nth-safe edit-content (dec pos)))
@commands/*initial-commands)
(and last-command
(commands/get-matched-commands last-command)))))
(when (> pos 0) last-command))
(catch :default e
(js/console.error e)
nil)))
(defn get-matched-commands
[command]
(condp = command
nil nil
"" @commands/*initial-commands
(commands/get-matched-commands command)))
(defn auto-complete?
[]
(or @*asset-uploading?
@@ -1929,9 +1931,9 @@
(defn resize-image!
[config block-id metadata full_text size]
(let [asset (:asset-block config)]
(if (and asset (config/db-based-graph?))
(if (config/db-based-graph?)
(property-handler/set-block-property! (state/get-current-repo)
(:db/id asset)
(if asset (:db/id asset) block-id)
:logseq.property.asset/resize-metadata
size)
(let [new-meta (merge metadata size)
@@ -3206,10 +3208,13 @@
(and (= :commands (state/get-editor-action)) (not= k commands/command-trigger))
(if (= commands/command-trigger (second (re-find #"(\S+)\s+$" value)))
(state/clear-editor-action!)
(let [matched-commands (get-matched-commands input)]
(let [command (get-last-command input)
matched-commands (get-matched-commands command)]
(if (seq matched-commands)
(reset! commands/*matched-commands matched-commands)
(state/clear-editor-action!))))
(commands/set-matched-commands! command matched-commands)
(if (> (- (count command) (count @commands/*latest-matched-command)) 2)
(state/clear-editor-action!)
(reset! commands/*matched-commands nil)))))
:else
(default-case-for-keyup-handler input current-pos k code is-processed?))

View File

@@ -1,7 +1,10 @@
(ns frontend.handler.events.ui
"UI events"
(:require [frontend.components.block :as block]
(:require [clojure.core.async :as async]
[clojure.core.async.interop :refer [p->c]]
[frontend.components.block :as block]
[frontend.components.cmdk.core :as cmdk]
[frontend.components.file-sync :as file-sync]
[frontend.components.page :as component-page]
[frontend.components.plugins :as plugin]
[frontend.components.property.dialog :as property-dialog]
@@ -20,6 +23,7 @@
[frontend.fs.capacitor-fs :as capacitor-fs]
[frontend.fs.nfs :as nfs]
[frontend.fs.sync :as sync]
[frontend.handler.db-based.rtc :as rtc-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.events :as events]
[frontend.handler.file-based.nfs :as nfs-handler]
@@ -27,8 +31,11 @@
[frontend.handler.notification :as notification]
[frontend.handler.page :as page-handler]
[frontend.handler.plugin :as plugin-handler]
[frontend.handler.repo :as repo-handler]
[frontend.handler.route :as route-handler]
[frontend.handler.user :as user-handler]
[frontend.mobile.util :as mobile-util]
[frontend.modules.instrumentation.sentry :as sentry-event]
[frontend.state :as state]
[frontend.ui :as ui]
[frontend.util :as util]
@@ -352,3 +359,44 @@
(merge {:close-btn? false
:center? true
:close-backdrop? false} opts)))
(defn- enable-beta-features!
[]
(when-not (false? (state/enable-sync?)) ; user turns it off
(file-sync-handler/set-sync-enabled! true)))
;; TODO: separate rtc and file-based implementation
(defmethod events/handle :user/fetch-info-and-graphs [[_]]
(state/set-state! [:ui/loading? :login] false)
(async/go
(let [result (async/<! (sync/<user-info sync/remoteapi))]
(cond
(instance? ExceptionInfo result)
nil
(map? result)
(do
(state/set-user-info! result)
(when-let [uid (user-handler/user-uuid)]
(sentry-event/set-user! uid))
(let [status (if (user-handler/alpha-or-beta-user?) :welcome :unavailable)]
(when (and (= status :welcome) (user-handler/logged-in?))
(enable-beta-features!)
(async/<! (p->c (rtc-handler/<get-remote-graphs)))
(async/<! (file-sync-handler/load-session-graphs))
(p/let [repos (repo-handler/refresh-repos!)]
(when-let [repo (state/get-current-repo)]
(when (some #(and (= (:url %) repo)
(vector? (:sync-meta %))
(util/uuid-string? (first (:sync-meta %)))
(util/uuid-string? (second (:sync-meta %)))) repos)
(sync/<sync-start)))))
(file-sync/maybe-onboarding-show status)))))))
(defmethod events/handle :file-sync/onboarding-tip [[_ type opts]]
(let [type (keyword type)]
(when-not (config/db-based-graph? (state/get-current-repo))
(shui/dialog-open!
(file-sync/make-onboarding-panel type)
(merge {:close-btn? false
:center? true
:close-backdrop? (not= type :welcome)} opts)))))

View File

@@ -1,7 +1,6 @@
(ns frontend.handler.file-based.events
"Events that are only for file graphs"
(:require [clojure.core.async :as async]
[clojure.core.async.interop :refer [p->c]]
[clojure.set :as set]
[clojure.string :as string]
[frontend.components.diff :as diff]
@@ -14,7 +13,6 @@
[frontend.fs :as fs]
[frontend.fs.sync :as sync]
[frontend.handler.common :as common-handler]
[frontend.handler.db-based.rtc :as rtc-handler]
[frontend.handler.events :as events]
[frontend.handler.file-based.file :as file-handler]
[frontend.handler.file-based.nfs :as nfs-handler]
@@ -28,7 +26,6 @@
[frontend.handler.user :as user-handler]
[frontend.mobile.graph-picker :as graph-picker]
[frontend.mobile.util :as mobile-util]
[frontend.modules.instrumentation.sentry :as sentry-event]
[frontend.modules.shortcut.core :as st]
[frontend.state :as state]
[frontend.ui :as ui]
@@ -164,37 +161,6 @@
opts))
{:center? true :close-btn? false :close-backdrop? false}))
(defn- enable-beta-features!
[]
(when-not (false? (state/enable-sync?)) ; user turns it off
(file-sync-handler/set-sync-enabled! true)))
(defmethod events/handle :user/fetch-info-and-graphs [[_]]
(state/set-state! [:ui/loading? :login] false)
(async/go
(let [result (async/<! (sync/<user-info sync/remoteapi))]
(cond
(instance? ExceptionInfo result)
nil
(map? result)
(do
(state/set-user-info! result)
(when-let [uid (user-handler/user-uuid)]
(sentry-event/set-user! uid))
(let [status (if (user-handler/alpha-or-beta-user?) :welcome :unavailable)]
(when (and (= status :welcome) (user-handler/logged-in?))
(enable-beta-features!)
(async/<! (p->c (rtc-handler/<get-remote-graphs)))
(async/<! (file-sync-handler/load-session-graphs))
(p/let [repos (repo-handler/refresh-repos!)]
(when-let [repo (state/get-current-repo)]
(when (some #(and (= (:url %) repo)
(vector? (:sync-meta %))
(util/uuid-string? (first (:sync-meta %)))
(util/uuid-string? (second (:sync-meta %)))) repos)
(sync/<sync-start)))))
(file-sync/maybe-onboarding-show status)))))))
(defmethod events/handle :graph/pull-down-remote-graph [[_ graph dir-name]]
(if (mobile-util/native-ios?)
(when-let [graph-name (or dir-name (:GraphName graph))]
@@ -234,15 +200,6 @@
(file-sync/pick-page-histories-panel graph-uuid page-name)
{:id :page-histories :label "modal-page-histories"}))
(defmethod events/handle :file-sync/onboarding-tip [[_ type opts]]
(let [type (keyword type)]
(when-not (config/db-based-graph? (state/get-current-repo))
(shui/dialog-open!
(file-sync/make-onboarding-panel type)
(merge {:close-btn? false
:center? true
:close-backdrop? (not= type :welcome)} opts)))))
(defmethod events/handle :file-sync/maybe-onboarding-show [[_ type]]
(file-sync/maybe-onboarding-show type))

View File

@@ -0,0 +1,23 @@
(ns frontend.worker.db.fix
"fix db"
(:require [datascript.core :as d]
[logseq.db.sqlite.util :as sqlite-util]))
(defn check-and-fix-schema!
[repo conn]
(let [schema (sqlite-util/get-schema repo)
db-schema (:schema @conn)
diffs (->> (keep (fn [[k v]]
(let [schema-v (-> (get db-schema k)
(dissoc :db/ident))
schema-v' (cond-> schema-v
(= (:db/cardinality schema-v) :db.cardinality/one)
(dissoc :db/cardinality)
(and (:db/index schema-v)
(nil? (:db/index v)))
(dissoc :db/index))]
(when-not (or (= v schema-v') (= k :db/ident))
(assoc v :db/ident k))))
schema))]
(when (seq diffs)
(d/transact! conn diffs))))

View File

@@ -13,6 +13,7 @@
[frontend.common.graph-view :as graph-view]
[frontend.common.thread-api :as thread-api :refer [def-thread-api]]
[frontend.worker.db-listener :as db-listener]
[frontend.worker.db.fix :as db-fix]
[frontend.worker.db.migrate :as db-migrate]
[frontend.worker.db.validate :as worker-db-validate]
[frontend.worker.export :as worker-export]
@@ -333,6 +334,7 @@
(search/create-tables-and-triggers! search-db)
(let [schema (sqlite-util/get-schema repo)
conn (sqlite-common-db/get-storage-conn storage schema)
_ (db-fix/check-and-fix-schema! repo conn)
_ (when datoms
(let [data (map (fn [datom]
[:db/add (:e datom) (:a datom) (:v datom)]) datoms)]

View File

@@ -82,8 +82,10 @@
(state/set-editor-action! action)
;; Default cursor pos to end of line
(let [pos (or cursor-pos (count value))
input #js {:value value}]
(with-redefs [editor/get-matched-commands (constantly commands)
input #js {:value value}
command (subs value 1)]
(with-redefs [editor/get-last-command (constantly command)
editor/get-matched-commands (constantly commands)
;; Ignore as none of its behaviors are tested
editor/default-case-for-keyup-handler (constantly nil)
cursor/pos (constantly pos)]
@@ -93,18 +95,31 @@
(deftest keyup-handler-test
(testing "Command autocompletion"
;; default last matching command is ""
(keyup-handler {:value "/z"
:action :commands
:commands []})
(is (= :commands (state/get-editor-action))
"Completion stays open if no matches but differs from last success by <= 2 chars")
(keyup-handler {:value "/zz"
:action :commands
:commands []})
(is (= :commands (state/get-editor-action))
"Completion stays open if no matches but differs from last success by <= 2 chars")
(keyup-handler {:value "/zzz"
:action :commands
:commands []})
(is (= nil (state/get-editor-action))
"Completion closed if no matches and > 2 chars form last success")
(keyup-handler {:value "/b"
:action :commands
:commands [:fake-command]})
(is (= :commands (state/get-editor-action))
"Completion stays open if there is a matching command")
(keyup-handler {:value "/zz"
:action :commands
:commands []})
(is (= nil (state/get-editor-action))
"Completion closed if there no matching commands")
(keyup-handler {:value "/ " :action :commands})
(is (= nil (state/get-editor-action))
"Completion closed after a space follows /")