mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
Merge branch 'master' into feat/db
This commit is contained in:
@@ -83,7 +83,8 @@
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[rum.core :as rum]
|
||||
[shadow.loader :as loader]
|
||||
[logseq.common.path :as path]))
|
||||
[logseq.common.path :as path]
|
||||
[electron.ipc :as ipc]))
|
||||
|
||||
;; local state
|
||||
(defonce *dragging?
|
||||
@@ -316,7 +317,7 @@
|
||||
:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(if local?
|
||||
(js/window.apis.showItemInFolder image-src)
|
||||
(ipc/ipc "openFileInFolder" image-src)
|
||||
(js/window.apis.openExternal image-src)))}
|
||||
image-src])
|
||||
[:.flex
|
||||
|
||||
@@ -202,16 +202,23 @@
|
||||
;; The pages search action uses an existing handler
|
||||
(defmethod load-results :pages [group state]
|
||||
(let [!input (::input state)
|
||||
!results (::results state)]
|
||||
!results (::results state)
|
||||
repo (state/get-current-repo)]
|
||||
(swap! !results assoc-in [group :status] :loading)
|
||||
(p/let [pages (search/page-search @!input)
|
||||
items (map
|
||||
(fn [page]
|
||||
(let [entity (db/entity [:block/name (util/page-name-sanity-lc page)])
|
||||
whiteboard? (= (:block/type entity) "whiteboard")]
|
||||
whiteboard? (= (:block/type entity) "whiteboard")
|
||||
source-page (model/get-alias-source-page repo page)]
|
||||
(hash-map :icon (if whiteboard? "whiteboard" "page")
|
||||
:icon-theme :gray
|
||||
:text page
|
||||
:text (if source-page
|
||||
[:div.flex.flex-row.items-center.gap-2
|
||||
page
|
||||
[:div.opacity-50.font-normal "alias of"]
|
||||
(:block/original-name source-page)]
|
||||
page)
|
||||
:source-page page)))
|
||||
pages)]
|
||||
(swap! !results update group merge {:status :success :items items}))))
|
||||
@@ -297,10 +304,12 @@
|
||||
|
||||
(defmethod handle-action :open-page [_ state _event]
|
||||
(when-let [page-name (some-> state state->highlighted-item :source-page)]
|
||||
(let [page (db/entity [:block/name (util/page-name-sanity-lc page-name)])]
|
||||
(let [redirect-page-name (model/get-redirect-page-name page-name)
|
||||
page (db/entity [:block/name (util/page-name-sanity-lc redirect-page-name)])
|
||||
original-name (:block/original-name page)]
|
||||
(if (= (:block/type page) "whiteboard")
|
||||
(route-handler/redirect-to-whiteboard! page-name)
|
||||
(route-handler/redirect-to-page! page-name)))
|
||||
(route-handler/redirect-to-whiteboard! original-name)
|
||||
(route-handler/redirect-to-page! original-name)))
|
||||
(close-unless-alt! state)))
|
||||
|
||||
(defmethod handle-action :open-block [_ state _event]
|
||||
@@ -315,8 +324,10 @@
|
||||
|
||||
(defmethod handle-action :open-page-right [_ state _event]
|
||||
(when-let [page-name (some-> state state->highlighted-item :source-page)]
|
||||
(when-let [page (db/entity [:block/name (util/page-name-sanity-lc page-name)])]
|
||||
(editor-handler/open-block-in-sidebar! (:block/uuid page)))
|
||||
(let [redirect-page-name (model/get-redirect-page-name page-name)
|
||||
page (db/entity [:block/name (util/page-name-sanity-lc redirect-page-name)])]
|
||||
(when page
|
||||
(editor-handler/open-block-in-sidebar! (:block/uuid page))))
|
||||
(close-unless-alt! state)))
|
||||
|
||||
(defmethod handle-action :open-block-right [_ state _event]
|
||||
@@ -441,7 +452,12 @@
|
||||
[:div {:class "border-b border-gray-06 pb-1 last:border-b-0"
|
||||
:on-mouse-move #(reset! *mouse-active? true)}
|
||||
[:div {:class "text-xs py-1.5 px-3 flex justify-between items-center gap-2 text-gray-11 bg-gray-02"}
|
||||
[:div {:class "font-bold text-gray-11 pl-0.5"} title]
|
||||
[:div {:class "font-bold text-gray-11 pl-0.5 cursor-pointer select-none"
|
||||
:on-click (fn [_e]
|
||||
;; change :less to :more or :more to :less
|
||||
(swap! (::results state) update-in [group :show] {:more :less
|
||||
:less :more}))}
|
||||
title]
|
||||
(when (not= group :create)
|
||||
[:div {:class "pl-1.5 text-gray-12 rounded-full"
|
||||
:style {:font-size "0.7rem"}}
|
||||
@@ -535,6 +551,7 @@
|
||||
keyname (.-key e)
|
||||
enter? (= keyname "Enter")
|
||||
esc? (= keyname "Escape")
|
||||
composing? (util/event-is-composing? e)
|
||||
highlighted-group @(::highlighted-group state)
|
||||
show-less (fn [] (swap! (::results state) assoc-in [highlighted-group :show] :less))
|
||||
show-more (fn [] (swap! (::results state) assoc-in [highlighted-group :show] :more))
|
||||
@@ -559,9 +576,9 @@
|
||||
as-keyup? (if meta?
|
||||
(show-less)
|
||||
(move-highlight state -1))
|
||||
enter? (do
|
||||
(handle-action :default state e)
|
||||
(util/stop-propagation e))
|
||||
(and enter? (not composing?)) (do
|
||||
(handle-action :default state e)
|
||||
(util/stop-propagation e))
|
||||
esc? (let [filter @(::filter state)]
|
||||
(when (or (and filter @(::input-changed? state))
|
||||
(not (string/blank? input)))
|
||||
@@ -573,7 +590,7 @@
|
||||
(util/stop-propagation e))
|
||||
:else nil)))
|
||||
|
||||
(defn keyup-handler
|
||||
(defn- keyup-handler
|
||||
[state e]
|
||||
(let [shift? (.-shiftKey e)
|
||||
meta? (.-metaKey e)
|
||||
@@ -751,9 +768,8 @@
|
||||
(mixins/on-key-down state {}
|
||||
{:target ref
|
||||
:all-handler (fn [e _key] (keydown-handler state e))})
|
||||
(mixins/on-key-up state {}
|
||||
{:target ref
|
||||
:all-handler (fn [e _key] (keyup-handler state e))}))))
|
||||
(mixins/on-key-up state {} (fn [e _key]
|
||||
(keyup-handler state e))))))
|
||||
(rum/local false ::shift?)
|
||||
(rum/local false ::meta?)
|
||||
(rum/local false ::alt?)
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
(let [repo-dir (config/get-repo-dir repo)
|
||||
file-fpath (path/path-join repo-dir file-rpath)]
|
||||
[{:title (t :page/open-in-finder)
|
||||
:options {:on-click #(js/window.apis.showItemInFolder file-fpath)}}
|
||||
:options {:on-click #(ipc/ipc "openFileInFolder" file-fpath)}}
|
||||
{:title (t :page/open-with-default-app)
|
||||
:options {:on-click #(js/window.apis.openPath file-fpath)}}]))
|
||||
|
||||
|
||||
@@ -460,10 +460,7 @@
|
||||
|
||||
(defn get-repo-fpath
|
||||
[repo-url path]
|
||||
(if (and (or (util/electron?) (mobile-util/native-platform?))
|
||||
(local-file-based-graph? repo-url))
|
||||
(path/path-join (get-repo-dir repo-url) path)
|
||||
(util/node-path.join (get-repo-dir repo-url) path)))
|
||||
(path/path-join (get-repo-dir repo-url) path))
|
||||
|
||||
(defn get-repo-config-path
|
||||
[]
|
||||
|
||||
@@ -44,6 +44,34 @@
|
||||
(p/catch (fn [_error]
|
||||
(js/window.pfs.mkdir dir)))))
|
||||
|
||||
(defn- <exists?
|
||||
"dir is path, without memory:// prefix for simplicity"
|
||||
[dir]
|
||||
(-> (js/window.pfs.stat dir)
|
||||
(p/then (fn [stat]
|
||||
(not (nil? stat))))
|
||||
(p/catch (fn [_]
|
||||
nil))))
|
||||
|
||||
(defn- <mkdir-recur!
|
||||
"mkdir, recursively create parent directories if not exist
|
||||
|
||||
lightning-fs does not support's :recursive in mkdir options"
|
||||
[dir]
|
||||
(p/let [fpath (path/url-to-path dir)
|
||||
sub-dirs (p/loop [top-parent fpath
|
||||
remains []]
|
||||
(p/let [exists? (<exists? top-parent)]
|
||||
(if exists?
|
||||
(reverse remains) ;; top-parent is the first non-exist dir
|
||||
(p/recur (path/parent top-parent)
|
||||
(conj remains top-parent)))))]
|
||||
(p/loop [remains sub-dirs]
|
||||
(if (empty? remains)
|
||||
(p/resolved nil)
|
||||
(p/do! (js/window.pfs.mkdir (first remains))
|
||||
(p/recur (rest remains)))))))
|
||||
|
||||
(defrecord MemoryFs []
|
||||
protocol/Fs
|
||||
(mkdir! [_this dir]
|
||||
@@ -51,13 +79,11 @@
|
||||
(let [fpath (path/url-to-path dir)]
|
||||
(-> (js/window.pfs.mkdir fpath)
|
||||
(p/catch (fn [error] (println "(memory-fs)Mkdir error: " error)))))))
|
||||
(mkdir-recur! [this dir]
|
||||
;; FIXME: replace this with a recurisve implementation
|
||||
(mkdir-recur! [_this dir]
|
||||
(when js/window.pfs
|
||||
(p/let [dir' (path/url-to-path dir)
|
||||
parent (path/parent dir')
|
||||
_ (when parent (<ensure-dir! parent))]
|
||||
(protocol/mkdir! this dir'))))
|
||||
(let [fpath (path/url-to-path dir)]
|
||||
(-> (<mkdir-recur! fpath)
|
||||
(p/catch (fn [error] (println "(memory-fs)Mkdir-recur error: " error)))))))
|
||||
|
||||
(readdir [_this dir]
|
||||
(when js/window.pfs
|
||||
|
||||
@@ -2701,7 +2701,7 @@
|
||||
v)))))
|
||||
:flush-fn #(swap! *sync-state sync-state-reset-queued-local->remote-files)
|
||||
:stop-ch stop-chan
|
||||
:distinct-coll? true
|
||||
:distinct-key-fn identity
|
||||
:flush-now-ch private-immediately-local->remote-chan
|
||||
:refresh-timeout-ch private-recent-edited-chan)))
|
||||
|
||||
|
||||
@@ -76,8 +76,9 @@
|
||||
|
||||
(str "assets://" (string/replace rpath' (str "@" (:name alias)) (:dir alias)))
|
||||
|
||||
(if has-schema? (path/path-join graph-root rpath)
|
||||
(path/path-join "file://" graph-root rpath))))]
|
||||
(if has-schema?
|
||||
(path/path-join graph-root rpath)
|
||||
(path/prepend-protocol "file:" (path/path-join graph-root rpath)))))]
|
||||
(convert-platform-protocol ret)))))
|
||||
|
||||
(defn normalize-asset-resource-url
|
||||
|
||||
@@ -1447,7 +1447,7 @@
|
||||
(assets-handler/resolve-asset-real-path-url (state/get-current-repo) path)
|
||||
|
||||
(util/electron?)
|
||||
(path/path-join "assets://" full-path)
|
||||
(path/prepend-protocol "assets:" full-path)
|
||||
|
||||
(mobile-util/native-platform?)
|
||||
(mobile-util/convert-file-src full-path)
|
||||
@@ -1628,7 +1628,7 @@
|
||||
editing-page (and block
|
||||
(when-let [page-id (:db/id (:block/page block))]
|
||||
(:block/name (db/entity page-id))))
|
||||
pages (search/page-search q 100)]
|
||||
pages (search/page-search q)]
|
||||
(if editing-page
|
||||
;; To prevent self references
|
||||
(remove (fn [p] (= (util/page-name-sanity-lc p) editing-page)) pages)
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
[logseq.graph-parser.util.page-ref :as page-ref]
|
||||
[promesa.core :as p]
|
||||
[logseq.common.path :as path]
|
||||
[frontend.handler.property.util :as pu]))
|
||||
[frontend.handler.property.util :as pu]
|
||||
[electron.ipc :as ipc]))
|
||||
|
||||
(def create! page-common-handler/create!)
|
||||
(def delete! page-common-handler/delete!)
|
||||
@@ -319,7 +320,7 @@
|
||||
(if-let [file-rpath (and (util/electron?) (page-util/get-page-file-rpath))]
|
||||
(let [repo-dir (config/get-repo-dir (state/get-current-repo))
|
||||
file-fpath (path/path-join repo-dir file-rpath)]
|
||||
(js/window.apis.showItemInFolder file-fpath))
|
||||
(ipc/ipc "openFileInFolder" file-fpath))
|
||||
(notification/show! "No file found" :warning)))
|
||||
|
||||
(defn copy-page-url
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
nil)))))
|
||||
|
||||
(defn on-key-up
|
||||
"Caution: This mixin uses a different args than on-key-down"
|
||||
[state keycode-map all-handler]
|
||||
(listen state js/window "keyup"
|
||||
(fn [e]
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
(not (state/input-idle? repo {:diff 3000}))) ;; long page
|
||||
;; when this whiteboard page is just being updated
|
||||
(and whiteboard? (not (state/whiteboard-idle? repo))))
|
||||
(async/put! (state/get-file-write-chan) [repo page-db-id outliner-op])
|
||||
(async/put! (state/get-file-write-chan) [repo page-db-id outliner-op (tc/to-long (t/now))])
|
||||
(let [pull-keys (if whiteboard? whiteboard-blocks-pull-keys-with-persisted-ids '[*])
|
||||
blocks (model/get-page-blocks-no-cache repo (:block/name page-block) {:pull-keys pull-keys})
|
||||
blocks (if whiteboard? (map cleanup-whiteboard-block blocks) blocks)]
|
||||
@@ -73,7 +73,7 @@
|
||||
[pages]
|
||||
(when (seq pages)
|
||||
(when-not config/publishing?
|
||||
(doseq [[repo page-id outliner-op] (set pages)]
|
||||
(doseq [[repo page-id outliner-op] (set (map #(take 3 %) pages))] ; remove time to dedupe pages to write
|
||||
(try (do-write-file! repo page-id outliner-op)
|
||||
(catch :default e
|
||||
(notification/show!
|
||||
@@ -101,17 +101,17 @@
|
||||
(defn <ratelimit-file-writes!
|
||||
[]
|
||||
(util/<ratelimit (state/get-file-write-chan) batch-write-interval
|
||||
:filter-fn
|
||||
(fn [[repo _ time]]
|
||||
(swap! *writes-finished? assoc repo {:time time
|
||||
:value false})
|
||||
true)
|
||||
:flush-fn
|
||||
(fn [col]
|
||||
(let [start-time (tc/to-long (t/now))
|
||||
repos (distinct (map first col))]
|
||||
(write-files! col)
|
||||
(doseq [repo repos]
|
||||
(let [last-write-time (get-in @*writes-finished? [repo :time])]
|
||||
(when (> start-time last-write-time)
|
||||
(swap! *writes-finished? assoc repo {:value true}))))))))
|
||||
:filter-fn
|
||||
(fn [[repo _ _ time]]
|
||||
(swap! *writes-finished? assoc repo {:time time
|
||||
:value false})
|
||||
true)
|
||||
:flush-fn
|
||||
(fn [col]
|
||||
(let [start-time (tc/to-long (t/now))
|
||||
repos (distinct (map first col))]
|
||||
(write-files! col)
|
||||
(doseq [repo repos]
|
||||
(let [last-write-time (get-in @*writes-finished? [repo :time])]
|
||||
(when (> start-time last-write-time)
|
||||
(swap! *writes-finished? assoc repo {:value true}))))))))
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
(defn page-search
|
||||
"Return a list of page names that match the query"
|
||||
([q]
|
||||
(page-search q 10))
|
||||
(page-search q 500))
|
||||
([q limit]
|
||||
(when-let [repo (state/get-current-repo)]
|
||||
(let [q (util/search-normalize q (state/enable-search-remove-accents?))
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
[electron.ipc :as ipc]
|
||||
[frontend.colors :as colors]
|
||||
[frontend.mobile.util :as mobile-util]
|
||||
[frontend.storage :as storage]
|
||||
[frontend.spec.storage :as storage-spec]
|
||||
[frontend.storage :as storage]
|
||||
[frontend.util :as util]
|
||||
[frontend.util.cursor :as cursor]
|
||||
[goog.dom :as gdom]
|
||||
[goog.object :as gobj]
|
||||
[logseq.graph-parser.config :as gp-config]
|
||||
[malli.core :as m]
|
||||
[medley.core :as medley]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
@@ -35,10 +36,12 @@
|
||||
{:route-match nil
|
||||
:today nil
|
||||
:system/events (async/chan 1000)
|
||||
:file/writes (async/chan 10000
|
||||
(util/dedupe-by
|
||||
(fn [[repo page-id outliner-op _epoch]]
|
||||
[repo page-id outliner-op])))
|
||||
:file/writes (let [coercer (m/coercer [:catn
|
||||
[:repo :string]
|
||||
[:page-id :any]
|
||||
[:outliner-op :any]
|
||||
[:epoch :int]])]
|
||||
(async/chan 10000 (map coercer)))
|
||||
:file/unlinked-dirs #{}
|
||||
:reactive/custom-queries (async/chan 1000)
|
||||
:notification/show? false
|
||||
|
||||
@@ -1141,11 +1141,11 @@
|
||||
will poll it when its return value is channel,
|
||||
- :flush-fn exec flush-fn when time to flush, (flush-fn item-coll)
|
||||
- :stop-ch stop go-loop when stop-ch closed
|
||||
- :distinct-coll? distinct coll when put into CH
|
||||
- :distinct-key-fn distinct coll when put into CH
|
||||
- :chan-buffer buffer of return CH, default use (async/chan 1000)
|
||||
- :flush-now-ch flush the content in the queue immediately
|
||||
- :refresh-timeout-ch refresh (timeout max-duration)"
|
||||
[in-ch max-duration & {:keys [filter-fn flush-fn stop-ch distinct-coll? chan-buffer flush-now-ch refresh-timeout-ch]}]
|
||||
[in-ch max-duration & {:keys [filter-fn flush-fn stop-ch distinct-key-fn chan-buffer flush-now-ch refresh-timeout-ch]}]
|
||||
(let [ch (if chan-buffer (async/chan chan-buffer) (async/chan 1000))
|
||||
stop-ch* (or stop-ch (async/chan))
|
||||
flush-now-ch* (or flush-now-ch (async/chan))
|
||||
@@ -1173,8 +1173,8 @@
|
||||
(async/<! filter-v)
|
||||
filter-v)]
|
||||
(if filter-v*
|
||||
(recur timeout-ch (cond-> (conj coll e)
|
||||
distinct-coll? distinct
|
||||
(recur timeout-ch (cond->> (conj coll e)
|
||||
distinct-key-fn (distinct-by distinct-key-fn)
|
||||
true vec))
|
||||
(recur timeout-ch coll)))
|
||||
|
||||
@@ -1549,19 +1549,4 @@ Arg *stop: atom, reset to true to stop the loop"
|
||||
(or
|
||||
(not (string/includes? s " "))
|
||||
(string/starts-with? s "#[[")
|
||||
(string/ends-with? s "]]")))))
|
||||
|
||||
(defn dedupe-by
|
||||
([keyfn]
|
||||
(fn [rf]
|
||||
(let [pa (volatile! ::none)]
|
||||
(fn
|
||||
([] (rf))
|
||||
([result] (rf result))
|
||||
([result input]
|
||||
(let [prior @pa
|
||||
key (keyfn input)]
|
||||
(vreset! pa key)
|
||||
(if (= prior key)
|
||||
result
|
||||
(rf result input)))))))))
|
||||
(string/ends-with? s "]]")))))
|
||||
@@ -1,3 +1,3 @@
|
||||
(ns ^:no-doc frontend.version)
|
||||
|
||||
(defonce version "0.9.20")
|
||||
(defonce version "0.10.0")
|
||||
|
||||
Reference in New Issue
Block a user