Browse Source

Merge branch 'feat/db' into refactor/dsl-query

Tienson Qin 11 months ago
parent
commit
502e3fd807

+ 2 - 2
deps/db/src/logseq/db/frontend/property/type.cljs

@@ -38,12 +38,12 @@
   "Property value ref types where the refed entity stores its value in
   :property.value/content e.g. :number is stored as a number. new value-ref-property-types
   should default to this as it allows for more querying power"
-  #{:number :url})
+  #{:number})
 
 (def value-ref-property-types
   "Property value ref types where the refed entities either store their value in
   :property.value/content or :block/title (for :default)"
-  (into #{:default} original-value-ref-property-types))
+  (into #{:default :url} original-value-ref-property-types))
 
 (def user-ref-property-types
   "User ref types. Property values that users see are stored in either

+ 6 - 3
deps/graph-parser/script/db_import.cljs

@@ -134,11 +134,14 @@
         conn (outliner-cli/init-conn dir db-name {:classpath (cp/get-classpath)})
         directory? (.isDirectory (fs/statSync file-graph'))
         ;; coerce option collection into strings
-        options' (if (:tag-classes options) (update options :tag-classes (partial mapv str)) options)]
+        user-options (if (:tag-classes options) (update options :tag-classes (partial mapv str)) options)
+        options' (merge {:user-options (dissoc user-options :verbose :files :help)
+                         :graph-name db-name}
+                        (select-keys options [:files :verbose]))]
     (p/let [{:keys [import-state]}
             (if directory?
-              (import-file-graph-to-db file-graph' (node-path/join dir db-name) conn (merge options' {:graph-name db-name}))
-              (import-files-to-db file-graph' conn (merge options' {:graph-name db-name})))]
+              (import-file-graph-to-db file-graph' (node-path/join dir db-name) conn options')
+              (import-files-to-db file-graph' conn options'))]
 
       (when-let [ignored-props (seq @(:ignored-properties import-state))]
         (println "Ignored properties:" (pr-str ignored-props)))

