mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-28 12:32:09 +03:00
Merge pull request #864 from toeverything/feat/sync-status
Feat/sync status
This commit is contained in:
commit
d135bcb2fd
@ -4,13 +4,15 @@ import { Button } from '@/ui/button';
|
|||||||
import { Check, UnCheck } from './icon';
|
import { Check, UnCheck } from './icon';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { useAppState } from '@/providers/app-state-provider';
|
||||||
interface LoginModalProps {
|
interface LoginModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: (wait: boolean) => void;
|
onClose: (wait: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LogoutModal = ({ open, onClose }: LoginModalProps) => {
|
export const LogoutModal = ({ open, onClose }: LoginModalProps) => {
|
||||||
const [localCache, setLocalCache] = useState(false);
|
const [localCache, setLocalCache] = useState(true);
|
||||||
|
const { blobDataSynced } = useAppState();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Modal open={open} onClose={onClose} data-testid="logout-modal">
|
<Modal open={open} onClose={onClose} data-testid="logout-modal">
|
||||||
@ -24,7 +26,11 @@ export const LogoutModal = ({ open, onClose }: LoginModalProps) => {
|
|||||||
</Header>
|
</Header>
|
||||||
<Content>
|
<Content>
|
||||||
<ContentTitle>{t('Sign out')}?</ContentTitle>
|
<ContentTitle>{t('Sign out')}?</ContentTitle>
|
||||||
<SignDes>{t('Set up an AFFiNE account to sync data')}</SignDes>
|
<SignDes>
|
||||||
|
{blobDataSynced
|
||||||
|
? t('Set up an AFFiNE account to sync data')
|
||||||
|
: 'All data has been stored in the cloud'}
|
||||||
|
</SignDes>
|
||||||
<StyleTips>
|
<StyleTips>
|
||||||
{localCache ? (
|
{localCache ? (
|
||||||
<StyleCheck
|
<StyleCheck
|
||||||
|
@ -38,7 +38,7 @@ export const useEnsureWorkspace = () => {
|
|||||||
// }
|
// }
|
||||||
const workspaceId =
|
const workspaceId =
|
||||||
(router.query.workspaceId as string) || workspaceList[0]?.id;
|
(router.query.workspaceId as string) || workspaceList[0]?.id;
|
||||||
loadWorkspace(workspaceId).finally(() => {
|
loadWorkspace.current(workspaceId).finally(() => {
|
||||||
setWorkspaceLoaded(true);
|
setWorkspaceLoaded(true);
|
||||||
setActiveWorkspaceId(activeWorkspaceId);
|
setActiveWorkspaceId(activeWorkspaceId);
|
||||||
});
|
});
|
||||||
|
@ -4,9 +4,11 @@ import { PageListHeader } from '@/components/header';
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { PageMeta, useAppState } from '@/providers/app-state-provider';
|
||||||
const All = () => {
|
const All = () => {
|
||||||
const { pageList } = useAppState();
|
const { currentWorkspace } = useAppState();
|
||||||
|
const pageList = (currentWorkspace?.blocksuiteWorkspace?.meta.pageMetas ||
|
||||||
|
[]) as PageMeta[];
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -10,16 +10,20 @@ import {
|
|||||||
import { createDefaultWorkspace } from './utils';
|
import { createDefaultWorkspace } from './utils';
|
||||||
import { User } from '@affine/datacenter';
|
import { User } from '@affine/datacenter';
|
||||||
|
|
||||||
|
export interface Disposable {
|
||||||
|
dispose(): void;
|
||||||
|
}
|
||||||
|
|
||||||
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
|
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
|
||||||
|
|
||||||
export const AppState = createContext<AppStateContext>({} as AppStateContext);
|
export const AppState = createContext<AppStateContext>({} as AppStateContext);
|
||||||
|
|
||||||
export const useAppState = () => useContext(AppState);
|
export const useAppState = () => useContext(AppState);
|
||||||
|
|
||||||
export const AppStateProvider = ({
|
export const AppStateProvider = ({
|
||||||
children,
|
children,
|
||||||
}: PropsWithChildren<AppStateContextProps>) => {
|
}: PropsWithChildren<AppStateContextProps>) => {
|
||||||
const [appState, setAppState] = useState<AppStateValue>({} as AppStateValue);
|
const [appState, setAppState] = useState<AppStateValue>({} as AppStateValue);
|
||||||
|
const [blobState, setBlobState] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initState = async () => {
|
const initState = async () => {
|
||||||
const dataCenter = await getDataCenter();
|
const dataCenter = await getDataCenter();
|
||||||
@ -90,7 +94,8 @@ export const AppStateProvider = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadWorkspace = useRef<AppStateFunction['loadWorkspace']>();
|
const loadWorkspace: AppStateFunction['loadWorkspace'] =
|
||||||
|
useRef() as AppStateFunction['loadWorkspace'];
|
||||||
loadWorkspace.current = async (workspaceId: string) => {
|
loadWorkspace.current = async (workspaceId: string) => {
|
||||||
const { dataCenter, workspaceList, currentWorkspace, user } = appState;
|
const { dataCenter, workspaceList, currentWorkspace, user } = appState;
|
||||||
if (!workspaceList.find(v => v.id.toString() === workspaceId)) {
|
if (!workspaceList.find(v => v.id.toString() === workspaceId)) {
|
||||||
@ -99,6 +104,7 @@ export const AppStateProvider = ({
|
|||||||
if (workspaceId === currentWorkspace?.id) {
|
if (workspaceId === currentWorkspace?.id) {
|
||||||
return currentWorkspace;
|
return currentWorkspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
const workspace = (await dataCenter.loadWorkspace(workspaceId)) ?? null;
|
const workspace = (await dataCenter.loadWorkspace(workspaceId)) ?? null;
|
||||||
let isOwner;
|
let isOwner;
|
||||||
if (workspace?.provider === 'local') {
|
if (workspace?.provider === 'local') {
|
||||||
@ -108,6 +114,7 @@ export const AppStateProvider = ({
|
|||||||
// We must ensure workspace.owner exists, then ensure id same.
|
// We must ensure workspace.owner exists, then ensure id same.
|
||||||
isOwner = workspace?.owner && user?.id === workspace.owner.id;
|
isOwner = workspace?.owner && user?.id === workspace.owner.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageList =
|
const pageList =
|
||||||
(workspace?.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]) ?? [];
|
(workspace?.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]) ?? [];
|
||||||
setAppState({
|
setAppState({
|
||||||
@ -122,6 +129,26 @@ export const AppStateProvider = ({
|
|||||||
return workspace;
|
return workspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let syncChangeDisposable: Disposable | undefined;
|
||||||
|
const currentWorkspace = appState.currentWorkspace;
|
||||||
|
if (!currentWorkspace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const getBlobStorage = async () => {
|
||||||
|
const blobStorage = await currentWorkspace?.blocksuiteWorkspace?.blobs;
|
||||||
|
syncChangeDisposable = blobStorage?.signals.onBlobSyncStateChange.on(
|
||||||
|
() => {
|
||||||
|
setBlobState(blobStorage?.uploading);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
getBlobStorage();
|
||||||
|
return () => {
|
||||||
|
syncChangeDisposable?.dispose();
|
||||||
|
};
|
||||||
|
}, [appState.currentWorkspace]);
|
||||||
|
|
||||||
const setEditor: AppStateFunction['setEditor'] =
|
const setEditor: AppStateFunction['setEditor'] =
|
||||||
useRef() as AppStateFunction['setEditor'];
|
useRef() as AppStateFunction['setEditor'];
|
||||||
setEditor.current = editor => {
|
setEditor.current = editor => {
|
||||||
@ -163,9 +190,10 @@ export const AppStateProvider = ({
|
|||||||
...appState,
|
...appState,
|
||||||
setEditor,
|
setEditor,
|
||||||
loadPage: loadPage.current,
|
loadPage: loadPage.current,
|
||||||
loadWorkspace: loadWorkspace.current,
|
loadWorkspace: loadWorkspace,
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
|
blobDataSynced: blobState,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -24,12 +24,15 @@ export type AppStateValue = {
|
|||||||
editor?: EditorContainer | null;
|
editor?: EditorContainer | null;
|
||||||
synced: boolean;
|
synced: boolean;
|
||||||
isOwner?: boolean;
|
isOwner?: boolean;
|
||||||
|
blobDataSynced?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AppStateFunction = {
|
export type AppStateFunction = {
|
||||||
setEditor: MutableRefObject<(page: EditorContainer) => void>;
|
setEditor: MutableRefObject<(page: EditorContainer) => void>;
|
||||||
|
|
||||||
loadWorkspace: (workspaceId: string) => Promise<WorkspaceUnit | null>;
|
loadWorkspace: MutableRefObject<
|
||||||
|
(workspaceId: string) => Promise<WorkspaceUnit | null>
|
||||||
|
>;
|
||||||
loadPage: (pageId: string) => void;
|
loadPage: (pageId: string) => void;
|
||||||
|
|
||||||
login: () => Promise<User>;
|
login: () => Promise<User>;
|
||||||
|
Loading…
Reference in New Issue
Block a user