mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-21 03:56:23 +08:00
199 lines
6.0 KiB
TypeScript
199 lines
6.0 KiB
TypeScript
import type { NextRouter } from 'next/router';
|
|
import { useEffect } from 'react';
|
|
|
|
import { currentPageIdAtom, jotaiStore } from '../atoms';
|
|
import type { RemWorkspace } from '../shared';
|
|
import { RemWorkspaceFlavour } from '../shared';
|
|
import { useCurrentPageId } from './current/use-current-page-id';
|
|
import { useCurrentWorkspace } from './current/use-current-workspace';
|
|
import { useWorkspaces } from './use-workspaces';
|
|
|
|
export function findSuitablePageId(
|
|
workspace: RemWorkspace,
|
|
targetId: string
|
|
): string | null {
|
|
switch (workspace.flavour) {
|
|
case RemWorkspaceFlavour.AFFINE: {
|
|
return (
|
|
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
|
page => page.id === targetId
|
|
)?.id ??
|
|
workspace.blockSuiteWorkspace.meta.pageMetas.at(0)?.id ??
|
|
null
|
|
);
|
|
}
|
|
case RemWorkspaceFlavour.LOCAL: {
|
|
return (
|
|
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
|
page => page.id === targetId
|
|
)?.id ??
|
|
workspace.blockSuiteWorkspace.meta.pageMetas.at(0)?.id ??
|
|
null
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
export const REDIRECT_TIMEOUT = 1000;
|
|
export function useSyncRouterWithCurrentWorkspaceAndPage(router: NextRouter) {
|
|
const [currentWorkspace, setCurrentWorkspaceId] = useCurrentWorkspace();
|
|
const [currentPageId, setCurrentPageId] = useCurrentPageId();
|
|
const workspaces = useWorkspaces();
|
|
useEffect(() => {
|
|
const listener: Parameters<typeof router.events.on>[1] = (url: string) => {
|
|
if (url.startsWith('/')) {
|
|
const path = url.split('/');
|
|
if (path.length === 4 && path[1] === 'workspace') {
|
|
if (
|
|
path[3] === 'all' ||
|
|
path[3] === 'setting' ||
|
|
path[3] === 'trash' ||
|
|
path[3] === 'favorite'
|
|
) {
|
|
return;
|
|
}
|
|
setCurrentWorkspaceId(path[2]);
|
|
if (currentWorkspace && 'blockSuiteWorkspace' in currentWorkspace) {
|
|
if (currentWorkspace.blockSuiteWorkspace.getPage(path[3])) {
|
|
setCurrentPageId(path[3]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
router.events.on('routeChangeStart', listener);
|
|
return () => {
|
|
router.events.off('routeChangeStart', listener);
|
|
};
|
|
}, [currentWorkspace, router, setCurrentPageId, setCurrentWorkspaceId]);
|
|
useEffect(() => {
|
|
if (!router.isReady) {
|
|
return;
|
|
}
|
|
if (
|
|
router.pathname === '/workspace/[workspaceId]/[pageId]' ||
|
|
router.pathname === '/'
|
|
) {
|
|
const targetPageId = router.query.pageId;
|
|
const targetWorkspaceId = router.query.workspaceId;
|
|
if (currentWorkspace && currentPageId) {
|
|
if (
|
|
currentWorkspace.id === targetWorkspaceId &&
|
|
currentPageId === targetPageId
|
|
) {
|
|
return;
|
|
}
|
|
}
|
|
if (
|
|
typeof targetPageId !== 'string' ||
|
|
typeof targetWorkspaceId !== 'string'
|
|
) {
|
|
if (router.asPath === '/') {
|
|
const first = workspaces.at(0);
|
|
if (first && 'blockSuiteWorkspace' in first) {
|
|
const targetWorkspaceId = first.id;
|
|
const targetPageId =
|
|
first.blockSuiteWorkspace.meta.pageMetas.at(0)?.id;
|
|
if (targetPageId) {
|
|
setCurrentWorkspaceId(targetWorkspaceId);
|
|
setCurrentPageId(targetPageId);
|
|
router.push(`/workspace/${targetWorkspaceId}/${targetPageId}`);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (!currentWorkspace) {
|
|
const targetWorkspace = workspaces.find(
|
|
workspace => workspace.id === targetPageId
|
|
);
|
|
if (targetWorkspace) {
|
|
setCurrentWorkspaceId(targetWorkspace.id);
|
|
router.push({
|
|
query: {
|
|
...router.query,
|
|
workspaceId: targetWorkspace.id,
|
|
},
|
|
});
|
|
return;
|
|
} else {
|
|
const first = workspaces.at(0);
|
|
if (first) {
|
|
setCurrentWorkspaceId(first.id);
|
|
router.push({
|
|
query: {
|
|
...router.query,
|
|
workspaceId: first.id,
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
if (!currentPageId && currentWorkspace) {
|
|
const targetId = findSuitablePageId(currentWorkspace, targetPageId);
|
|
if (targetId) {
|
|
setCurrentPageId(targetId);
|
|
router.push({
|
|
query: {
|
|
...router.query,
|
|
workspaceId: currentWorkspace.id,
|
|
pageId: targetId,
|
|
},
|
|
});
|
|
return;
|
|
} else {
|
|
const dispose =
|
|
currentWorkspace.blockSuiteWorkspace.slots.pageAdded.on(
|
|
pageId => {
|
|
if (pageId === targetPageId) {
|
|
dispose.dispose();
|
|
setCurrentPageId(pageId);
|
|
router.push({
|
|
query: {
|
|
...router.query,
|
|
workspaceId: currentWorkspace.id,
|
|
pageId: targetPageId,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
);
|
|
const clearId = setTimeout(() => {
|
|
if (jotaiStore.get(currentPageIdAtom) === null) {
|
|
const id =
|
|
currentWorkspace.blockSuiteWorkspace.meta.pageMetas.at(0)?.id;
|
|
if (id) {
|
|
router.push({
|
|
query: {
|
|
...router.query,
|
|
workspaceId: currentWorkspace.id,
|
|
pageId: id,
|
|
},
|
|
});
|
|
setCurrentPageId(id);
|
|
}
|
|
}
|
|
dispose.dispose();
|
|
}, REDIRECT_TIMEOUT);
|
|
return () => {
|
|
clearTimeout(clearId);
|
|
dispose.dispose();
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, [
|
|
currentPageId,
|
|
currentWorkspace,
|
|
router.query.workspaceId,
|
|
router.query.pageId,
|
|
setCurrentPageId,
|
|
setCurrentWorkspaceId,
|
|
workspaces,
|
|
router,
|
|
]);
|
|
}
|