From f1102c57c9cdf3112f45aefe27600c3590d7d466 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 20 Sep 2022 11:58:56 +0800 Subject: [PATCH 01/10] fix: bring in tldraw's optimization on using freehand see https://github.com/tldraw/tldraw/pull/989 --- .../src/lib/shapes/PencilShape.tsx | 56 +++++++++++++++---- tldraw/apps/tldraw-logseq/src/styles.css | 1 - .../packages/core/src/utils/SvgPathUtils.ts | 42 ++++++++------ 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/tldraw/apps/tldraw-logseq/src/lib/shapes/PencilShape.tsx b/tldraw/apps/tldraw-logseq/src/lib/shapes/PencilShape.tsx index 68381c7be..91a98834b 100644 --- a/tldraw/apps/tldraw-logseq/src/lib/shapes/PencilShape.tsx +++ b/tldraw/apps/tldraw-logseq/src/lib/shapes/PencilShape.tsx @@ -3,13 +3,56 @@ import { SvgPathUtils, TLDrawShape, TLDrawShapeProps } from '@tldraw/core' import { SVGContainer, TLComponentProps } from '@tldraw/react' import { computed, makeObservable } from 'mobx' import { observer } from 'mobx-react-lite' -import getStroke from 'perfect-freehand' +import getStroke, { getStrokeOutlinePoints, getStrokePoints, StrokeOptions } from 'perfect-freehand' import { CustomStyleProps, withClampedStyles } from './style-props' export interface PencilShapeProps extends TLDrawShapeProps, CustomStyleProps { type: 'pencil' } +const simulatePressureSettings: StrokeOptions = { + easing: t => Math.sin((t * Math.PI) / 2), + simulatePressure: true, +} + +const realPressureSettings: StrokeOptions = { + easing: t => t * t, + simulatePressure: false, +} + +function getFreehandOptions(shape: PencilShapeProps) { + const options: StrokeOptions = { + size: 1 + shape.strokeWidth * 1.5, + thinning: 0.65, + streamline: 0.65, + smoothing: 0.65, + ...(shape.points[1][2] === 0.5 ? simulatePressureSettings : realPressureSettings), + last: shape.isComplete, + } + + return options +} + +function getFillPath(shape: PencilShapeProps) { + if (shape.points.length < 2) return '' + + return SvgPathUtils.getSvgPathFromStroke( + getStrokePoints(shape.points, getFreehandOptions(shape)).map(pt => pt.point) + ) +} + +function getDrawStrokePoints(shape: PencilShapeProps, options: StrokeOptions) { + return getStrokePoints(shape.points, options) +} + +function getDrawStrokePathTDSnapshot(shape: PencilShapeProps) { + if (shape.points.length < 2) return '' + const options = getFreehandOptions(shape) + const strokePoints = getDrawStrokePoints(shape, options) + const path = SvgPathUtils.getSvgPathFromStroke(getStrokeOutlinePoints(strokePoints, options)) + return path +} + export class PencilShape extends TLDrawShape { constructor(props = {} as Partial) { super(props) @@ -34,16 +77,7 @@ export class PencilShape extends TLDrawShape { } @computed get pointsPath() { - const { - props: { points, isComplete, strokeWidth }, - } = this - if (points.length < 2) { - return `M -4, 0 - a 4,4 0 1,0 8,0 - a 4,4 0 1,0 -8,0` - } - const stroke = getStroke(points, { size: 4 + strokeWidth * 2, last: isComplete }) - return SvgPathUtils.getCurvedPathForPolygon(stroke) + return getDrawStrokePathTDSnapshot(this.props) } ReactComponent = observer(({ events, isErasing }: TLComponentProps) => { diff --git a/tldraw/apps/tldraw-logseq/src/styles.css b/tldraw/apps/tldraw-logseq/src/styles.css index 22a7a75a7..e0b948c76 100644 --- a/tldraw/apps/tldraw-logseq/src/styles.css +++ b/tldraw/apps/tldraw-logseq/src/styles.css @@ -558,7 +558,6 @@ button.tl-select-input-trigger { } &[data-recently-changed=true] { - transition-delay: 0.5s; i.tie { transition-delay: 0.5s; } diff --git a/tldraw/packages/core/src/utils/SvgPathUtils.ts b/tldraw/packages/core/src/utils/SvgPathUtils.ts index cd23ad4f2..344fc0ba2 100644 --- a/tldraw/packages/core/src/utils/SvgPathUtils.ts +++ b/tldraw/packages/core/src/utils/SvgPathUtils.ts @@ -1,4 +1,3 @@ -import Vec from '@tldraw/vec' export class SvgPathUtils { static getCurvedPathForPolygon(points: number[][]) { @@ -45,23 +44,34 @@ export class SvgPathUtils { * @param stroke ; */ static getSvgPathFromStroke(points: number[][], closed = true): string { - if (!points.length) { - return '' + const len = points.length + + if (len < 4) { + return `` } - const max = points.length - 1 + let a = points[0] + let b = points[1] + const c = points[2] - return points - .reduce( - (acc, point, i, arr) => { - if (i === max) { - if (closed) acc.push('Z') - } else acc.push(point, Vec.med(point, arr[i + 1])) - return acc - }, - ['M', points[0], 'Q'] - ) - .join(' ') - .replaceAll(this.TRIM_NUMBERS, '$1') + let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed( + 2 + )} ${average(b[0], c[0]).toFixed(2)},${average(b[1], c[1]).toFixed(2)} T` + + for (let i = 2, max = len - 1; i < max; i++) { + a = points[i] + b = points[i + 1] + result += `${average(a[0], b[0]).toFixed(2)},${average(a[1], b[1]).toFixed(2)} ` + } + + if (closed) { + result += 'Z' + } + + return result } } + +function average(a: number, b: number): number { + return (a + b) / 2 +} From 44e0f0be26ced12be888496ff1af6c762b5a1b4a Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 20 Sep 2022 14:16:11 +0800 Subject: [PATCH 02/10] fix: save whiteboard when inactive for 3s --- src/main/frontend/handler/whiteboard.cljs | 13 +------- src/main/frontend/modules/outliner/file.cljs | 8 ++--- .../frontend/modules/shortcut/before.cljs | 2 +- src/main/frontend/state.cljs | 30 ++++++++++++------- .../src/lib/shapes/LogseqPortalShape.tsx | 2 ++ .../SelectionForeground.tsx | 7 +++-- .../react/src/hooks/usePreventNavigation.ts | 20 +++++++++---- 7 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/main/frontend/handler/whiteboard.cljs b/src/main/frontend/handler/whiteboard.cljs index 264b449d0..58662d745 100644 --- a/src/main/frontend/handler/whiteboard.cljs +++ b/src/main/frontend/handler/whiteboard.cljs @@ -2,7 +2,6 @@ (:require [datascript.core :as d] [frontend.db.model :as model] [frontend.db.utils :as db-utils] - [frontend.handler.editor :as editor-handler] [frontend.handler.route :as route-handler] [frontend.modules.outliner.core :as outliner] [frontend.modules.outliner.file :as outliner-file] @@ -30,17 +29,6 @@ ;; (and (.-classList el) (.. el -classList (contains "whiteboard"))) true ;; :else (recur (.-parentElement el))))) -(defn get-tldr-app - [] - js/window.tln) - -(defn tldraw-idle? - "return true when tldraw is active and idle. nil when tldraw is - not active." - [] - (when-let [^js app (get-tldr-app)] - (.. app -selectedTool (isIn "idle")))) - (defn- block->shape [block] (:block/properties block)) @@ -116,6 +104,7 @@ (let [{:keys [pages assets]} (js->clj tldr :keywordize-keys true) page (first pages) tx (tldr-page->blocks-tx page-name (assoc page :assets assets))] + (state/set-last-transact-time! (state/get-current-repo) (util/time-ms)) (db-utils/transact! tx))) (defn get-default-tldr diff --git a/src/main/frontend/modules/outliner/file.cljs b/src/main/frontend/modules/outliner/file.cljs index 2f6f60fec..1476b37fd 100644 --- a/src/main/frontend/modules/outliner/file.cljs +++ b/src/main/frontend/modules/outliner/file.cljs @@ -40,12 +40,12 @@ [repo page-db-id] (let [page-block (db/pull repo '[*] page-db-id) page-db-id (:db/id page-block) + whiteboard? (:block/whiteboard? page-block) blocks-count (model/get-page-blocks-count repo page-db-id)] - (if (and (> blocks-count 500) - (not (state/input-idle? repo :diff 3000))) ; long page + (if (and (or (> blocks-count 500) whiteboard?) + (not (state/input-idle? repo :diff 3000))) ; long page or whiteboard (async/put! (state/get-file-write-chan) [repo page-db-id]) - (let [whiteboard? (:block/whiteboard? page-block) - pull-keys (if whiteboard? whiteboard-blocks-pull-keys-with-persisted-ids '[*]) + (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)] (when-not (and (= 1 (count blocks)) diff --git a/src/main/frontend/modules/shortcut/before.cljs b/src/main/frontend/modules/shortcut/before.cljs index 62cd6b3d4..d67aba9b6 100644 --- a/src/main/frontend/modules/shortcut/before.cljs +++ b/src/main/frontend/modules/shortcut/before.cljs @@ -35,6 +35,6 @@ (fn [e] (when (and (or (contains? #{:srs :page-histories} (state/get-modal-id)) (not (state/block-component-editing?))) - (not (and (whiteboard/tldraw-idle?) + (not (and (state/tldraw-idle?) (not (state/editing?))))) (f e)))) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index ae048b186..5e7e98b2b 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1,20 +1,20 @@ (ns frontend.state (:require [cljs-bean.core :as bean] [cljs.core.async :as async] - [clojure.string :as string] [cljs.spec.alpha :as s] + [clojure.string :as string] [dommy.core :as dom] - [medley.core :as medley] [electron.ipc :as ipc] + [frontend.mobile.util :as mobile-util] [frontend.storage :as storage] [frontend.util :as util] [frontend.util.cursor :as cursor] [goog.dom :as gdom] [goog.object :as gobj] - [promesa.core :as p] - [rum.core :as rum] [logseq.graph-parser.config :as gp-config] - [frontend.mobile.util :as mobile-util])) + [medley.core :as medley] + [promesa.core :as p] + [rum.core :as rum])) ;; Stores main application state (defonce ^:large-vars/data-var state @@ -1396,6 +1396,16 @@ Similar to re-frame subscriptions" (set-state! [:plugin/installed-hooks hook-or-all] (disj coll pid)))) true)) +(defn active-tldraw-app + [] + ^js js/window.tln) + +(defn tldraw-idle? + "return true when tldraw is active and idle. nil when tldraw is + not active." + [] + (when-let [app (active-tldraw-app)] + (.. app -selectedTool (isIn "idle")))) (defn set-graph-syncing? [value] @@ -1445,11 +1455,11 @@ Similar to re-frame subscriptions" :or {diff 1000}}] (when repo (or - (when-let [last-time (get-in @state [:editor/last-input-time repo])] - (let [now (util/time-ms)] - (>= (- now last-time) diff))) - ;; not in editing mode - (not (get-edit-input-id))))) + (when-let [last-time (get-in @state [:editor/last-input-time repo])] + (let [now (util/time-ms)] + (>= (- now last-time) diff))) + ;; not in editing mode + (not (or (get-edit-input-id) (active-tldraw-app)))))) (defn set-nfs-refreshing! [value] diff --git a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx index 2600d031a..8cca46a4b 100644 --- a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx +++ b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx @@ -30,6 +30,7 @@ export interface LogseqPortalShapeProps extends TLBoxShapeProps, CustomStyleProp blockType?: 'P' | 'B' collapsed?: boolean compact?: boolean + borderRadius?: number collapsedHeight?: number scaleLevel?: SizeLevel } @@ -186,6 +187,7 @@ export class LogseqPortalShape extends TLBoxShape { stroke: 'var(--ls-primary-text-color)', fill: 'var(--ls-secondary-background-color)', noFill: false, + borderRadius: 8, strokeWidth: 2, strokeType: 'line', opacity: 1, diff --git a/tldraw/packages/react/src/components/ui/SelectionForeground/SelectionForeground.tsx b/tldraw/packages/react/src/components/ui/SelectionForeground/SelectionForeground.tsx index 38660c4aa..cb6b7af0f 100644 --- a/tldraw/packages/react/src/components/ui/SelectionForeground/SelectionForeground.tsx +++ b/tldraw/packages/react/src/components/ui/SelectionForeground/SelectionForeground.tsx @@ -22,7 +22,8 @@ export const SelectionForeground = observer(function SelectionForeground @@ -30,8 +31,8 @@ export const SelectionForeground = observer(function SelectionForeground ): if (!elm) return () => void null - elm.addEventListener('touchstart', preventGestureNavigation) + elm.addEventListener('touchstart', preventGestureNavigation, { + passive: true, + }) // @ts-ignore - elm.addEventListener('gestureend', preventGestureNavigation) + elm.addEventListener('gestureend', preventGestureNavigation, { + passive: true, + }) // @ts-ignore - elm.addEventListener('gesturechange', preventGestureNavigation) + elm.addEventListener('gesturechange', preventGestureNavigation, { + passive: true, + }) // @ts-ignore - elm.addEventListener('gesturestart', preventGestureNavigation) + elm.addEventListener('gesturestart', preventGestureNavigation, { + passive: true, + }) // @ts-ignore - elm.addEventListener('touchstart', preventNavigation) + elm.addEventListener('touchstart', preventNavigation, { + passive: true, + }) return () => { if (elm) { From a0054fc0e195d821961f17ca7b06a42a57b9de69 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 20 Sep 2022 14:34:03 +0800 Subject: [PATCH 03/10] docs: add a reminder --- src/main/frontend/state.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 5e7e98b2b..68235f98b 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1459,6 +1459,7 @@ Similar to re-frame subscriptions" (let [now (util/time-ms)] (>= (- now last-time) diff))) ;; not in editing mode + ;; Is this a good idea to put whiteboard check here? (not (or (get-edit-input-id) (active-tldraw-app)))))) (defn set-nfs-refreshing! From b4e6ad47697a8534c3f6f0a790cb3bd4bd86a1ad Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 20 Sep 2022 14:34:40 +0800 Subject: [PATCH 04/10] fix: lint issue --- src/main/frontend/modules/shortcut/before.cljs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/frontend/modules/shortcut/before.cljs b/src/main/frontend/modules/shortcut/before.cljs index d67aba9b6..34cf13325 100644 --- a/src/main/frontend/modules/shortcut/before.cljs +++ b/src/main/frontend/modules/shortcut/before.cljs @@ -1,8 +1,7 @@ (ns frontend.modules.shortcut.before - (:require [frontend.state :as state] - [frontend.util :as util] - [frontend.mobile.util :as mobile-util] - [frontend.handler.whiteboard :as whiteboard])) + (:require [frontend.mobile.util :as mobile-util] + [frontend.state :as state] + [frontend.util :as util])) ;; before function (defn prevent-default-behavior From bfdae9c1a029d089b8d4c5b31581cbbfd1823050 Mon Sep 17 00:00:00 2001 From: paul <> Date: Tue, 20 Sep 2022 12:23:39 +0530 Subject: [PATCH 05/10] changed message typo from "Refresh detects and processes files modified on your disk and diverged from the actual Logseq page content. Continue?" to "Refresh detects and processes files modified on your disk that have diverged from the current Logseq page content. Continue?" --- src/main/frontend/dicts.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/frontend/dicts.cljc b/src/main/frontend/dicts.cljc index 920f97748..3974766e5 100644 --- a/src/main/frontend/dicts.cljc +++ b/src/main/frontend/dicts.cljc @@ -217,7 +217,7 @@ :open-new-window "New window" :sync-from-local-files "Refresh" :sync-from-local-files-detail "Import changes from local files" - :sync-from-local-changes-detected "Refresh detects and processes files modified on your disk and diverged from the actual Logseq page content. Continue?" + :sync-from-local-changes-detected "Refresh detects and processes files modified on your disk that have diverged from the current Logseq page content. Continue?" :unlink "unlink" :search/publishing "Search" From c6ff4e80846576af3a6eea55c1ebd418cd98632d Mon Sep 17 00:00:00 2001 From: Andelf Date: Tue, 20 Sep 2022 12:02:49 +0800 Subject: [PATCH 06/10] chore: rm unused code --- src/main/frontend/fs/capacitor_fs.cljs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/frontend/fs/capacitor_fs.cljs b/src/main/frontend/fs/capacitor_fs.cljs index 115a201c5..5c8f23ad4 100644 --- a/src/main/frontend/fs/capacitor_fs.cljs +++ b/src/main/frontend/fs/capacitor_fs.cljs @@ -62,12 +62,7 @@ (defn- (p/chain (.stat Filesystem (clj->js {:path path})) - #(js->clj % :keywordize-keys true) - #(update % :type (fn [v] - (case v - "NSFileTypeDirectory" "directory" - "NSFileTypeRegular" "file" - v)))) + #(js->clj % :keywordize-keys true)) (p/catch (fn [error] (js/console.error "stat Error: " path ": " error) nil)))) From dfbb42a1b316c9b5bbc1c35398da59f213c2a2ca Mon Sep 17 00:00:00 2001 From: Andelf Date: Tue, 20 Sep 2022 12:03:59 +0800 Subject: [PATCH 07/10] fix(sync): update rsapi, add graph-uuid to all fn --- resources/package.json | 2 +- src/electron/electron/file_sync_rsapi.cljs | 15 ++++----- src/electron/electron/handler.cljs | 3 -- src/main/frontend/fs/sync.cljs | 36 +++++++++++----------- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/resources/package.json b/resources/package.json index c25f5bcf7..2d1b36567 100644 --- a/resources/package.json +++ b/resources/package.json @@ -37,7 +37,7 @@ "https-proxy-agent": "5.0.0", "@sentry/electron": "2.5.1", "posthog-js": "1.10.2", - "@logseq/rsapi": "0.0.38", + "@logseq/rsapi": "0.0.44", "electron-deeplink": "1.0.10", "abort-controller": "3.0.0" }, diff --git a/src/electron/electron/file_sync_rsapi.cljs b/src/electron/electron/file_sync_rsapi.cljs index f81dfef09..5513cb7ed 100644 --- a/src/electron/electron/file_sync_rsapi.cljs +++ b/src/electron/electron/file_sync_rsapi.cljs @@ -3,8 +3,8 @@ (defn key-gen [] (rsapi/keygen)) -(defn set-env [env private-key public-key] - (rsapi/setEnv env private-key public-key)) +(defn set-env [graph-uuid env private-key public-key] + (rsapi/setEnv graph-uuid env private-key public-key)) (defn get-local-files-meta [graph-uuid base-path file-paths] (rsapi/getLocalFilesMeta graph-uuid base-path (clj->js file-paths))) @@ -27,17 +27,14 @@ (defn delete-remote-files [graph-uuid base-path file-paths txid token] (rsapi/deleteRemoteFiles graph-uuid base-path (clj->js file-paths) txid token)) -(defn update-remote-file [graph-uuid base-path file-path txid token] - (rsapi/updateRemoteFile graph-uuid base-path file-path txid token)) - (defn update-remote-files [graph-uuid base-path file-paths txid token] (rsapi/updateRemoteFiles graph-uuid base-path (clj->js file-paths) txid token true)) -(defn encrypt-fnames [fnames] - (mapv rsapi/encryptFname fnames)) +(defn encrypt-fnames [graph-uuid fnames] + (rsapi/encryptFnames graph-uuid (clj->js fnames))) -(defn decrypt-fnames [fnames] - (mapv rsapi/decryptFname fnames)) +(defn decrypt-fnames [graph-uuid fnames] + (rsapi/decryptFnames graph-uuid (clj->js fnames))) (defn encrypt-with-passphrase [passphrase data] (rsapi/ageEncryptWithPassphrase passphrase data)) diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index f32986a22..a74a0d79a 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -564,9 +564,6 @@ (defmethod handle :delete-remote-files [_ args] (apply rsapi/delete-remote-files (rest args))) -(defmethod handle :update-remote-file [_ args] - (apply rsapi/update-remote-file (rest args))) - (defmethod handle :update-remote-files [_ args] (apply rsapi/update-remote-files (rest args))) diff --git a/src/main/frontend/fs/sync.cljs b/src/main/frontend/fs/sync.cljs index 2efd36a79..0ff53de85 100644 --- a/src/main/frontend/fs/sync.cljs +++ b/src/main/frontend/fs/sync.cljs @@ -634,7 +634,7 @@ (defprotocol IRSAPI (rsapi-ready? [this graph-uuid] "return true when rsapi ready") ( remote, return err or txid") (clj (c (ipc/ipc "key-gen"))) :keywordize-keys true))) - (c (ipc/ipc "set-env" (if prod? "prod" "dev") private-key public-key))) + (p->c (ipc/ipc "set-env" graph-uuid (if prod? "prod" "dev") private-key public-key))) (c (ipc/ipc "get-local-all-files-meta" graph-uuid base-path))))] @@ -781,9 +781,9 @@ (c (ipc/ipc "delete-remote-files" graph-uuid base-path filepaths local-txid token))))))) - (clj (c (ipc/ipc "encrypt-fnames" fnames)))))) - (c (ipc/ipc "decrypt-fnames" fnames)))] + (clj (c (ipc/ipc "encrypt-fnames" graph-uuid fnames)))))) + (c (ipc/ipc "decrypt-fnames" graph-uuid fnames)))] (if (instance? ExceptionInfo r) (ex-info "decrypt-failed" {:fnames fnames} (ex-cause r)) (js->clj r)))))) @@ -806,7 +806,7 @@ (go (let [r (c (.keygen mobile-util/file-sync #js {})))] (-> r (js->clj :keywordize-keys true))))) - (clj r) "txid"))))) - (c (.encryptFnames mobile-util/file-sync (clj->js {:filePaths fnames}))))] (if (instance? ExceptionInfo r) (.-cause r) (get (js->clj r) "value"))))) - (c (.decryptFnames mobile-util/file-sync (clj->js {:filePaths fnames}))))] (if (instance? ExceptionInfo r) @@ -1107,7 +1107,7 @@ exp-r (let [file-meta-list* (persistent! file-meta-list) encrypted-path-list* (persistent! encrypted-path-list) - path-list-or-exp (path-map (zipmap encrypted-path-list* path-list-or-exp)] @@ -1124,12 +1124,12 @@ (path-map (zipmap encrypted-paths paths-or-exp)] @@ -1152,7 +1152,7 @@ (path-map (zipmap encrypted-paths - (path-map %))) @@ -1205,7 +1205,7 @@ encrypted-path->path-map (zipmap encrypted-paths - ( Date: Tue, 20 Sep 2022 12:44:49 +0800 Subject: [PATCH 08/10] fix(sync): add graph-uuid arg to r first :path (not= filepath)) (-> r first :path))))) (defn remote-files sync-state--add-current-remote->local-files @@ -1406,7 +1406,8 @@ (remove nil?))] (doseq [relative-p (map relative-path filetxns)] - (when-some [relative-p* (local-file-item {:remote->local-type :delete :checksum nil :path relative-p*}] @@ -1433,7 +1434,7 @@ (.-deleted? (first filetxns)) (let [filetxn (first filetxns)] (assert (= 1 (count filetxns))) - (if (recent-remote->local-file-item - [^FileChangeEvent e] + [graph-uuid ^FileChangeEvent e] (go (let [tp (case (.-type e) ("add" "change") :update @@ -1555,7 +1556,7 @@ path (relative-path e)] {:remote->local-type tp :checksum (if (= tp :delete) nil - (val (first ( files-meta first :etag))] (>! local-changes-chan (->FileChangeEvent type dir path stat checksum)))))))))) @@ -2159,18 +2161,18 @@ (case (.-type e) "unlink" ;; keep this e when it's not found - (local-files @*sync-state) - (recent-remote->local-file-item e))))] + (recent-remote->local-file-item + graph-uuid e))))] (when (and (true? r) (seq (:recent-remote->local-files @*sync-state))) (println :debug (:recent-remote->local-files @*sync-state) e)) @@ -2291,7 +2295,7 @@ (map #(relative-path %)) (remove ignored?))] (go - (let [es* (local-file-item {:remote->local-type :delete :checksum nil :path relative-p}] From 41b4cdb93887fee8ed473ba66773167c4c66717b Mon Sep 17 00:00:00 2001 From: rcmerci Date: Tue, 20 Sep 2022 12:58:32 +0800 Subject: [PATCH 09/10] fix(sync): check sync-state is valid to accept filewatcher events --- src/main/frontend/fs/sync.cljs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/frontend/fs/sync.cljs b/src/main/frontend/fs/sync.cljs index 014d6edff..083b610b6 100644 --- a/src/main/frontend/fs/sync.cljs +++ b/src/main/frontend/fs/sync.cljs @@ -1591,6 +1591,7 @@ (map #(partition-all n %)) cat)) +(declare sync-state--valid-to-accept-filewatcher-event?) (defonce local-changes-chan (chan (async/dropping-buffer 1000))) (defn file-watch-handler "file-watcher callback" @@ -1598,7 +1599,7 @@ (when-let [current-graph (state/get-current-repo)] (when (string/ends-with? current-graph dir) (let [sync-state (state/get-file-sync-state current-graph)] - (when (and sync-state (not (sync-state--stopped? sync-state))) + (when (and sync-state (sync-state--valid-to-accept-filewatcher-event? sync-state)) (when (or (:mtime stat) (= type "unlink")) (go (let [path (remove-dir-prefix dir path) @@ -2039,6 +2040,13 @@ {:pre [(s/valid? ::sync-state sync-state)]} (= ::stop (:state sync-state))) +(defn sync-state--valid-to-accept-filewatcher-event? + [sync-state] + {:pre [(s/valid? ::sync-state sync-state)]} + (contains? #{::idle ::local->remote ::remote->local ::local->remote-full-sync ::remote->local-full-sync} + (:state sync-state))) + + ;;; ### remote->local syncer & local->remote syncer (defprotocol IRemote->LocalSync From 2c4798f6ddbd9c5dedfe7b25e9ae04f058d8ecb1 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 20 Sep 2022 16:47:05 +0800 Subject: [PATCH 10/10] fix: revise whiteboard saving throttle code --- src/main/frontend/handler/whiteboard.cljs | 1 - src/main/frontend/modules/outliner/file.cljs | 6 ++++-- .../frontend/modules/shortcut/before.cljs | 5 +++-- src/main/frontend/state.cljs | 21 ++++++++++++++----- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/frontend/handler/whiteboard.cljs b/src/main/frontend/handler/whiteboard.cljs index 58662d745..c0d5881fd 100644 --- a/src/main/frontend/handler/whiteboard.cljs +++ b/src/main/frontend/handler/whiteboard.cljs @@ -104,7 +104,6 @@ (let [{:keys [pages assets]} (js->clj tldr :keywordize-keys true) page (first pages) tx (tldr-page->blocks-tx page-name (assoc page :assets assets))] - (state/set-last-transact-time! (state/get-current-repo) (util/time-ms)) (db-utils/transact! tx))) (defn get-default-tldr diff --git a/src/main/frontend/modules/outliner/file.cljs b/src/main/frontend/modules/outliner/file.cljs index 1476b37fd..f004f9f79 100644 --- a/src/main/frontend/modules/outliner/file.cljs +++ b/src/main/frontend/modules/outliner/file.cljs @@ -42,8 +42,10 @@ page-db-id (:db/id page-block) whiteboard? (:block/whiteboard? page-block) blocks-count (model/get-page-blocks-count repo page-db-id)] - (if (and (or (> blocks-count 500) whiteboard?) - (not (state/input-idle? repo :diff 3000))) ; long page or whiteboard + (if (or (and (> blocks-count 500) + (not (state/input-idle? repo :diff 3000))) ;; long page + ;; when this whiteboard page is just being updated + (and whiteboard? (state/whiteboard-page-idle? repo page-block 3000))) (async/put! (state/get-file-write-chan) [repo page-db-id]) (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}) diff --git a/src/main/frontend/modules/shortcut/before.cljs b/src/main/frontend/modules/shortcut/before.cljs index 34cf13325..bc9b5a1a2 100644 --- a/src/main/frontend/modules/shortcut/before.cljs +++ b/src/main/frontend/modules/shortcut/before.cljs @@ -34,6 +34,7 @@ (fn [e] (when (and (or (contains? #{:srs :page-histories} (state/get-modal-id)) (not (state/block-component-editing?))) - (not (and (state/tldraw-idle?) - (not (state/editing?))))) + ;; should not enable when in whiteboard mode, but not editing a logseq block + (not (and (state/active-tldraw-app) + (not (state/tldraw-editing-logseq-block?))))) (f e)))) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 68235f98b..a64258d7b 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1400,12 +1400,11 @@ Similar to re-frame subscriptions" [] ^js js/window.tln) -(defn tldraw-idle? - "return true when tldraw is active and idle. nil when tldraw is - not active." +(defn tldraw-editing-logseq-block? [] (when-let [app (active-tldraw-app)] - (.. app -selectedTool (isIn "idle")))) + (and (= 1 (.. app -selectedShapesArray -length)) + (= (.. app -editingShape) (.. app -selectedShapesArray (at 0)))))) (defn set-graph-syncing? [value] @@ -1460,7 +1459,19 @@ Similar to re-frame subscriptions" (>= (- now last-time) diff))) ;; not in editing mode ;; Is this a good idea to put whiteboard check here? - (not (or (get-edit-input-id) (active-tldraw-app)))))) + (not (get-edit-input-id))))) + +(defn whiteboard-page-idle? + [repo whiteboard-page & {:keys [diff] + :or {diff 1000}}] + (when repo + (or + (when-let [last-time (:block/updated-at whiteboard-page)] + (let [now (util/time-ms)] + (>= (- now last-time) diff))) + ;; not in idle mode + (not (when-let [tldraw-app (active-tldraw-app)] + (.. tldraw-app -selectedTool (isIn "idle"))))))) (defn set-nfs-refreshing! [value]