Merge branch 'master' into feat/db

This commit is contained in:
Gabriel Horner
2023-11-29 09:56:12 -05:00
29 changed files with 792 additions and 245 deletions

View File

@@ -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

View File

@@ -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?)

View File

@@ -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)}}]))

View File

@@ -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
[]

View File

@@ -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

View File

@@ -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)))

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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]

View File

@@ -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}))))))))

View File

@@ -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?))

View File

@@ -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

View File

@@ -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 "]]")))))

View File

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