diff --git a/packages/frontend/component/src/ui/loading/loading.tsx b/packages/frontend/component/src/ui/loading/loading.tsx
index 49e72705c..34195e5ec 100644
--- a/packages/frontend/component/src/ui/loading/loading.tsx
+++ b/packages/frontend/component/src/ui/loading/loading.tsx
@@ -5,9 +5,14 @@ import { loading, speedVar } from './styles.css';
export interface LoadingProps {
size?: number;
speed?: number;
+ progress?: number;
}
-export const Loading = ({ size, speed = 1.2 }: LoadingProps) => {
+export const Loading = ({
+ size,
+ speed = 1.2,
+ progress = 0.2,
+}: LoadingProps) => {
return (
);
diff --git a/packages/frontend/component/src/ui/loading/styles.css.ts b/packages/frontend/component/src/ui/loading/styles.css.ts
index 465f98986..94f92627c 100644
--- a/packages/frontend/component/src/ui/loading/styles.css.ts
+++ b/packages/frontend/component/src/ui/loading/styles.css.ts
@@ -13,5 +13,6 @@ export const loading = style({
},
textRendering: 'optimizeLegibility',
WebkitFontSmoothing: 'antialiased',
+ transform: 'rotate(-90deg)',
animation: `${rotate} ${speedVar} infinite linear`,
});
diff --git a/packages/frontend/core/src/components/pure/workspace-slider-bar/workspace-card/index.tsx b/packages/frontend/core/src/components/pure/workspace-slider-bar/workspace-card/index.tsx
index ceff61e90..1fef59aa3 100644
--- a/packages/frontend/core/src/components/pure/workspace-slider-bar/workspace-card/index.tsx
+++ b/packages/frontend/core/src/components/pure/workspace-slider-bar/workspace-card/index.tsx
@@ -15,7 +15,7 @@ import {
import { useWorkspaceBlobObjectUrl } from '@toeverything/hooks/use-workspace-blob';
import { useWorkspaceInfo } from '@toeverything/hooks/use-workspace-info';
import { useAtomValue } from 'jotai';
-import { debounce } from 'lodash-es';
+import { debounce, mean } from 'lodash-es';
import {
forwardRef,
type HTMLAttributes,
@@ -45,10 +45,10 @@ const CloudWorkspaceStatus = () => {
);
};
-const SyncingWorkspaceStatus = () => {
+const SyncingWorkspaceStatus = ({ progress }: { progress?: number }) => {
return (
<>
-
+
Syncing...
>
);
@@ -85,7 +85,7 @@ const OfflineStatus = () => {
);
};
-const WorkspaceStatus = () => {
+const useSyncEngineSyncProgress = () => {
const isOnline = useSystemOnline();
const [syncEngineStatus, setSyncEngineStatus] =
@@ -106,6 +106,24 @@ const WorkspaceStatus = () => {
};
}, [currentWorkspace]);
+ const progress = useMemo(() => {
+ if (!syncEngineStatus?.remotes || syncEngineStatus?.remotes.length === 0) {
+ return null;
+ }
+ return mean(
+ syncEngineStatus.remotes.map(peer => {
+ if (!peer) {
+ return 0;
+ }
+ const totalTask =
+ peer.totalDocs + peer.pendingPullUpdates + peer.pendingPushUpdates;
+ const doneTask = peer.loadedDocs;
+
+ return doneTask / totalTask;
+ })
+ );
+ }, [syncEngineStatus?.remotes]);
+
const content = useMemo(() => {
// TODO: add i18n
if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
@@ -118,38 +136,51 @@ const WorkspaceStatus = () => {
return 'Disconnected, please check your network connection';
}
if (!syncEngineStatus || syncEngineStatus.step === SyncEngineStep.Syncing) {
- return 'Syncing with AFFiNE Cloud';
+ return (
+ `Syncing with AFFiNE Cloud` +
+ (progress ? ` (${Math.floor(progress * 100)}%)` : '')
+ );
}
if (syncEngineStatus.retrying) {
return 'Sync disconnected due to unexpected issues, reconnecting.';
}
return 'Synced with AFFiNE Cloud';
- }, [currentWorkspace.flavour, isOnline, syncEngineStatus]);
+ }, [currentWorkspace.flavour, isOnline, progress, syncEngineStatus]);
const CloudWorkspaceSyncStatus = useCallback(() => {
if (!syncEngineStatus || syncEngineStatus.step === SyncEngineStep.Syncing) {
- return SyncingWorkspaceStatus();
+ return SyncingWorkspaceStatus({
+ progress: progress ? Math.max(progress, 0.2) : undefined,
+ });
} else if (syncEngineStatus.retrying) {
return UnSyncWorkspaceStatus();
} else {
return CloudWorkspaceStatus();
}
- }, [syncEngineStatus]);
+ }, [progress, syncEngineStatus]);
+
+ return {
+ message: content,
+ icon:
+ currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD ? (
+ !isOnline ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ ),
+ };
+};
+
+const WorkspaceStatus = () => {
+ const { message, icon } = useSyncEngineSyncProgress();
return (
-
-
- {currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD ? (
- !isOnline ? (
-
- ) : (
-
- )
- ) : (
-
- )}
-
+
+ {icon}
);