fix: add router defend

This commit is contained in:
QiShaoXuan
2022-12-22 18:35:51 +08:00
parent cc910dd9e9
commit a64f77c9d2
18 changed files with 284 additions and 120 deletions
@@ -23,6 +23,7 @@ export interface AppStateValue {
currentPage: StorePage | null;
editor: EditorContainer | null;
synced: boolean;
}
export interface AppStateContext extends AppStateValue {
@@ -31,15 +32,9 @@ export interface AppStateContext extends AppStateValue {
((page: StorePage) => EditorContainer | null) | undefined
>;
setEditor?: MutableRefObject<((page: EditorContainer) => void) | undefined>;
loadWorkspace?: MutableRefObject<
((workspaceId: string) => Promise<StoreWorkspace | null> | null) | undefined
>;
loadPage?: MutableRefObject<
((pageId: string) => Promise<StorePage | null> | null) | undefined
>;
createPage?: MutableRefObject<
((pageId?: string) => Promise<string | null>) | undefined
>;
loadWorkspace: (workspaceId: string) => Promise<StoreWorkspace | null>;
loadPage: (pageId: string) => Promise<StorePage | null>;
createPage: (pageId?: string) => Promise<string | null>;
}
export const AppState = createContext<AppStateContext>({
@@ -56,9 +51,10 @@ export const AppState = createContext<AppStateContext>({
setState: () => {},
createEditor: undefined,
setEditor: undefined,
loadWorkspace: undefined,
loadPage: undefined,
createPage: undefined,
loadWorkspace: () => Promise.resolve(null),
loadPage: () => Promise.resolve(null),
createPage: () => Promise.resolve(null),
synced: false,
workspaces: {},
});
@@ -89,15 +89,12 @@ const DynamicBlocksuite = ({
p => p instanceof IndexedDBDocProvider
);
if (indexDBProvider) {
(indexDBProvider as IndexedDBDocProvider).on('synced', async () => {
const updates = await downloadWorkspace({ workspaceId });
if (updates && updates.byteLength) {
Workspace.Y.applyUpdate(workspace.doc, new Uint8Array(updates));
// if after update, the space:meta is empty, then we need to get map with doc
workspace.doc.getMap('space:meta');
}
(indexDBProvider as IndexedDBDocProvider)?.on('synced', async () => {
// const updates = await downloadWorkspace({ workspaceId });
// updates &&
// Workspace.Y.applyUpdate(workspace.doc, new Uint8Array(updates));
// if after update, the space:meta is empty, then we need to get map with doc
workspace.doc.getMap('space:meta');
resolve(workspace);
});
} else {
@@ -9,7 +9,7 @@ export const useLoadWorkspace = () => {
const workspaceId = router.query.workspaceId as string;
useEffect(() => {
loadWorkspace?.current?.(workspaceId);
loadWorkspace?.(workspaceId);
}, [workspaceId, loadWorkspace]);
return currentWorkspaceId === workspaceId ? currentWorkspace : null;
@@ -29,7 +29,7 @@ export const useLoadPage = () => {
}
const page = pageId ? workspace?.getPage(pageId) : null;
if (page) {
loadPage?.current?.(pageId);
loadPage?.(pageId);
return;
}
@@ -39,7 +39,7 @@ export const useLoadPage = () => {
return;
}
createPage?.current?.()?.then(async pageId => {
createPage?.()?.then(async pageId => {
if (!pageId) {
return;
}
@@ -8,7 +8,7 @@ import {
WorkspaceType,
getWorkspaceDetail,
} from '@pathfinder/data-services';
import { AppState } from './context';
import { AppState, AppStateContext } from './context';
import type {
AppStateValue,
CreateEditorHandler,
@@ -29,6 +29,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
currentPage: null,
editor: null,
workspaces: {},
// Synced is used to ensure that the provider has synced with the server,
// So after Synced set to true, the other state is sure to be set.
synced: false,
});
const [loadWorkspaceHandler, _setLoadWorkspaceHandler] =
@@ -50,12 +53,14 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
[_setCreateEditorHandler]
);
const loadWorkspace =
useRef<(workspaceId: string) => Promise<Workspace | null> | null>();
const loadWorkspace = useRef<AppStateContext['loadWorkspace']>(() =>
Promise.resolve(null)
);
loadWorkspace.current = async (workspaceId: string) => {
if (state.currentWorkspaceId === workspaceId) {
return state.currentWorkspace;
}
const workspace = (await loadWorkspaceHandler?.(workspaceId, true)) || null;
// @ts-expect-error
@@ -72,7 +77,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
}));
return workspace;
};
const loadPage = useRef<(pageId: string) => Promise<Page | null> | null>();
const loadPage = useRef<AppStateContext['loadPage']>(() =>
Promise.resolve(null)
);
loadPage.current = async (pageId: string) => {
const { currentWorkspace, currentPage } = state;
if (pageId === currentPage?.pageId) {
@@ -114,7 +121,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
setState(state => ({ ...state, editor }));
};
const createPage = useRef<(pageId?: string) => Promise<string | null>>();
const createPage = useRef<AppStateContext['createPage']>(() =>
Promise.resolve(null)
);
createPage.current = (pageId: string = Date.now().toString()) =>
new Promise<string | null>(resolve => {
@@ -130,8 +139,16 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
});
useEffect(() => {
if (!loadWorkspaceHandler) {
return;
}
const callback = async (user: AccessTokenMessage | null) => {
const workspacesMeta = user ? await getWorkspaces() : [];
const workspacesMeta = user
? await getWorkspaces().catch(() => {
return [];
})
: [];
const workspacesList = await Promise.all(
workspacesMeta.map(async ({ id }) => {
const workspace = (await loadWorkspaceHandler?.(id)) || null;
@@ -146,7 +163,13 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
});
// TODO: add meta info to workspace meta
setState(state => ({ ...state, user: user, workspacesMeta, workspaces }));
setState(state => ({
...state,
user: user,
workspacesMeta,
workspaces,
synced: true,
}));
};
authorizationEvent.onChange(callback);
@@ -161,9 +184,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
setState,
createEditor,
setEditor,
loadWorkspace,
loadPage,
createPage,
loadWorkspace: loadWorkspace.current,
loadPage: loadPage.current,
createPage: createPage.current,
}),
[state, setState, loadPage, loadWorkspace]
);
@@ -174,7 +197,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
setLoadWorkspaceHandler={setLoadWorkspaceHandler}
setCreateEditorHandler={setCreateEditorHandler}
/>
{loadWorkspaceHandler ? children : null}
{children}
</AppState.Provider>
);
};
@@ -1,4 +1,4 @@
import { createContext, useContext, useState } from 'react';
import { createContext, useContext, useEffect, useState } from 'react';
import type { PropsWithChildren } from 'react';
import ShortcutsModal from '@/components/shortcuts-modal';
import ContactModal from '@/components/contact-modal';
@@ -49,6 +49,10 @@ export const ModalProvider = ({
[key]: visible ?? !modalMap[key],
});
};
useEffect(() => {
// @ts-ignore
window.triggerHandler = () => triggerHandler('login');
}, [triggerHandler]);
return (
<ModalContext.Provider