mirror of https://github.com/logseq/logseq
Merge branch 'feat/db' into refactor/single-block-type
commit
9c60742519
|
@ -4,7 +4,7 @@
|
||||||
{logseq/bb-tasks
|
{logseq/bb-tasks
|
||||||
#_{:local/root "../../../bb-tasks"}
|
#_{:local/root "../../../bb-tasks"}
|
||||||
{:git/url "https://github.com/logseq/bb-tasks"
|
{:git/url "https://github.com/logseq/bb-tasks"
|
||||||
:git/sha "70d3edeb287f5cec7192e642549a401f7d6d4263"}}
|
:git/sha "1d429e223baeade426d30a4ed1c8a110173a2402"}}
|
||||||
|
|
||||||
:pods
|
:pods
|
||||||
{clj-kondo/clj-kondo {:version "2023.05.26"}}
|
{clj-kondo/clj-kondo {:version "2023.05.26"}}
|
||||||
|
|
|
@ -89,9 +89,14 @@
|
||||||
(let [datoms (d/datoms db :eavt)
|
(let [datoms (d/datoms db :eavt)
|
||||||
ent-maps* (db-malli-schema/datoms->entities datoms)
|
ent-maps* (db-malli-schema/datoms->entities datoms)
|
||||||
schema (update-schema db-malli-schema/DB db {:closed-schema? true})
|
schema (update-schema db-malli-schema/DB db {:closed-schema? true})
|
||||||
ent-maps (db-malli-schema/update-properties-in-ents db ent-maps*)
|
ent-maps (mapv
|
||||||
|
;; Remove some UI interactions adding this e.g. import
|
||||||
|
#(dissoc % :block.temp/fully-loaded?)
|
||||||
|
(db-malli-schema/update-properties-in-ents db ent-maps*))
|
||||||
errors (->> ent-maps (m/explain schema) :errors)]
|
errors (->> ent-maps (m/explain schema) :errors)]
|
||||||
(cond-> {:datom-count (count datoms)
|
(cond-> {:datom-count (count datoms)
|
||||||
:entities ent-maps}
|
:entities ent-maps}
|
||||||
(some? errors)
|
(some? errors)
|
||||||
(assoc :errors (group-errors-by-entity db ent-maps errors)))))
|
(assoc :errors (map #(-> (dissoc % :errors-by-type)
|
||||||
|
(update :errors (fn [errs] (me/humanize {:errors errs}))))
|
||||||
|
(group-errors-by-entity db ent-maps errors))))))
|
||||||
|
|
|
@ -294,12 +294,19 @@
|
||||||
[(:name v) k]))
|
[(:name v) k]))
|
||||||
(into {})))
|
(into {})))
|
||||||
|
|
||||||
(def built-in-property-names
|
;; Should this move to logseq.db.frontend.property to be better maintained?
|
||||||
"Set of all built-in property names as keywords. Using in-memory property
|
(def db-only-built-in-property-names
|
||||||
names because these are legacy names already in a user's file graph"
|
"Built-in property names that are are only used by DB graphs"
|
||||||
|
#{:description :page-tags :hide-properties? :created-from-property
|
||||||
|
:built-in? :includes :excludes :status :priority :deadline :sorting
|
||||||
|
:hidden-columns :ordered-columns :view-for :remote-metadata})
|
||||||
|
|
||||||
|
(def file-built-in-property-names
|
||||||
|
"Built-in property names for file graphs that are imported. Expressed as set of keywords"
|
||||||
(-> built-in-property-name-to-idents keys set
|
(-> built-in-property-name-to-idents keys set
|
||||||
;; :filters is not in built-in-properties because it maps to 2 new properties
|
;; :filters is not in built-in-properties because it maps to 2 new properties
|
||||||
(conj :filters)))
|
(conj :filters)
|
||||||
|
(set/difference db-only-built-in-property-names)))
|
||||||
|
|
||||||
(defn- update-built-in-property-values
|
(defn- update-built-in-property-values
|
||||||
[props {:keys [ignored-properties all-idents]} {:block/keys [title name]} options]
|
[props {:keys [ignored-properties all-idents]} {:block/keys [title name]} options]
|
||||||
|
@ -433,7 +440,7 @@
|
||||||
{:keys [import-state] :as options}]
|
{:keys [import-state] :as options}]
|
||||||
(let [{:keys [all-idents property-schemas]} import-state
|
(let [{:keys [all-idents property-schemas]} import-state
|
||||||
get-ident' #(get-ident @all-idents %)
|
get-ident' #(get-ident @all-idents %)
|
||||||
user-properties (apply dissoc props built-in-property-names)]
|
user-properties (apply dissoc props file-built-in-property-names)]
|
||||||
(when (seq user-properties)
|
(when (seq user-properties)
|
||||||
(swap! (:block-properties-text-values import-state)
|
(swap! (:block-properties-text-values import-state)
|
||||||
assoc
|
assoc
|
||||||
|
@ -444,7 +451,7 @@
|
||||||
(if (contains? props :template)
|
(if (contains? props :template)
|
||||||
{}
|
{}
|
||||||
(let [props' (-> (update-built-in-property-values
|
(let [props' (-> (update-built-in-property-values
|
||||||
(select-keys props built-in-property-names)
|
(select-keys props file-built-in-property-names)
|
||||||
(select-keys import-state [:ignored-properties :all-idents])
|
(select-keys import-state [:ignored-properties :all-idents])
|
||||||
(select-keys block [:block/name :block/title])
|
(select-keys block [:block/name :block/title])
|
||||||
(select-keys options [:property-classes]))
|
(select-keys options [:property-classes]))
|
||||||
|
@ -479,7 +486,7 @@
|
||||||
class-related-properties)]
|
class-related-properties)]
|
||||||
(->> (apply dissoc properties dissoced-props)
|
(->> (apply dissoc properties dissoced-props)
|
||||||
(keep (fn [[prop val]]
|
(keep (fn [[prop val]]
|
||||||
(if (not (contains? built-in-property-names prop))
|
(if (not (contains? file-built-in-property-names prop))
|
||||||
;; only update user properties
|
;; only update user properties
|
||||||
(if (string? val)
|
(if (string? val)
|
||||||
;; Ignore blank values as they were usually generated by templates
|
;; Ignore blank values as they were usually generated by templates
|
||||||
|
@ -508,7 +515,7 @@
|
||||||
properties-to-infer (if (:template properties')
|
properties-to-infer (if (:template properties')
|
||||||
;; Ignore template properties as they don't consistently have representative property values
|
;; Ignore template properties as they don't consistently have representative property values
|
||||||
{}
|
{}
|
||||||
(apply dissoc properties' built-in-property-names))
|
(apply dissoc properties' file-built-in-property-names))
|
||||||
property-changes
|
property-changes
|
||||||
(->> properties-to-infer
|
(->> properties-to-infer
|
||||||
(keep (fn [[prop val]]
|
(keep (fn [[prop val]]
|
||||||
|
@ -676,9 +683,22 @@
|
||||||
(not (:block/file %))))
|
(not (:block/file %))))
|
||||||
;; remove file path relative
|
;; remove file path relative
|
||||||
(map #(dissoc % :block/file)))
|
(map #(dissoc % :block/file)))
|
||||||
existing-pages (keep #(ldb/get-page @conn (:block/name %)) all-pages)
|
existing-pages (keep #(first
|
||||||
|
;; don't fetch built-in as that would give the wrong entity if a user used
|
||||||
|
;; a db-only built-in property name e.g. description
|
||||||
|
(d/q '[:find [(pull ?b [*]) ...]
|
||||||
|
:in $ ?name
|
||||||
|
:where [?b :block/name ?name] [(missing? $ ?b :logseq.property/built-in?)]]
|
||||||
|
@conn
|
||||||
|
(:block/name %)))
|
||||||
|
all-pages)
|
||||||
existing-page-names-to-uuids (into {} (map (juxt :block/name :block/uuid) existing-pages))
|
existing-page-names-to-uuids (into {} (map (juxt :block/name :block/uuid) existing-pages))
|
||||||
new-pages (remove #(contains? existing-page-names-to-uuids (:block/name %)) all-pages)
|
new-pages (->> all-pages
|
||||||
|
(remove #(contains? existing-page-names-to-uuids (:block/name %)))
|
||||||
|
;; fix extract incorrectly assigning user properties built-in property uuids
|
||||||
|
(map #(if (contains? db-only-built-in-property-names (keyword (:block/name %)))
|
||||||
|
(assoc % :block/uuid (d/squuid))
|
||||||
|
%)))
|
||||||
page-names-to-uuids (merge existing-page-names-to-uuids
|
page-names-to-uuids (merge existing-page-names-to-uuids
|
||||||
(into {} (map (juxt :block/name :block/uuid) new-pages)))
|
(into {} (map (juxt :block/name :block/uuid) new-pages)))
|
||||||
all-pages-m (mapv #(handle-page-properties % @conn page-names-to-uuids all-pages options)
|
all-pages-m (mapv #(handle-page-properties % @conn page-names-to-uuids all-pages options)
|
||||||
|
@ -701,7 +721,11 @@
|
||||||
(update-page-alias page-names-to-uuids)
|
(update-page-alias page-names-to-uuids)
|
||||||
(:block/tags m)
|
(:block/tags m)
|
||||||
(update-page-tags @conn tag-classes page-names-to-uuids (:all-idents import-state)))))
|
(update-page-tags @conn tag-classes page-names-to-uuids (:all-idents import-state)))))
|
||||||
(build-new-page m @conn tag-classes page-names-to-uuids (:all-idents import-state))))
|
(let [m' (if (contains? db-only-built-in-property-names (keyword (:block/name m)))
|
||||||
|
;; Use fixed uuid from above
|
||||||
|
(assoc m :block/uuid (get page-names-to-uuids (:block/name m)))
|
||||||
|
m)]
|
||||||
|
(build-new-page m' @conn tag-classes page-names-to-uuids (:all-idents import-state)))))
|
||||||
(map :block all-pages-m))]
|
(map :block all-pages-m))]
|
||||||
{:pages-tx pages-tx
|
{:pages-tx pages-tx
|
||||||
:page-properties-tx (mapcat :properties-tx all-pages-m)
|
:page-properties-tx (mapcat :properties-tx all-pages-m)
|
||||||
|
@ -791,10 +815,10 @@
|
||||||
:tag-classes (set (map string/lower-case (:tag-classes user-options)))
|
:tag-classes (set (map string/lower-case (:tag-classes user-options)))
|
||||||
:property-classes (set/difference
|
:property-classes (set/difference
|
||||||
(set (map (comp keyword string/lower-case) (:property-classes user-options)))
|
(set (map (comp keyword string/lower-case) (:property-classes user-options)))
|
||||||
built-in-property-names)
|
file-built-in-property-names)
|
||||||
:property-parent-classes (set/difference
|
:property-parent-classes (set/difference
|
||||||
(set (map (comp keyword string/lower-case) (:property-parent-classes user-options)))
|
(set (map (comp keyword string/lower-case) (:property-parent-classes user-options)))
|
||||||
built-in-property-names)}))
|
file-built-in-property-names)}))
|
||||||
|
|
||||||
(defn- split-pages-and-properties-tx
|
(defn- split-pages-and-properties-tx
|
||||||
"Separates new pages from new properties tx in preparation for properties to
|
"Separates new pages from new properties tx in preparation for properties to
|
||||||
|
|
|
@ -900,6 +900,7 @@
|
||||||
granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
|
granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
|
||||||
theme (state/sub :ui/theme)
|
theme (state/sub :ui/theme)
|
||||||
accent-color (some-> (state/sub :ui/radix-color) (name))
|
accent-color (some-> (state/sub :ui/radix-color) (name))
|
||||||
|
editor-font (some-> (state/sub :ui/editor-font) (name))
|
||||||
system-theme? (state/sub :ui/system-theme?)
|
system-theme? (state/sub :ui/system-theme?)
|
||||||
light? (= "light" (state/sub :ui/theme))
|
light? (= "light" (state/sub :ui/theme))
|
||||||
sidebar-open? (state/sub :ui/sidebar-open?)
|
sidebar-open? (state/sub :ui/sidebar-open?)
|
||||||
|
@ -929,6 +930,7 @@
|
||||||
{:t t
|
{:t t
|
||||||
:theme theme
|
:theme theme
|
||||||
:accent-color accent-color
|
:accent-color accent-color
|
||||||
|
:editor-font editor-font
|
||||||
:route route-match
|
:route route-match
|
||||||
:current-repo current-repo
|
:current-repo current-repo
|
||||||
:edit? edit?
|
:edit? edit?
|
||||||
|
|
|
@ -277,7 +277,7 @@
|
||||||
(do
|
(do
|
||||||
(log/error :import-errors {:msg (str "Import detected " (count errors) " invalid block(s):")
|
(log/error :import-errors {:msg (str "Import detected " (count errors) " invalid block(s):")
|
||||||
:counts (assoc (counts-from-entities entities) :datoms datom-count)})
|
:counts (assoc (counts-from-entities entities) :datoms datom-count)})
|
||||||
(pprint/pprint (map :entity errors))
|
(pprint/pprint errors)
|
||||||
(notification/show! (str "Import detected " (count errors) " invalid block(s). These blocks may be buggy when you interact with them. See the javascript console for more.")
|
(notification/show! (str "Import detected " (count errors) " invalid block(s). These blocks may be buggy when you interact with them. See the javascript console for more.")
|
||||||
:warning false))
|
:warning false))
|
||||||
(log/info :import-valid {:msg "Valid import!"
|
(log/info :import-valid {:msg "Valid import!"
|
||||||
|
@ -413,7 +413,7 @@
|
||||||
(shui/dialog-open!
|
(shui/dialog-open!
|
||||||
#(set-graph-name-dialog e {:sqlite? true})))}]])
|
#(set-graph-name-dialog e {:sqlite? true})))}]])
|
||||||
|
|
||||||
(when (and db-based? (or util/electron? util/web-platform?))
|
(when (or util/electron? util/web-platform?)
|
||||||
[:label.action-input.flex.items-center.mx-2.my-2
|
[:label.action-input.flex.items-center.mx-2.my-2
|
||||||
[:span.as-flex-center [:i (svg/logo 28)]]
|
[:span.as-flex-center [:i (svg/logo 28)]]
|
||||||
[:span.flex.flex-col
|
[:span.flex.flex-col
|
||||||
|
|
|
@ -94,56 +94,56 @@
|
||||||
(shui/tabler-icon "folder-pin") [:span.pl-1 root]])
|
(shui/tabler-icon "folder-pin") [:span.pl-1 root]])
|
||||||
|
|
||||||
(let [db-graph? (config/db-based-graph? url)
|
(let [db-graph? (config/db-based-graph? url)
|
||||||
manager? (and db-graph? (user-handler/manager? url))]
|
manager? (and db-graph? (user-handler/manager? url))
|
||||||
|
title (cond
|
||||||
|
only-cloud?
|
||||||
|
"Deletes this remote graph. Note this can't be recovered."
|
||||||
|
|
||||||
|
db-based?
|
||||||
|
"Unsafe delete this DB-based graph. Note this can't be recovered."
|
||||||
|
|
||||||
|
:else
|
||||||
|
"Removes Logseq's access to the local file path of your graph. It won't remove your local files.")]
|
||||||
(when-not (and only-cloud? (not manager?))
|
(when-not (and only-cloud? (not manager?))
|
||||||
(ui/tippy {:html [:div.text-sm.max-w-xs
|
[:a.text-gray-400.ml-4.font-medium.text-sm.whitespace-nowrap
|
||||||
(cond
|
{:title title
|
||||||
only-cloud?
|
:on-click (fn []
|
||||||
"Deletes this remote graph. Note this can't be recovered."
|
(let [has-prompt? true
|
||||||
|
prompt-str (cond only-cloud?
|
||||||
|
(str "Are you sure to permanently delete the graph \"" GraphName "\" from our server?")
|
||||||
|
db-based?
|
||||||
|
(str "Are you sure to permanently delete the graph \"" url "\" from Logseq?")
|
||||||
|
:else
|
||||||
|
(str "Are you sure to unlink the graph \"" url "\" from local folder?"))
|
||||||
|
unlink-or-remote-fn! (fn []
|
||||||
|
(repo-handler/remove-repo! repo)
|
||||||
|
(state/pub-event! [:graph/unlinked repo (state/get-current-repo)]))
|
||||||
|
action-confirm-fn! (if only-cloud?
|
||||||
|
(fn []
|
||||||
|
(when (or manager? (not db-graph?))
|
||||||
|
(let [delete-graph (if db-graph?
|
||||||
|
rtc-handler/<rtc-delete-graph!
|
||||||
|
file-sync/<delete-graph)]
|
||||||
|
(state/set-state! [:file-sync/remote-graphs :loading] true)
|
||||||
|
(go (<! (delete-graph GraphUUID))
|
||||||
|
(state/delete-repo! repo)
|
||||||
|
(state/delete-remote-graph! repo)
|
||||||
|
(state/set-state! [:file-sync/remote-graphs :loading] false)))))
|
||||||
|
unlink-or-remote-fn!)
|
||||||
|
confirm-fn!
|
||||||
|
(fn []
|
||||||
|
(-> (shui/dialog-confirm!
|
||||||
|
[:p.font-medium.-my-4 prompt-str
|
||||||
|
[:span.mt-1.flex.font-normal.opacity-70
|
||||||
|
(if (or db-based? only-cloud?)
|
||||||
|
[:small.text-red-rx-11 "⚠️ Notice that we can't recover this graph after being deleted. Make sure you have backups before deleting it."]
|
||||||
|
[:small.opacity-70 "⚠️ It won't remove your local files!"])]])
|
||||||
|
(p/then #(action-confirm-fn!))))]
|
||||||
|
|
||||||
db-based?
|
(if has-prompt?
|
||||||
"Unsafe delete this DB-based graph. Note this can't be recovered."
|
(confirm-fn!)
|
||||||
|
(unlink-or-remote-fn!))))}
|
||||||
:else
|
(if only-cloud? "Remove (server)" "Unlink (local)")]))]]]))
|
||||||
"Removes Logseq's access to the local file path of your graph. It won't remove your local files.")]
|
|
||||||
:class "tippy-hover"
|
|
||||||
:interactive true}
|
|
||||||
[:a.text-gray-400.ml-4.font-medium.text-sm.whitespace-nowrap
|
|
||||||
{:on-click (fn []
|
|
||||||
(let [has-prompt? (or only-cloud? db-based?)
|
|
||||||
prompt-str (cond only-cloud?
|
|
||||||
(str "Are you sure to permanently delete the graph \"" GraphName "\" from our server?")
|
|
||||||
db-based?
|
|
||||||
(str "Are you sure to permanently delete the graph \"" url "\" from Logseq?")
|
|
||||||
:else
|
|
||||||
"")
|
|
||||||
unlink-or-remote-fn! (fn []
|
|
||||||
(repo-handler/remove-repo! repo)
|
|
||||||
(state/pub-event! [:graph/unlinked repo (state/get-current-repo)]))
|
|
||||||
action-confirm-fn! (if only-cloud?
|
|
||||||
(fn []
|
|
||||||
(when (or manager? (not db-graph?))
|
|
||||||
(let [delete-graph (if db-graph?
|
|
||||||
rtc-handler/<rtc-delete-graph!
|
|
||||||
file-sync/<delete-graph)]
|
|
||||||
(state/set-state! [:file-sync/remote-graphs :loading] true)
|
|
||||||
(go (<! (delete-graph GraphUUID))
|
|
||||||
(state/delete-repo! repo)
|
|
||||||
(state/delete-remote-graph! repo)
|
|
||||||
(state/set-state! [:file-sync/remote-graphs :loading] false)))))
|
|
||||||
unlink-or-remote-fn!)
|
|
||||||
confirm-fn!
|
|
||||||
(fn []
|
|
||||||
(-> (shui/dialog-confirm!
|
|
||||||
[:p.font-medium.-my-4 prompt-str
|
|
||||||
[:span.mt-1.flex.font-normal.opacity-40
|
|
||||||
[:small "Notice that we can't recover this graph after being deleted. Make sure you have backups before deleting it."]]])
|
|
||||||
(p/then #(action-confirm-fn!))))]
|
|
||||||
|
|
||||||
(if has-prompt?
|
|
||||||
(confirm-fn!)
|
|
||||||
(unlink-or-remote-fn!))))}
|
|
||||||
(if only-cloud? "Remove (server)" "Unlink (local)")])))]]]))
|
|
||||||
|
|
||||||
(rum/defc repos < rum/reactive
|
(rum/defc repos < rum/reactive
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -220,6 +220,38 @@
|
||||||
[:div {:style {:text-align "right"}}
|
[:div {:style {:text-align "right"}}
|
||||||
(ui/render-keyboard-shortcut (shortcut-helper/gen-shortcut-seq :ui/toggle-brackets))])])
|
(ui/render-keyboard-shortcut (shortcut-helper/gen-shortcut-seq :ui/toggle-brackets))])])
|
||||||
|
|
||||||
|
(defn toggle-wide-mode-row [t wide-mode?]
|
||||||
|
[:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-center
|
||||||
|
[:label.block.text-sm.font-medium.leading-5.opacity-70
|
||||||
|
{:for "wide_mode"}
|
||||||
|
(t :settings-page/wide-mode)]
|
||||||
|
[:div
|
||||||
|
[:div.rounded-md.sm:max-w-xs
|
||||||
|
(ui/toggle wide-mode?
|
||||||
|
state/toggle-wide-mode!
|
||||||
|
true)]]
|
||||||
|
(when (not (or (util/mobile?) (mobile-util/native-platform?)))
|
||||||
|
[:div {:style {:text-align "right"}}
|
||||||
|
(ui/render-keyboard-shortcut (shortcut-helper/gen-shortcut-seq :ui/toggle-wide-mode))])])
|
||||||
|
|
||||||
|
(defn editor-font-family-row [t font]
|
||||||
|
[:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-center
|
||||||
|
[:label.block.text-sm.font-medium.leading-5.opacity-70
|
||||||
|
{:for "font_family"}
|
||||||
|
(t :settings-page/editor-font)]
|
||||||
|
[:div.rounded-md.sm:max-w-xs.flex.gap-2
|
||||||
|
(for [t [:default :serif :mono]
|
||||||
|
:let [t (name t)
|
||||||
|
tt (string/capitalize t)
|
||||||
|
active? (= font t)]]
|
||||||
|
(shui/button
|
||||||
|
{:variant :secondary
|
||||||
|
:class (when active? "border-primary border-[2px]")
|
||||||
|
:on-click #(state/set-editor-font! t)}
|
||||||
|
[:span.flex.flex-col
|
||||||
|
[:strong "Ag"]
|
||||||
|
[:small tt]]))]])
|
||||||
|
|
||||||
(rum/defcs switch-spell-check-row < rum/reactive
|
(rum/defcs switch-spell-check-row < rum/reactive
|
||||||
[state t]
|
[state t]
|
||||||
(let [enabled? (state/sub [:electron/user-cfgs :spell-check])]
|
(let [enabled? (state/sub [:electron/user-cfgs :spell-check])]
|
||||||
|
@ -719,6 +751,8 @@
|
||||||
enable-tooltip? (state/enable-tooltip?)
|
enable-tooltip? (state/enable-tooltip?)
|
||||||
enable-shortcut-tooltip? (state/sub :ui/shortcut-tooltip?)
|
enable-shortcut-tooltip? (state/sub :ui/shortcut-tooltip?)
|
||||||
show-brackets? (state/show-brackets?)
|
show-brackets? (state/show-brackets?)
|
||||||
|
wide-mode? (state/sub :ui/wide-mode?)
|
||||||
|
editor-font (state/sub :ui/editor-font)
|
||||||
enable-git-auto-push? (state/enable-git-auto-push? current-repo)
|
enable-git-auto-push? (state/enable-git-auto-push? current-repo)
|
||||||
db-graph? (config/db-based-graph? (state/get-current-repo))]
|
db-graph? (config/db-based-graph? (state/get-current-repo))]
|
||||||
|
|
||||||
|
@ -728,7 +762,9 @@
|
||||||
(date-format-row t preferred-date-format)
|
(date-format-row t preferred-date-format)
|
||||||
(when-not db-graph?
|
(when-not db-graph?
|
||||||
(workflow-row t preferred-workflow))
|
(workflow-row t preferred-workflow))
|
||||||
|
(editor-font-family-row t editor-font)
|
||||||
(show-brackets-row t show-brackets?)
|
(show-brackets-row t show-brackets?)
|
||||||
|
(toggle-wide-mode-row t wide-mode?)
|
||||||
|
|
||||||
(when (util/electron?) (switch-spell-check-row t))
|
(when (util/electron?) (switch-spell-check-row t))
|
||||||
(outdenting-row t logical-outdenting?)
|
(outdenting-row t logical-outdenting?)
|
||||||
|
|
|
@ -183,14 +183,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-item .cp__shortcut-page-x {
|
.sidebar-item .cp__shortcut-page-x {
|
||||||
padding: 12px 0 0 0;
|
padding: 12px 0 0 0;
|
||||||
background-color: var(--color-level-2);
|
background-color: var(--color-level-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-item article {
|
.sidebar-item article {
|
||||||
max-height: unset;
|
max-height: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.keyboard-shortcut {
|
.keyboard-shortcut {
|
||||||
@apply inline-flex;
|
@apply inline-flex;
|
||||||
|
|
||||||
|
.ui__button {
|
||||||
|
@apply cursor-default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
|
|
||||||
(defonce *once-theme-loaded? (volatile! false))
|
(defonce *once-theme-loaded? (volatile! false))
|
||||||
|
|
||||||
(rum/defc ^:large-vars/cleanup-todo container
|
(rum/defc ^:large-vars/cleanup-todo container < rum/static
|
||||||
[{:keys [route theme accent-color on-click current-repo nfs-granted? db-restoring?
|
[{:keys [route theme accent-color editor-font on-click current-repo nfs-granted? db-restoring?
|
||||||
settings-open? sidebar-open? system-theme? sidebar-blocks-len onboarding-state preferred-language]} child]
|
settings-open? sidebar-open? system-theme? sidebar-blocks-len onboarding-state preferred-language]} child]
|
||||||
(let [mounted-fn (use-mounted)
|
(let [mounted-fn (use-mounted)
|
||||||
[restored-sidebar? set-restored-sidebar?] (rum/use-state false)]
|
[restored-sidebar? set-restored-sidebar?] (rum/use-state false)]
|
||||||
|
@ -60,6 +60,11 @@
|
||||||
(or accent-color "logseq")))
|
(or accent-color "logseq")))
|
||||||
[accent-color])
|
[accent-color])
|
||||||
|
|
||||||
|
(rum/use-effect!
|
||||||
|
#(some-> js/document.documentElement
|
||||||
|
(.setAttribute "data-font" (or editor-font "default")))
|
||||||
|
[editor-font])
|
||||||
|
|
||||||
(rum/use-effect!
|
(rum/use-effect!
|
||||||
#(let [doc js/document.documentElement]
|
#(let [doc js/document.documentElement]
|
||||||
(.setAttribute doc "lang" preferred-language)))
|
(.setAttribute doc "lang" preferred-language)))
|
||||||
|
|
|
@ -153,4 +153,12 @@ main.ls-fold-button-on-right {
|
||||||
|
|
||||||
main.theme-container-inner {
|
main.theme-container-inner {
|
||||||
--left-sidebar-bg-color: var(--lx-gray-02, hsl(var(--secondary, var(--rx-gray-03-hsl))));
|
--left-sidebar-bg-color: var(--lx-gray-02, hsl(var(--secondary, var(--rx-gray-03-hsl))));
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-font='serif'] .ls-block, .ls-font-serif {
|
||||||
|
font-family: Lyon-Text, Georgia, ui-serif, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-font='mono'] .ls-block, .ls-font-mono {
|
||||||
|
font-family: iawriter-mono, Nitti, Menlo, Courier, monospace;
|
||||||
}
|
}
|
|
@ -139,8 +139,8 @@
|
||||||
(if (false? bindings)
|
(if (false? bindings)
|
||||||
[]
|
[]
|
||||||
(-> bindings
|
(-> bindings
|
||||||
first
|
last
|
||||||
(str/split #" |\+")))))
|
(str/split #" |\+")))))
|
||||||
|
|
||||||
(defn binding-for-display [k binding]
|
(defn binding-for-display [k binding]
|
||||||
(let [tmp (cond
|
(let [tmp (cond
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
:ui/custom-theme (or (storage/get :ui/custom-theme) {:light {:mode "light"} :dark {:mode "dark"}})
|
:ui/custom-theme (or (storage/get :ui/custom-theme) {:light {:mode "light"} :dark {:mode "dark"}})
|
||||||
:ui/wide-mode? (storage/get :ui/wide-mode)
|
:ui/wide-mode? (storage/get :ui/wide-mode)
|
||||||
:ui/radix-color (storage/get :ui/radix-color)
|
:ui/radix-color (storage/get :ui/radix-color)
|
||||||
|
:ui/editor-font (storage/get :ui/editor-font)
|
||||||
|
|
||||||
;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
|
;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
|
||||||
;; 1. right sidebar
|
;; 1. right sidebar
|
||||||
|
@ -2385,6 +2386,11 @@ Similar to re-frame subscriptions"
|
||||||
(storage/remove :ui/radix-color)
|
(storage/remove :ui/radix-color)
|
||||||
(util/set-android-theme))
|
(util/set-android-theme))
|
||||||
|
|
||||||
|
(defn set-editor-font! [font]
|
||||||
|
(let [font (if (keyword? font) (name font) (str font))]
|
||||||
|
(swap! state assoc :ui/editor-font font)
|
||||||
|
(storage/set :ui/editor-font font)))
|
||||||
|
|
||||||
(defn handbook-open?
|
(defn handbook-open?
|
||||||
[]
|
[]
|
||||||
(:ui/handbooks-open? @state))
|
(:ui/handbooks-open? @state))
|
||||||
|
|
|
@ -270,6 +270,8 @@
|
||||||
:settings-page/custom-theme "Custom theme"
|
:settings-page/custom-theme "Custom theme"
|
||||||
:settings-page/export-theme "Export theme"
|
:settings-page/export-theme "Export theme"
|
||||||
:settings-page/show-brackets "Show brackets"
|
:settings-page/show-brackets "Show brackets"
|
||||||
|
:settings-page/wide-mode "Wide mode"
|
||||||
|
:settings-page/editor-font "Font family"
|
||||||
:settings-page/spell-checker "Spell checker"
|
:settings-page/spell-checker "Spell checker"
|
||||||
:settings-page/auto-updater "Auto updater"
|
:settings-page/auto-updater "Auto updater"
|
||||||
:settings-page/disable-sentry "Send usage data and diagnostics to Logseq"
|
:settings-page/disable-sentry "Send usage data and diagnostics to Logseq"
|
||||||
|
|
Loading…
Reference in New Issue