+ 30 - 26
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -535,7 +535,7 @@
   updated properties in :block-properties and any property values tx in :pvalues-tx"
   [props _db page-names-to-uuids
    {:block/keys [properties-text-values] :as block}
-   {:keys [import-state] :as options}]
+   {:keys [import-state user-options] :as options}]
   (let [{:keys [all-idents property-schemas]} import-state
         get-ident' #(get-ident @all-idents %)
         user-properties (apply dissoc props file-built-in-property-names)]
@@ -553,7 +553,7 @@
                         page-names-to-uuids
                         (select-keys import-state [:ignored-properties :all-idents])
                         (select-keys block [:block/name :block/title])
-                        (select-keys options [:property-classes]))
+                        (select-keys user-options [:property-classes]))
                        (merge (update-user-property-values user-properties page-names-to-uuids properties-text-values import-state options)))
             pvalue-tx-m (->property-value-tx-m block props' #(get-property-schema @property-schemas %) @all-idents)
             block-properties (-> (merge props' (db-property-build/build-properties-with-ref-values pvalue-tx-m))
@@ -605,7 +605,9 @@
   a property is updated. Only infers property schemas on user properties as
   built-in ones must not change"
   [{:block/keys [properties] :as block} db page-names-to-uuids refs
-   {:keys [import-state macros property-classes property-parent-classes] :as options}]
+   {{:keys [property-classes property-parent-classes]} :user-options
+    :keys [import-state macros]
+    :as options}]
   (-> (if (seq properties)
         (let [classes-from-properties (->> (select-keys properties property-classes)
                                            (mapcat (fn [[_k v]] (if (coll? v) v [v])))
@@ -644,11 +646,11 @@
 (defn- handle-page-properties
   "Adds page properties including special handling for :logseq.property/parent"
   [{:block/keys [properties] :as block*} db page-names-to-uuids refs
-   {:keys [property-parent-classes log-fn import-state] :as options}]
+   {:keys [user-options log-fn import-state] :as options}]
   (let [{:keys [block properties-tx]} (handle-page-and-block-properties block* db page-names-to-uuids refs options)
         block'
         (if (seq properties)
-          (let [parent-classes-from-properties (->> (select-keys properties property-parent-classes)
+          (let [parent-classes-from-properties (->> (select-keys properties (:property-parent-classes user-options))
                                                     (mapcat (fn [[_k v]] (if (coll? v) v [v])))
                                                     distinct)]
             (cond-> block
@@ -672,7 +674,9 @@
 
 (defn- handle-block-properties
   "Does everything page properties does and updates a couple of block specific attributes"
-  [{:block/keys [title] :as block*} db page-names-to-uuids refs {:keys [property-classes] :as options}]
+  [{:block/keys [title] :as block*}
+   db page-names-to-uuids refs
+   {{:keys [property-classes]} :user-options :as options}]
   (let [{:keys [block properties-tx]} (handle-page-and-block-properties block* db page-names-to-uuids refs options)
         advanced-query (some->> (second (re-find #"(?s)#\+BEGIN_QUERY(.*)#\+END_QUERY" title)) string/trim)
         additional-props (cond-> {}
@@ -787,7 +791,7 @@
                    (fix-pre-block-references pre-blocks page-names-to-uuids)
                    (fix-block-name-lookup-ref page-names-to-uuids)
                    (update-block-refs page-names-to-uuids options)
-                   (update-block-tags db (select-keys options [:convert-all-tags? :tag-classes :remove-inline-tags?]) page-names-to-uuids (:all-idents import-state))
+                   (update-block-tags db (:user-options options) page-names-to-uuids (:all-idents import-state))
                    (update-block-marker options)
                    (update-block-priority options)
                    add-missing-timestamps
@@ -860,7 +864,7 @@
         (seq (:block/alias m))
         (update-page-alias page-names-to-uuids)
         (:block/tags m)
-        (update-page-tags db (select-keys options [:tag-classes :convert-all-tags?]) page-names-to-uuids (:all-idents import-state))))))
+        (update-page-tags db (:user-options options) page-names-to-uuids (:all-idents import-state))))))
 
 (defn- modify-page-tx
   "Modifies page tx from graph-parser for use with DB graphs. Currently modifies
@@ -899,11 +903,12 @@
   "Given all the pages and blocks parsed from a file, return a map containing
   all non-whiteboard pages to be transacted, pages' properties and additional
   data for subsequent steps"
-  [conn pages blocks {:keys [property-classes property-parent-classes import-state]
+  [conn pages blocks {:keys [import-state user-options]
                       :as options}]
   (let [all-pages* (->> (extract/with-ref-pages pages blocks)
                         ;; remove unused property pages unless the page has content
-                        (remove #(and (contains? (into property-classes property-parent-classes) (keyword (:block/name %)))
+                        (remove #(and (contains? (into (:property-classes user-options) (:property-parent-classes user-options))
+                                                 (keyword (:block/name %)))
                                       (not (:block/file %))))
                         ;; remove file path relative
                         (map #(dissoc % :block/file)))
@@ -925,9 +930,8 @@
                                      ;; Don't build a new page if it overwrites an existing class
                                      (not (some-> (get @(:all-idents import-state) (keyword (:block/title m)))
                                                   db-malli-schema/class?)))
-                             (build-new-page-or-class (dissoc m ::original-name) @conn
-                                                      (select-keys options [:tag-classes :convert-all-tags?])
-                                                      page-names-to-uuids (:all-idents import-state)))))
+                             (build-new-page-or-class (dissoc m ::original-name)
+                                                      @conn user-options page-names-to-uuids (:all-idents import-state)))))
                        (map :block all-pages-m))]
     {:pages-tx pages-tx
      :page-properties-tx (mapcat :properties-tx all-pages-m)
@@ -1018,15 +1022,15 @@
     ;; Track per file changes to make to existing properties
     ;; Map of property names (keyword) and their changes (map)
     :upstream-properties (atom {})
-    :remove-inline-tags? (:remove-inline-tags? user-options)
-    :convert-all-tags? (:convert-all-tags? user-options)
-    :tag-classes (set (map string/lower-case (:tag-classes user-options)))
-    :property-classes (set/difference
-                       (set (map (comp keyword string/lower-case) (:property-classes user-options)))
-                       file-built-in-property-names)
-    :property-parent-classes (set/difference
-                              (set (map (comp keyword string/lower-case) (:property-parent-classes user-options)))
-                              file-built-in-property-names)}))
+    :user-options
+    (merge user-options
+           {:tag-classes (set (map string/lower-case (:tag-classes user-options)))
+            :property-classes (set/difference
+                               (set (map (comp keyword string/lower-case) (:property-classes user-options)))
+                               file-built-in-property-names)
+            :property-parent-classes (set/difference
+                                      (set (map (comp keyword string/lower-case) (:property-parent-classes user-options)))
+                                      file-built-in-property-names)})}))
 
 (defn- split-pages-and-properties-tx
   "Separates new pages from new properties tx in preparation for properties to
@@ -1143,7 +1147,8 @@
 
 * :extract-options - Options map to pass to extract/extract
 * :user-options - User provided options maps that alter how a file is converted to db graph. Current options
-   are :tag-classes (set) and :property-classes (set).
+   are: :tag-classes (set), :property-classes (set), :property-parent-classes (set), :convert-all-tags? (boolean)
+   and :remove-inline-tags? (boolean)
 * :import-state - useful import state to maintain across files e.g. property schemas or ignored properties
 * :macros - map of macros for use with macro expansion
 * :notify-user - Displays warnings to user without failing the import. Fn receives a map with :msg
@@ -1385,9 +1390,7 @@
                          :filename-format (or (:file/name-format config) :legacy)
                          :verbose (:verbose options)}
        :user-config config
-       :user-options (merge
-                      {:remove-inline-tags? true}
-                      (select-keys options [:tag-classes :property-classes :property-parent-classes :convert-all-tags? :remove-inline-tags?]))
+       :user-options (merge {:remove-inline-tags? true} (:user-options options))
        :import-state (new-import-state)
        :macros (or (:macros options) (:macros config))}
       (merge (select-keys options [:set-ui-state :export-file :notify-user]))))
@@ -1404,6 +1407,7 @@
    * :rpath-key - keyword used to get relative path in file map. Default to :path
    * :<read-file - fn which reads a file across multiple steps
    * :default-config - default config if config is unable to be read
+   * :user-options - map of user specific options. See add-file-to-db-graph for more
    * :<save-config-file - fn which saves a config file
    * :<save-logseq-file - fn which saves a logseq file
    * :<copy-asset - fn which copies asset file

+ 7 - 9
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -116,18 +116,18 @@
   (let [*files (build-graph-files file-graph-dir)
         config-file (first (filter #(string/ends-with? (:path %) "logseq/config.edn") *files))
         _ (assert config-file "No 'logseq/config.edn' found for file graph dir")
-        options' (-> (merge default-export-options
-                            options
-                            ;; asset file options
-                            {:<copy-asset #(swap! assets conj %)})
-                     (dissoc :assets))]
+        options' (merge default-export-options
+                        {:user-options (dissoc options :assets)
+                        ;; asset file options
+                         :<copy-asset #(swap! assets conj %)})]
     (gp-exporter/export-file-graph conn conn config-file *files options')))
 
 (defn- import-files-to-db
   "Import specific doc files for dev purposes"
   [files conn options]
   (p/let [doc-options (gp-exporter/build-doc-options (merge {:macros {}} (:user-config options))
-                                                     (merge default-export-options options))
+                                                     (merge default-export-options
+                                                            {:user-options (dissoc options :user-config)}))
           files' (mapv #(hash-map :path %) files)
           _ (gp-exporter/export-doc-files conn files' <read-file doc-options)]
     {:import-state (:import-state doc-options)}))
@@ -472,11 +472,9 @@
                (:logseq.property/page-tags (readable-properties @conn (find-page-by-name @conn "chat-gpt"))))
             "tagged page has new page and other pages marked with '#' and '[[]]` imported as tags to page-tags")))))
 
-(deftest-async export-basic-graph-with-convert-all-tags
+(deftest-async export-basic-graph-with-convert-all-tags-option
   (p/let [file-graph-dir "test/resources/exporter-test-graph"
           conn (db-test/create-conn)
-          ;; Simulate frontend path-refs being calculated
-          _ (db-pipeline/add-listener conn)
           {:keys [import-state]}
           (import-file-graph-to-db file-graph-dir conn {:convert-all-tags? true})]
 

+ 1 - 0
deps/shui/src/logseq/shui/popup/core.cljs

@@ -161,6 +161,7 @@
                              "bottom"
                              (if (> (- th bh) 100)
                                "top" "bottom"))))
+          auto-side? (if (boolean? auto-side?) auto-side? true)
           content-props (cond-> content-props
                           auto-side? (assoc :side (auto-side-fn)))
           hide (fn [] (hide! id 1))]

+ 3 - 3
packages/ui/src/vars-classic.css

@@ -49,7 +49,7 @@ html[data-theme=light][data-color=logseq] {
   --ls-active-secondary-color: #00477c;
   --ls-block-properties-background-color: var(--ls-secondary-background-color);
   --ls-page-properties-background-color: var(--ls-secondary-background-color);
-  --ls-block-ref-link-text-color: #d8e1e8;
+  --ls-block-ref-link-text-color: var(--ls-link-text-color);
   --ls-border-color: #ccc;
   --ls-secondary-border-color: #e2e2e2;
   --ls-tertiary-border-color: rgba(200, 200, 200, 0.3);
@@ -107,7 +107,7 @@ html[data-theme=dark][data-color=logseq] {
   --ls-active-secondary-color: #d0e8e8;
   --ls-block-properties-background-color: #06323e;
   --ls-page-properties-background-color: #06323e;
-  --ls-block-ref-link-text-color: #1a6376;
+  --ls-block-ref-link-text-color: #377f91;
   --ls-border-color: #0e5263;
   --ls-secondary-border-color: #126277;
   --ls-tertiary-border-color: rgba(0, 2, 0, 0.1);
@@ -159,4 +159,4 @@ html[data-theme=dark][data-color=logseq] {
   --color-level-4: #195d6c;
   --color-level-5: #266c7d;
   --color-level-6: #3a7e8e;
-}
+}

+ 3 - 3
resources/css/codemirror.lsradix.css

@@ -100,9 +100,9 @@ http://ethanschoonover.com/lsradix/img/lsradix-palette.png
   border-bottom: 1px dotted or(--rx-red-11, #dc322f);
 }
 
-.cm-s-lsradix.cm-s-dark div.CodeMirror-selected { background: or(--lx-gray-06, #073642); }
-.cm-s-lsradix.cm-s-dark.CodeMirror ::selection { background: or(--lx-gray-06, rgba(7, 54, 66, 0.99)); }
-.cm-s-lsradix.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: or(--lx-gray-06, rgba(7, 54, 66, 0.99)); }
+.cm-s-lsradix.cm-s-dark div.CodeMirror-selected { background: or(--lx-gray-06, rgb(4 38 47 / 99%)); }
+.cm-s-lsradix.cm-s-dark.CodeMirror ::selection { background: or(--lx-gray-06, rgb(4 38 47 / 99%)); }
+.cm-s-lsradix.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: or(--lx-gray-06, rgb(4 38 47 / 99%)); }
 
 .cm-s-lsradix.cm-s-light div.CodeMirror-selected { background: or(--lx-gray-06, #eee8d5); }
 .cm-s-lsradix.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: or(--lx-gray-06, #eee8d5); }

+ 45 - 42
src/main/frontend/components/block.cljs

@@ -819,43 +819,47 @@
         [visible? set-visible!] (rum/use-state nil)
         ;; set-visible! (fn debug-visible [v] (js/console.warn "debug: visible" v) (set-visible! v))
         _  #_:clj-kondo/ignore (rum/defc preview-render []
-                                 (rum/use-effect!
-                                  (fn []
-                                    (let [el-popup (rum/deref *el-popup)
-                                          focus! #(js/setTimeout (fn [] (.focus el-popup)))]
-                                      (focus!)
-                                      #(set-visible! false)))
-                                  [])
-
-                                 (when-let [source (or (db/get-alias-source-page (state/get-current-repo) (:db/id page-entity))
+                                 (let [[ready? set-ready!] (rum/use-state false)]
+
+                                   (rum/use-effect!
+                                     (fn []
+                                       (let [el-popup (rum/deref *el-popup)
+                                             focus! #(js/setTimeout (fn [] (.focus el-popup)))]
+                                         (set-ready! true)
+                                         (focus!)
+                                         (fn [] (set-visible! false))))
+                                     [])
+
+                                   (when-let [source (or (db/get-alias-source-page (state/get-current-repo) (:db/id page-entity))
                                                        page-entity)]
-                                   [:div.tippy-wrapper.as-page
-                                    {:ref *el-popup
-                                     :tab-index -1
-                                     :style {:width 600
-                                             :text-align "left"
-                                             :font-weight 500
-                                             :padding-bottom 64}
-                                     :on-mouse-enter (fn []
-                                                       (when-let [timer1 (rum/deref *timer1)]
-                                                         (js/clearTimeout timer1)))
-                                     :on-mouse-leave (fn []
+                                     [:div.tippy-wrapper.as-page
+                                      {:ref *el-popup
+                                       :tab-index -1
+                                       :style {:width 600
+                                               :text-align "left"
+                                               :font-weight 500
+                                               :padding-bottom 64}
+                                       :on-mouse-enter (fn []
+                                                         (when-let [timer1 (rum/deref *timer1)]
+                                                           (js/clearTimeout timer1)))
+                                       :on-mouse-leave (fn []
                                                          ;; check the top popup whether is the preview popup
-                                                       (when (ui/last-shui-preview-popup?)
-                                                         (rum/set-ref! *timer1
-                                                                       (js/setTimeout #(set-visible! false) 500))))}
-                                    (let [page-cp (state/get-page-blocks-cp)]
-                                      (page-cp {:repo (state/get-current-repo)
-                                                :page-name (str (:block/uuid source))
-                                                :sidebar? sidebar?
-                                                :preview? true}))]))]
+                                                         (when (ui/last-shui-preview-popup?)
+                                                           (rum/set-ref! *timer1
+                                                             (js/setTimeout #(set-visible! false) 500))))}
+                                      (when-let [page-cp (and ready? (state/get-page-blocks-cp))]
+                                        (page-cp {:repo (state/get-current-repo)
+                                                  :page-name (str (:block/uuid source))
+                                                  :sidebar? sidebar?
+                                                  :scroll-container (some-> (rum/deref *el-popup) (.closest ".ls-preview-popup"))
+                                                  :preview? true}))])))]
 
     (rum/use-effect!
-     (fn []
-       (if (some-> (rum/deref *el-wrap) (.closest "[data-radix-popper-content-wrapper]"))
-         (set-in-popup! true)
-         (set-in-popup! false)))
-     [])
+      (fn []
+        (if (some-> (rum/deref *el-wrap) (.closest "[data-radix-popper-content-wrapper]"))
+          (set-in-popup! true)
+          (set-in-popup! false)))
+      [])
 
     [:span {:ref *el-wrap}
      (if (boolean? in-popup?)
@@ -4014,7 +4018,8 @@
         *virtualized-ref (rum/use-ref nil)
         virtual-opts (when virtualized?
                        {:ref *virtualized-ref
-                        :custom-scroll-parent (gdom/getElement "main-content-container")
+                        :custom-scroll-parent (or (:scroll-container config)
+                                                (gdom/getElement "main-content-container"))
                         :compute-item-key (fn [idx]
                                             (let [block (nth blocks idx)]
                                               (str (:container-id config) "-" (:db/id block))))
@@ -4027,12 +4032,12 @@
                                               bottom? (= (dec (count blocks)) idx)
                                               block (nth blocks idx)]
                                           (block-item (assoc config :top? top?)
-                                                      block
-                                                      {:top? top?
-                                                       :bottom? bottom?})))})
+                                            block
+                                            {:top? top?
+                                             :bottom? bottom?})))})
         *wrap-ref (rum/use-ref nil)]
     (rum/use-effect!
-     (fn []
+      (fn []
        (when virtualized?
          (when (:current-page? config)
            (let [ref (.-current *virtualized-ref)]
@@ -4168,10 +4173,8 @@
      (and (:ref? config) (:group-by-page? config) (vector? (first blocks)))
      [:div.flex.flex-col.references-blocks-wrap
       (let [blocks (sort-by (comp :block/journal-day first) > blocks)
-            scroll-container (or
-                              (when-let [*ref (:scroll-container config)]
-                                (rum/deref *ref))
-                              (gdom/getElement "main-content-container"))]
+            scroll-container (or (:scroll-container config)
+                               (gdom/getElement "main-content-container"))]
         (when (seq blocks)
           (if (:sidebar? config)
             (for [block blocks]

+ 7 - 7
src/main/frontend/components/imports.cljs

@@ -321,7 +321,7 @@
 
 (defn- import-file-graph
   [*files
-   {:keys [graph-name tag-classes convert-all-tags? property-classes property-parent-classes remove-inline-tags?]}
+   {:keys [graph-name tag-classes property-classes property-parent-classes] :as user-options}
    config-file]
   (state/set-state! :graph/importing :file-graph)
   (state/set-state! [:graph/importing-state :current-page] "Config files")
@@ -329,12 +329,12 @@
           _ (repo-handler/new-db! graph-name {:file-graph-import? true})
           repo (state/get-current-repo)
           db-conn (db/get-db repo false)
-          options {;; user options
-                   :tag-classes (set (string/split tag-classes #",\s*"))
-                   :property-classes (set (string/split property-classes #",\s*"))
-                   :property-parent-classes (set (string/split property-parent-classes #",\s*"))
-                   :convert-all-tags? convert-all-tags?
-                   :remove-inline-tags? remove-inline-tags?
+          options {:user-options
+                   (merge
+                    (dissoc user-options :graph-name)
+                    {:tag-classes (some-> tag-classes string/trim not-empty  (string/split #",\s*") set)
+                     :property-classes (some-> property-classes string/trim not-empty  (string/split #",\s*") set)
+                     :property-parent-classes (some-> property-parent-classes string/trim not-empty  (string/split #",\s*") set)})
                    ;; common options
                    :notify-user show-notification
                    :set-ui-state state/set-state!

+ 4 - 7
src/main/frontend/components/property/value.cljs

@@ -115,7 +115,7 @@
     (shui/popup-hide!)
     (shui/dialog-close!))
   (p/let [block
-          (if (and (= :default (get-in property [:block/schema :type]))
+          (if (and (contains? #{:default :url} (get-in property [:block/schema :type]))
                    (not (db-property/many? property)))
             (p/let [existing-value (get block (:db/ident property))
                     existing-value? (and (some? existing-value)
@@ -806,10 +806,7 @@
        (closed-value-item value opts)
 
        (de/entity? value)
-       (when-some [content (if (some? (:property.value/content value))
-                             ;; content needs to be a string for display purposes
-                             (str (:property.value/content value))
-                             (:block/title value))]
+       (when-some [content (str (db-property/property-value-content value))]
          (inline-text-cp content))
 
        :else
@@ -872,10 +869,10 @@
     [:div.cursor-text
      {:id (or dom-id (random-uuid))
       :tabIndex 0
-      :class (str class " " (when-not (= type :default) "jtrigger"))
+      :class (str class " " (when-not (contains? #{:default :url} type) "jtrigger"))
       :style {:min-height 24}
       :on-click (fn []
-                  (when (and (= type :default) (nil? value))
+                  (when (and (contains? #{:default :url} type) (nil? value))
                     (<create-new-block! block property "")))}
      (cond
        (and (contains? #{:default :url} type) (nil? (:block/title value)))

+ 0 - 1
src/main/frontend/components/reference.cljs

@@ -49,7 +49,6 @@
     [:div.references-blocks.faster.fade-in {:ref *ref}
      (let [ref-hiccup (block/->hiccup filtered-ref-blocks
                                       {:id (str (:block/uuid page-entity))
-                                       :scroll-container *ref
                                        :ref? true
                                        :breadcrumb-show? true
                                        :group-by-page? true

+ 6 - 1
src/main/frontend/components/right_sidebar.cljs

@@ -41,11 +41,16 @@
                    :sidebar/idx idx
                    :repo        repo})))
 
+(defn get-scrollable-container
+  []
+  (js/document.querySelector ".sidebar-item-list"))
+
 (rum/defc page-cp < rum/reactive
   [repo page-name]
   (page/page-cp {:parameters {:path {:name page-name}}
                  :sidebar?   true
-                 :repo       repo}))
+                 :scroll-container (get-scrollable-container)
+                 :repo repo}))
 
 (rum/defc shortcut-settings
   []

+ 12 - 12
src/main/frontend/components/settings.cljs

@@ -149,13 +149,12 @@
            :height 500}]]])
 
 (defn row-with-button-action
-  [{:keys [left-label description action button-label href on-click desc -for stretch center?]
-    :or {center? true}}]
+  [{:keys [left-label description action button-label href on-click desc -for stretch]}]
   [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4
-   {:class (if center? "sm:items-center" "sm:items-start")}
+   {:class "sm:items-start"}
    ;; left column
    [:div.flex.flex-col
-    [:label.block.text-sm.font-medium.leading-5.opacity-70.pt-2
+    [:label.block.text-sm.font-medium.leading-5.opacity-70
      {:for -for}
      left-label]
     (when description
@@ -236,18 +235,19 @@
       (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
+  [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4
    [: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
+   [:div.col-span-2.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]")
+        :class (when active? " border-primary border-[2px]")
+        :style {:width "4.4rem"}
         :on-click #(state/set-editor-font! t)}
        [:span.flex.flex-col
         {:class (str "ls-font-" t)}
@@ -379,7 +379,7 @@
                     (for [color (concat [:none :logseq] colors/color-list)
                           :let [active? (= color color-accent)
                                 none? (= color :none)]]
-                      [:div.flex.items-center {:style {:height 28}}
+                      [:div.flex.items-center
                        (ui/tippy
                         {:html (case color
                                  :none [:p {:style {:max-width "300px"}}
@@ -412,7 +412,7 @@
                             (shortcut-helper/gen-shortcut-seq :ui/customize-appearance))])
        :stretch (boolean _in-modal?)
        :action pick-theme})
-     [:div.text-sm.opacity-50
+     [:div.text-sm.opacity-50.mt-1
       (t :settings-page/accent-color-alert)]]))
 
 (rum/defc appearance < rum/reactive
@@ -729,11 +729,13 @@
 (rum/defcs settings-general < rum/reactive
   [_state current-repo]
   (let [preferred-language (state/sub [:preferred-language])
-        show-radix-themes? true]
+        show-radix-themes? true
+        editor-font (state/sub :ui/editor-font)]
     [:div.panel-wrap.is-general
      (version-row t fv/version)
      (language-row t preferred-language)
      (theme-modes-row t)
+     (editor-font-family-row t editor-font)
      (when (and (util/electron?) (not util/mac?)) (native-titlebar-row t))
      (when show-radix-themes? (accent-color-row false))
      (when (config/global-config-enabled?) (edit-global-config-edn))
@@ -773,7 +775,6 @@
         enable-shortcut-tooltip? (state/sub :ui/shortcut-tooltip?)
         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)
         db-graph? (config/db-based-graph? (state/get-current-repo))]
 
@@ -783,7 +784,6 @@
      (date-format-row t preferred-date-format)
      (when-not db-graph?
        (workflow-row t preferred-workflow))
-     (editor-font-family-row t editor-font)
      (show-brackets-row t show-brackets?)
      (toggle-wide-mode-row t wide-mode?)
 

+ 4 - 28
src/main/frontend/components/settings.css

@@ -31,7 +31,7 @@
 
     > article {
       @apply p-4 flex-1 min-h-[12rem] w-screen overflow-y-auto;
-      @apply md:max-h-[70vh] md:w-[44rem];
+      @apply md:h-[70vh] md:w-[44rem];
     }
 
     > aside > .cp__settings-header,
@@ -89,7 +89,7 @@
     }
 
     .panel-wrap {
-      @apply p-1;
+      @apply p-1 flex flex-col gap-4;
 
       @screen sm {
         width: 600px;
@@ -98,9 +98,6 @@
       > .it {
         @apply sm:grid sm:grid-cols-3 sm:gap-6;
 
-        margin-bottom: 0;
-        padding-bottom: 12px;
-
         label {
           min-height: 28px;
           line-height: 28px;
@@ -149,19 +146,6 @@
         }
       }
 
-      &.is-general {
-        > .it {
-          margin-bottom: 8px;
-        }
-
-      }
-
-      &.is-advanced {
-        > .it {
-          margin-bottom: 8px;
-        }
-      }
-
       span[role="checkbox"] {
         &:hover {
           opacity: .8;
@@ -251,15 +235,7 @@
   }
 
   &-appearance-modal-inner {
-    @apply -m-2 -mb-3;
-
-    & > .it {
-      @apply mb-3;
-    }
-
-    label[for=toggle_radix_theme] {
-      @apply pt-2;
-    }
+    @apply -m-2 -mb-3 flex flex-col gap-4;
 
     .keyboard-shortcut {
       @apply relative -top-[3px];
@@ -512,4 +488,4 @@ body[data-settings-tab=keymap] {
       @apply grid-cols-8 pb-1 ml-1 max-w-[320px];
     }
   }
-}
+}

+ 3 - 3
src/main/frontend/extensions/fsrs.cljs

@@ -175,13 +175,13 @@
                                          [:dd "We got the answer wrong. Automatically means that we have forgotten the card. This is a lapse in memory."]]
                                         [:dl
                                          [:dt "Hard"]
-                                         [:dd "The answer was only partially correct and/or we took too long to recall it."]]
+                                         [:dd "The answer was correct but we were not confident about it and/or took too long to recall."]]
                                         [:dl
                                          [:dt "Good"]
-                                         [:dd "The answer was correct but we were not confident about it."]]
+                                         [:dd "The answer was correct but we took some mental effort to recall it."]]
                                         [:dl
                                          [:dt "Easy"]
-                                         [:dd "The answer was correct and we were confident and quick in our recall."]]])
+                                         [:dd "The answer was correct and we were confident and quick in our recall without mental effort."]]])
                                      {:align "start"}))}
       (ui/icon "info-circle"))]))
 

+ 1 - 1
src/main/frontend/handler/editor.cljs

@@ -3249,7 +3249,7 @@
       (state/selection?)
       (shortcut-copy-selection e)
 
-      (state/editing?)
+      (and (state/editing?) (nil? (:editor/code-block-context @state/state)))
       (let [input (state/get-input)
             selected-start (util/get-selection-start input)
             selected-end (util/get-selection-end input)]

+ 45 - 34
src/main/frontend/handler/jump.cljs

@@ -88,42 +88,53 @@
 
 (defn jump-to
   []
-  (let [selected-block-or-page (or (first (state/get-selection-blocks))
-                                   ;; current edited block
-                                   (some-> (:block-parent-id (first (state/get-editor-args)))
-                                           js/document.getElementById)
-                                   ;; current page
-                                   (d/sel1 js/document "#main-content-container .ls-properties-area"))]
+  (let [current-block-id (or (:block/uuid (state/get-edit-block))
+                             (first (state/get-selection-block-ids))
+                             (:block/uuid (db/get-page (state/get-current-page))))]
     (cond
-      selected-block-or-page
+      current-block-id
       (when (empty? (d/sel js/document ".jtrigger-id"))
-        (let [triggers (d/sel selected-block-or-page ".jtrigger")]
-          (when (seq triggers)
-            (reset! *jump-data {:mode :property
-                                :triggers triggers})
-            (let [keys (generate-keys (count triggers))
-                  key-down-handler (fn [e]
-                                     (let [k (util/ekey e)]
-                                       (if (= k "Escape")
-                                         (exit!)
-                                         (when (and (contains? full-start-keys k) (seq (:triggers @*jump-data)))
-                                           (swap! *jump-data update :chords (fn [s] (str s (util/ekey e))))
-                                           (let [chords (:chords @*jump-data)]
-                                             (trigger! chords e))))))]
-              (swap! *jump-data assoc :key-down-handler key-down-handler)
-              (reset! *current-keys keys)
-              (doall
-               (map-indexed
-                (fn [id dom]
-                  (let [class (if (d/has-class? dom "ui__checkbox")
-                                "jtrigger-id text-sm border rounded ml-4 px-1 shadow-xs"
-                                "jtrigger-id text-sm border rounded ml-2 px-1 shadow-xs")
-                        ^js view (or (.closest dom ".jtrigger-view") dom)]
-                    (d/append! view (-> (d/create-element :div)
-                                      (d/set-attr! :class class)
-                                      (d/set-text! (nth keys id))))))
-                (take (count keys) triggers)))
-              (.addEventListener js/window "keydown" key-down-handler)))))
+        (let [current-block (when (uuid? current-block-id)
+                              (db/entity [:block/uuid current-block-id]))
+              collapsed? (or (state/get-block-collapsed current-block-id) (:block/collapsed? current-block))]
+          (when collapsed?
+            (editor-handler/expand-block! current-block-id))
+          (let [f #(let [selected-block-or-page (or (first (state/get-selection-blocks))
+                                   ;; current edited block
+                                                    (some-> (:block-parent-id (first (state/get-editor-args)))
+                                                            js/document.getElementById)
+                                   ;; current page
+                                                    (d/sel1 js/document "#main-content-container .ls-properties-area"))
+                         triggers (d/sel selected-block-or-page ".jtrigger")]
+                     (when (seq triggers)
+                       (reset! *jump-data {:mode :property
+                                           :triggers triggers})
+                       (let [keys (generate-keys (count triggers))
+                             key-down-handler (fn [e]
+                                                (let [k (util/ekey e)]
+                                                  (if (= k "Escape")
+                                                    (exit!)
+                                                    (when (and (contains? full-start-keys k) (seq (:triggers @*jump-data)))
+                                                      (swap! *jump-data update :chords (fn [s] (str s (util/ekey e))))
+                                                      (let [chords (:chords @*jump-data)]
+                                                        (trigger! chords e))))))]
+                         (swap! *jump-data assoc :key-down-handler key-down-handler)
+                         (reset! *current-keys keys)
+                         (doall
+                          (map-indexed
+                           (fn [id dom]
+                             (let [class (if (d/has-class? dom "ui__checkbox")
+                                           "jtrigger-id text-sm border rounded ml-4 px-1 shadow-xs"
+                                           "jtrigger-id text-sm border rounded ml-2 px-1 shadow-xs")
+                                   ^js view (or (.closest dom ".jtrigger-view") dom)]
+                               (d/append! view (-> (d/create-element :div)
+                                                   (d/set-attr! :class class)
+                                                   (d/set-text! (nth keys id))))))
+                           (take (count keys) triggers)))
+                         (.addEventListener js/window "keydown" key-down-handler))))]
+            (if collapsed?
+              (js/setTimeout f 100)
+              (f)))))
 
       :else                             ; add block jump support
       nil)))

+ 1 - 1
src/resources/dicts/en.edn

@@ -246,7 +246,7 @@
  :settings-page/export-theme "Export theme"
  :settings-page/show-brackets "Show brackets"
  :settings-page/wide-mode "Wide mode"
- :settings-page/editor-font "Editor font"
+ :settings-page/editor-font "Font"
  :settings-page/accent-color "Accent color"
  :settings-page/accent-color-alert "Choosing an accent color may override any theme you have selected."
  :settings-page/spell-checker "Spell checker"