mirror of https://github.com/logseq/logseq
Merge branch 'master' into feat/db
commit
97a017df9b
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
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
|
||||
(or (vector? text) (object? text)) ; hiccup
|
||||
text
|
||||
|
||||
(string/blank? query)
|
||||
[:span (to-string text)]
|
||||
|
||||
:else
|
||||
[:span text-string]))))))
|
||||
(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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -4,7 +4,7 @@ module.exports = {
|
|||
packagerConfig: {
|
||||
name: 'Logseq',
|
||||
icon: './icons/logseq_big_sur.icns',
|
||||
buildVersion: 80,
|
||||
buildVersion: 81,
|
||||
protocols: [
|
||||
{
|
||||
"protocol": "logseq",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)]
|
||||
[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)))))))
|
||||
(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,21 +94,20 @@
|
|||
;; 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!
|
||||
([]
|
||||
(add-all-and-commit! nil))
|
||||
([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!)
|
||||
_ (add-all!)]
|
||||
(commit! message))
|
||||
(p/let [_ (init! graph-path)
|
||||
_ (add-all! graph-path)]
|
||||
(commit! graph-path message))
|
||||
(p/catch (fn [error]
|
||||
(when (and
|
||||
(string? error)
|
||||
|
@ -119,11 +115,17 @@
|
|||
(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.")})))))))))
|
||||
: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]
|
||||
(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))))
|
||||
|
||||
|
|
|
@ -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 []
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)]))
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,3 +1,3 @@
|
|||
(ns ^:no-doc frontend.version)
|
||||
|
||||
(defonce version "0.10.6")
|
||||
(defonce version "0.10.7")
|
||||
|
|
Loading…
Reference in New Issue