Explorar o código

Merge branch 'master' into feat/db

charlie hai 1 ano
pai
achega
97a017df9b

+ 2 - 2
android/app/build.gradle

@@ -7,8 +7,8 @@ android {
         applicationId "com.logseq.app"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
-        versionCode 80
-        versionName "0.10.6"
+        versionCode 81
+        versionName "0.10.7"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
              // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

+ 25 - 60
deps/shui/src/logseq/shui/list_item/v1.cljs

@@ -3,77 +3,42 @@
     ["remove-accents" :as remove-accents]
     [rum.core :as rum]
     [clojure.string :as string]
+    [goog.string :as gstring]
     [logseq.shui.icon.v2 :as icon]
     [logseq.shui.shortcut.v1 :as shortcut]))
 
 (def to-string shortcut/to-string)
 
-(defn normalize-text [app-config text]
+(defn- normalize-text [app-config text]
   (cond-> (to-string text)
-    :lower-case (string/lower-case)
+    ;; :lower-case (string/lower-case)
     :normalize (.normalize "NFKC")
     (:feature/enable-search-remove-accents? app-config) (remove-accents)))
 
-(defn split-text-on-highlight [text query normal-text normal-query]
-  (let [start-index (string/index-of normal-text normal-query)
-        end-index (+ start-index (count query))
-        text-string (to-string text)]
-    (if start-index
-      [(to-string (subs text-string 0 start-index))
-       (to-string (subs text-string start-index end-index))
-       (to-string (subs text-string end-index))]
-      [text-string "" ""])))
-
-
-(defn span-with-single-highlight-token [text query normal-text normal-query]
-  (let [[before-text highlighted-text after-text] (split-text-on-highlight text query normal-text normal-query)]
-    [:span
-     (when-not (string/blank? before-text) [:span before-text])
-     (when-not (string/blank? highlighted-text) [:span {:class "ui__list-item-highlighted-span bg-accent-06 dark:bg-accent-08-alpha"} highlighted-text])
-     (when-not (string/blank? after-text) [:span after-text])]))
-
-(defn span-with-multiple-highlight-tokens [app-config text normal-query]
-  (let [normalized-text (normalize-text app-config text)]
-    (loop [[query-token & more] (string/split normal-query #" ")
-           result [[:text (to-string text)]]]
-      (if-not query-token
-        (->> result
-             (map (fn [[type value]]
-                    (if (= type :text)
-                      [:span value]
-                      [:span {:class "ui__list-item-highlighted-span"} value])))
-             (into [:span]))
-        (->> result
-             (mapcat (fn [[type value]]
-                       (let [include-token? (and (= type :text) (string? value)
-                                                 (string/includes? normalized-text query-token))]
-                         (if include-token?
-                           (let [normal-value (normalize-text app-config value)
-                                 normal-query-token (normalize-text app-config query-token)
-                                 [before-text highlighted-text after-text] (split-text-on-highlight value query-token normal-value normal-query-token)]
-                             [[:text before-text]
-                              [:match highlighted-text]
-                              [:text after-text]])
-                           [[type value]]))))
-             (recur more))))))
-
 (defn highlight-query* [app-config query text]
-  (if (or (vector? text) (object? text))                    ; hiccup
+  (cond
+    (or (vector? text) (object? text))                                     ; hiccup
     text
-    (let [text-string (to-string text)]
-      (if-not (seq text-string)
-        [:span text-string]
-        (let [normal-text (normalize-text app-config text-string)
-              normal-query (normalize-text app-config query)]
-          (cond
-            (and (string? query) (re-find #" " query))
-            (span-with-multiple-highlight-tokens app-config text-string normal-query)
-          ;; When the match is present and only a single token, highlight that token
-            (string/includes? normal-text normal-query)
-            (span-with-single-highlight-token text-string query normal-text normal-query)
-          ;; Otherwise, just return the text
-            :else
-            [:span text-string]))))))
+
+    (string/blank? query)
+    [:span (to-string text)]
+
+    :else
+    (when-let [text-string (not-empty (to-string text))]
+      (let [normal-text (normalize-text app-config text-string)
+            normal-query (normalize-text app-config query)
+            query-terms (string/replace (gstring/regExpEscape normal-query) #"\s+" "|")
+            query-re (js/RegExp. (str "(" query-terms ")") "i")
+            highlighted-text (string/replace normal-text query-re "<:hlmarker>$1<:hlmarker>")
+            segs (string/split highlighted-text #"<:hlmarker>")]
+        (if (seq segs)
+          (into [:span]
+                (map-indexed (fn [i seg]
+                               (if (even? i)
+                                 [:span seg]
+                                 [:span {:class "ui__list-item-highlighted-span"} seg]))
+                             segs))
+          [:span normal-text])))))
 
 (rum/defc root [{:keys [icon icon-theme query text info shortcut value-label value
                         title highlighted on-highlight on-highlight-dep header on-click

+ 1 - 1
e2e-tests/page-search.spec.ts

@@ -157,7 +157,7 @@ async function alias_test(block: Block, page: Page, page_name: string, search_kw
     const results = await searchPage(page, kw_name)
 
     // test search results
-    expect(await results[0].innerText()).toContain(alias_name)
+    expect(await results[0].innerText()).toContain(alias_name.normalize('NFKC'))
 
     // test search entering (page)
     page.keyboard.press("Enter")

+ 1 - 1
resources/forge.config.js

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

+ 1 - 1
resources/package.json

@@ -1,7 +1,7 @@
 {
   "name": "Logseq",
   "productName": "Logseq",
-  "version": "0.10.6",
+  "version": "0.10.7",
   "main": "electron.js",
   "author": "Logseq",
   "license": "AGPL-3.0",

+ 57 - 55
src/electron/electron/git.cljs

@@ -13,8 +13,8 @@
 (def log-error (partial logger/error "[Git]"))
 
 (defn get-graph-git-dir
-  []
-  (when-let [graph-path (some-> (state/get-graph-path)
+  [graph-path]
+  (when-let [graph-path (some-> graph-path
                                 (string/replace "/" "_")
                                 (string/replace ":" "comma"))]
     (let [dir (.join node-path (.homedir os) ".logseq" "git" graph-path ".git")]
@@ -22,38 +22,35 @@
       dir)))
 
 (defn run-git!
-  [commands]
-  (when-let [path (state/get-graph-path)]
-    (when (fs/existsSync path)
-      (p/let [result (.exec GitProcess commands path)]
-        (if (zero? (gobj/get result "exitCode"))
-          (let [result (gobj/get result "stdout")]
-            (p/resolved result))
-          (let [error (gobj/get result "stderr")]
-            (when-not (string/blank? error)
-              (log-error error))
-            (p/rejected error)))))))
+  [graph-path commands]
+  (when (and graph-path (fs/existsSync graph-path))
+    (p/let [result (.exec GitProcess commands graph-path)]
+      (if (zero? (gobj/get result "exitCode"))
+        (let [result (gobj/get result "stdout")]
+          (p/resolved result))
+        (let [error (gobj/get result "stderr")]
+          (when-not (string/blank? error)
+            (log-error error))
+          (p/rejected error))))))
 
 (defn run-git2!
-  [commands]
-  (when-let [path (state/get-graph-path)]
-    (when (fs/existsSync path)
-      (p/let [^js result (.exec GitProcess commands path)]
-        result))))
+  [graph-path commands]
+  (when (and graph-path (fs/existsSync graph-path))
+    (p/let [^js result (.exec GitProcess commands graph-path)]
+      result)))
 
 (defn git-dir-exists?
-  []
+  [graph-path]
   (try
-    (let [p (.join node-path (state/get-graph-path) ".git")]
+    (let [p (.join node-path graph-path ".git")]
       (.isDirectory (fs/statSync p)))
     (catch :default _e
       nil)))
 
 (defn remove-dot-git-file!
-  []
+  [graph-path]
   (try
-    (let [graph-path (state/get-graph-path)
-          _ (when (string/blank? graph-path)
+    (let [_ (when (string/blank? graph-path)
               (utils/send-to-renderer :setCurrentGraph {})
               (throw (js/Error. "Empty graph path")))
           p (.join node-path graph-path ".git")]
@@ -70,23 +67,23 @@
       (log-error e))))
 
 (defn init!
-  []
-  (let [_ (remove-dot-git-file!)
-        separate-git-dir (get-graph-git-dir)
+  [graph-path]
+  (let [_ (remove-dot-git-file! graph-path)
+        separate-git-dir (get-graph-git-dir graph-path)
         args (cond
-               (git-dir-exists?)
+               (git-dir-exists? graph-path)
                ["init"]
                separate-git-dir
                ["init" (str "--separate-git-dir=" separate-git-dir)]
                :else
                ["init"])]
-    (p/let [_ (run-git! (clj->js args))]
+    (p/let [_ (run-git! graph-path (clj->js args))]
       (when utils/win32?
-        (run-git! #js ["config" "core.safecrlf" "false"])))))
+        (run-git! graph-path #js ["config" "core.safecrlf" "false"])))))
 
 (defn add-all!
-  []
-  (-> (run-git! #js ["add" "--ignore-errors" "./*"])
+  [graph-path]
+  (-> (run-git! graph-path #js ["add" "--ignore-errors" "./*"])
       (p/catch (fn [error]
                  (let [error (string/lower-case (str error))]
                    (if (or (string/includes? error "permission denied")
@@ -97,33 +94,38 @@
 ;; git log -100 --oneline -p ~/Desktop/org/pages/contents.org
 
 (defn commit!
-  [message]
-  (p/let [_ (run-git! #js ["config" "core.quotepath" "false"])]
-    (run-git! #js ["commit" "-m" message])))
+  [graph-path message]
+  (p/do!
+   (run-git! graph-path #js ["config" "core.quotepath" "false"])
+   (run-git! graph-path #js ["commit" "-m" message])))
+
+(defn add-all-and-commit-single-graph!
+  [graph-path message]
+  (let [message (if (string/blank? message)
+                  "Auto saved by Logseq"
+                  message)]
+    (->
+     (p/let [_ (init! graph-path)
+             _ (add-all! graph-path)]
+       (commit! graph-path message))
+     (p/catch (fn [error]
+                (when (and
+                       (string? error)
+                       (not (string/blank? error)))
+                  (if (string/starts-with? error "Author identity unknown")
+                    (utils/send-to-renderer "setGitUsernameAndEmail" {:type "git"})
+                    (utils/send-to-renderer "notification" {:type "error"
+                                                            :payload (str error "\nIf you don't want to see those errors or don't need git, you can disable the \"Git auto commit\" feature on Settings > Version control.")}))))))))
 
 (defn add-all-and-commit!
   ([]
    (add-all-and-commit! nil))
   ([message]
-   (let [message (if (string/blank? message)
-                   "Auto saved by Logseq"
-                   message)]
-     (->
-      (p/let [_ (init!)
-              _ (add-all!)]
-        (commit! message))
-      (p/catch (fn [error]
-                 (when (and
-                        (string? error)
-                        (not (string/blank? error)))
-                   (if (string/starts-with? error "Author identity unknown")
-                     (utils/send-to-renderer "setGitUsernameAndEmail" {:type "git"})
-                     (utils/send-to-renderer "notification" {:type "error"
-                                                             :payload (str error "\nIf you don't want to see those errors or don't need git, you can disable the \"Git auto commit\" feature on Settings > Version control.")})))))))))
+   (doseq [path (state/get-all-graph-paths)] (add-all-and-commit-single-graph! path message))))
 
 (defn short-status!
-  []
-  (run-git! #js ["status" "--porcelain"]))
+  [graph-path]
+  (run-git! graph-path #js ["status" "--porcelain"]))
 
 (defonce quotes-regex #"\"[^\"]+\"")
 (defn wrapped-by-quotes?
@@ -151,8 +153,8 @@
          (remove string/blank?))))
 
 (defn raw!
-  [args]
-  (init!)
+  [graph-path args]
+  (init! graph-path)
   (let [args (if (string? args)
                (split-args args)
                args)
@@ -165,8 +167,8 @@
                           (p/rejected error)))]
     (->
      (p/let [_ (when (= (first args) "commit")
-                 (add-all!))
-             result (run-git! (clj->js args))]
+                 (add-all! graph-path))
+             result (run-git! graph-path (clj->js args))]
        (p/resolved result))
      (p/catch error-handler))))
 

+ 9 - 10
src/electron/electron/handler.cljs

@@ -434,7 +434,6 @@
   (let [old-path (state/get-window-graph-path window)]
     (when (and old-path graph-path (not= old-path graph-path))
       (close-watcher-when-orphaned! window old-path))
-    (swap! state/state assoc :graph/current graph-path)
     (swap! state/state assoc-in [:window/graph window] graph-path)
     nil))
 
@@ -442,14 +441,14 @@
   (when graph-name
     (set-current-graph! window (utils/get-graph-dir graph-name))))
 
-(defmethod handle :runGit [_ [_ args]]
-  (when (seq args)
-    (git/raw! args)))
+(defmethod handle :runGit [_ [_ {:keys [repo command]}]]
+  (when (seq command)
+    (git/raw! (utils/get-graph-dir repo) command)))
 
-(defmethod handle :runGitWithinCurrentGraph [_ [_ args]]
-  (when (seq args)
-    (git/init!)
-    (git/run-git2! (clj->js args))))
+(defmethod handle :runGitWithinCurrentGraph [_ [_ {:keys [repo command]}]]
+  (when (seq command)
+    (git/init! (utils/get-graph-dir repo))
+    (git/run-git2! (utils/get-graph-dir repo) (clj->js command))))
 
 (defmethod handle :runCli [window [_ {:keys [command args returnResult]}]]
   (try
@@ -472,8 +471,8 @@
 (defmethod handle :gitCommitAll [_ [_ message]]
   (git/add-all-and-commit! message))
 
-(defmethod handle :gitStatus [_ [_]]
-  (git/short-status!))
+(defmethod handle :gitStatus [_ [_ repo]]
+  (git/short-status! (utils/get-graph-dir repo)))
 
 (def debounced-configure-auto-commit! (debounce git/configure-auto-commit! 5000))
 (defmethod handle :setGitAutoCommit []

+ 15 - 7
src/electron/electron/state.cljs

@@ -5,9 +5,6 @@
 (defonce state
   (atom {:config (config/get-config)
 
-         ;; FIXME: replace with :window/graph
-         :graph/current nil
-
          ;; window -> current graph
          :window/graph {}
 
@@ -33,15 +30,26 @@
   []
   (get-in @state [:config :git/commit-on-close?] false))
 
-(defn get-graph-path
-  []
-  (:graph/current @state))
-
 (defn get-window-graph-path
   "Get the path of the graph of a window (might be `nil`)"
   [window]
   (get (:window/graph @state) window))
 
+(defn get-all-graph-paths
+  "Get the paths of all graphs currently open in all windows."
+  []
+  (set (vals (:window/graph @state))))
+
+(defn get-active-window-graph-path
+  "Get the path of the graph of the currently focused window (might be `nil`)"
+  []
+  (let [windows (:window/graph @state)
+        active-windows-pairs (filter #(.isFocused (first %)) windows)
+        active-window-pair (first active-windows-pairs)
+        path (second active-window-pair)]
+    path)
+  )
+
 (defn close-window!
   [window]
   (swap! state medley/dissoc-in [:window/graph window]))

+ 1 - 1
src/main/frontend/components/commit.cljs

@@ -39,7 +39,7 @@
 (rum/defcs add-commit-message < rum/reactive
   (rum/local nil ::git-status)
   {:will-mount (fn [state]
-                 (-> (ipc/ipc "gitStatus")
+                 (-> (ipc/ipc "gitStatus" (state/get-current-repo))
                      (p/then (fn [status]
                                (reset! (get state ::git-status) status))))
                  state)

+ 18 - 1
src/main/frontend/components/theme.cljs

@@ -15,6 +15,22 @@
             [rum.core :as rum]
             [frontend.context.i18n :refer [t]]))
 
+(rum/defc scrollbar-measure
+  []
+  (let [*el (rum/use-ref nil)]
+    (rum/use-effect!
+      (fn []
+        (when-let [el (rum/deref *el)]
+          (let [w (- (.-offsetWidth el) (.-clientWidth el))
+                c "custom-scrollbar"
+                l (.-classList js/document.documentElement)]
+            (if (or (not util/mac?) (> w 2))
+              (.add l c) (.remove l c)))))
+      [])
+    [:div.fixed.w-16.h-16.overflow-scroll.opacity-0
+     {:ref   *el
+      :class "top-1/2 -left-1/2 z-[-999]"}]))
+
 (rum/defc ^:large-vars/cleanup-todo container
   [{:keys [route theme accent-color on-click current-repo nfs-granted? db-restoring?
            settings-open? sidebar-open? system-theme? sidebar-blocks-len onboarding-state preferred-language]} child]
@@ -117,4 +133,5 @@
      {:on-click on-click}
      child
 
-     (pdf/default-embed-playground)]))
+     (pdf/default-embed-playground)
+     (scrollbar-measure)]))

+ 1 - 1
src/main/frontend/components/theme.css

@@ -16,7 +16,7 @@
   }
 }
 
-.visible-scrollbar, html:not(.is-mac) {
+.visible-scrollbar , html.custom-scrollbar {
   ::-webkit-scrollbar-thumb {
     background-color: var(--lx-gray-05, var(--ls-scrollbar-foreground-color, var(--rx-gray-05)));
   }

+ 4 - 0
src/main/frontend/handler/export/text.cljs

@@ -360,6 +360,10 @@
             (when (and origin-ast newline-after-block? (not current-block-is-first-heading-block?))
               [(newline* 2)])
             (mapcatv inline-ast->simple-ast ast-content)
+            (let [last-element (last ast-content)
+                  [last-element-type] last-element]
+              (when (and newline-after-block? (= "Break_Line" last-element-type))
+                (inline-break-line)))
             [(newline* 1)]))
          "Paragraph_line"
          (assert false "Paragraph_line is mldoc internal ast")

+ 4 - 2
src/main/frontend/handler/shell.cljs

@@ -11,11 +11,13 @@
 
 (defn run-git-command!
   [command]
-  (ipc/ipc :runGit command))
+  (ipc/ipc :runGit {:repo (state/get-current-repo)
+                    :command command}))
 
 (defn run-git-command2!
   [command]
-  (ipc/ipc :runGitWithinCurrentGraph command))
+  (ipc/ipc :runGitWithinCurrentGraph {:repo (state/get-current-repo) 
+                                      :command command}))
 
 (defn run-cli-command!
   [command args]

+ 6 - 1
src/main/frontend/ui.cljs

@@ -1051,7 +1051,12 @@
                       :muted   disabled?}
                 button-props)
 
-        icon (when icon (shui/tabler-icon icon icon-props))
+        icon (when icon (shui-ui/tabler-icon icon icon-props))
+        href? (not (string/blank? href))
+        text (cond
+               href? [:a {:href href :target "_blank"
+                          :style {:color "inherit"}} text]
+               :else text)
         children [icon text]]
 
     (shui/button props children)))

+ 1 - 1
src/main/frontend/version.cljs

@@ -1,3 +1,3 @@
 (ns ^:no-doc frontend.version)
 
-(defonce version "0.10.6")
+(defonce version "0.10.7")