From 0e581c915cdb734a13c39526bc6c4f03a25903d0 Mon Sep 17 00:00:00 2001 From: EYHN Date: Mon, 24 Feb 2025 10:22:34 +0000 Subject: [PATCH] feat(core): add resetSync button (#10404) --- packages/common/nbstore/src/frontend/doc.ts | 4 +++ packages/common/nbstore/src/sync/doc/index.ts | 10 +++++++ packages/common/nbstore/src/worker/client.ts | 4 +++ .../common/nbstore/src/worker/consumer.ts | 1 + packages/common/nbstore/src/worker/ops.ts | 1 + .../workspace-setting/preference/index.tsx | 26 +++++++++++++++++++ 6 files changed, 46 insertions(+) diff --git a/packages/common/nbstore/src/frontend/doc.ts b/packages/common/nbstore/src/frontend/doc.ts index 74042d9f43..516a616b53 100644 --- a/packages/common/nbstore/src/frontend/doc.ts +++ b/packages/common/nbstore/src/frontend/doc.ts @@ -534,4 +534,8 @@ export class DocFrontend { sub?.unsubscribe(); }); } + + async resetSync() { + await this.sync.resetSync(); + } } diff --git a/packages/common/nbstore/src/sync/doc/index.ts b/packages/common/nbstore/src/sync/doc/index.ts index db9e30e3df..ae572cdf0f 100644 --- a/packages/common/nbstore/src/sync/doc/index.ts +++ b/packages/common/nbstore/src/sync/doc/index.ts @@ -27,6 +27,7 @@ export interface DocSync { readonly state$: Observable; docState$(docId: string): Observable; addPriority(id: string, priority: number): () => void; + resetSync(): Promise; } export class DocSyncImpl implements DocSync { @@ -127,4 +128,13 @@ export class DocSyncImpl implements DocSync { const undo = this.peers.map(peer => peer.addPriority(id, priority)); return () => undo.forEach(fn => fn()); } + + async resetSync() { + const running = this.abort !== null; + this.stop(); + await this.sync.clearClocks(); + if (running) { + this.start(); + } + } } diff --git a/packages/common/nbstore/src/worker/client.ts b/packages/common/nbstore/src/worker/client.ts index 1b50bb94ec..7dbeec2f6b 100644 --- a/packages/common/nbstore/src/worker/client.ts +++ b/packages/common/nbstore/src/worker/client.ts @@ -222,6 +222,10 @@ class WorkerDocSync implements DocSync { subscription.unsubscribe(); }; } + + resetSync(): Promise { + return this.client.call('docSync.resetSync'); + } } class WorkerBlobSync implements BlobSync { diff --git a/packages/common/nbstore/src/worker/consumer.ts b/packages/common/nbstore/src/worker/consumer.ts index 106be1ef8b..cffc864b1d 100644 --- a/packages/common/nbstore/src/worker/consumer.ts +++ b/packages/common/nbstore/src/worker/consumer.ts @@ -231,6 +231,7 @@ class StoreConsumer { const undo = this.docSync.addPriority(docId, priority); return () => undo(); }), + 'docSync.resetSync': () => this.docSync.resetSync(), 'blobSync.downloadBlob': key => this.blobSync.downloadBlob(key), 'blobSync.uploadBlob': blob => this.blobSync.uploadBlob(blob), 'blobSync.fullSync': () => diff --git a/packages/common/nbstore/src/worker/ops.ts b/packages/common/nbstore/src/worker/ops.ts index 1618d89a07..cbdeefa682 100644 --- a/packages/common/nbstore/src/worker/ops.ts +++ b/packages/common/nbstore/src/worker/ops.ts @@ -81,6 +81,7 @@ interface GroupedWorkerOps { state: [void, DocSyncState]; docState: [string, DocSyncDocState]; addPriority: [{ docId: string; priority: number }, boolean]; + resetSync: [void, void]; }; blobSync: { diff --git a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/preference/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/preference/index.tsx index c492e4e0a4..b30eb935eb 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/preference/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/preference/index.tsx @@ -8,7 +8,9 @@ import { WorkspaceServerService } from '@affine/core/modules/cloud'; import { WorkspaceService } from '@affine/core/modules/workspace'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant'; import { useI18n } from '@affine/i18n'; +import { ArrowRightSmallIcon } from '@blocksuite/icons/rc'; import { FrameworkScope, useService } from '@toeverything/infra'; +import { useCallback } from 'react'; import { DeleteLeaveWorkspace } from './delete-leave-workspace'; import { EnableCloudPanel } from './enable-cloud'; @@ -28,6 +30,17 @@ export const WorkspaceSettingDetail = ({ const workspaceInfo = useWorkspaceInfo(workspace); + const handleResetSyncStatus = useCallback(() => { + workspace?.engine.doc + .resetSync() + .then(() => { + onCloseSetting(); + }) + .catch(err => { + console.error(err); + }); + }, [onCloseSetting, workspace]); + return ( + + {t['com.affine.resetSyncStatus.button']()} + + } + desc={t['com.affine.resetSyncStatus.description']()} + style={{ cursor: 'pointer' }} + onClick={handleResetSyncStatus} + data-testid="reset-sync-status" + > + + );