mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { nanoid } from '@blocksuite/store';
|
|
import { useAtomValue, useSetAtom } from 'jotai';
|
|
import { useCallback, useEffect } from 'react';
|
|
|
|
import { jotaiWorkspacesAtom, workspacesAtom } from '../atoms';
|
|
import { WorkspacePlugins } from '../plugins';
|
|
import { LocalPlugin } from '../plugins/local';
|
|
import type { LocalWorkspace, RemWorkspace } from '../shared';
|
|
import { RemWorkspaceFlavour } from '../shared';
|
|
import { createEmptyBlockSuiteWorkspace } from '../utils';
|
|
|
|
export function useWorkspaces(): RemWorkspace[] {
|
|
return useAtomValue(workspacesAtom);
|
|
}
|
|
|
|
export function useWorkspacesHelper() {
|
|
const workspaces = useWorkspaces();
|
|
const jotaiWorkspaces = useAtomValue(jotaiWorkspacesAtom);
|
|
const set = useSetAtom(jotaiWorkspacesAtom);
|
|
return {
|
|
createWorkspacePage: useCallback(
|
|
(workspaceId: string, pageId: string) => {
|
|
const workspace = workspaces.find(
|
|
ws => ws.id === workspaceId
|
|
) as LocalWorkspace;
|
|
if (workspace && 'blockSuiteWorkspace' in workspace) {
|
|
workspace.blockSuiteWorkspace.createPage(pageId);
|
|
} else {
|
|
throw new Error('cannot create page. blockSuiteWorkspace not found');
|
|
}
|
|
},
|
|
[workspaces]
|
|
),
|
|
createLocalWorkspace: useCallback(
|
|
async (name: string): Promise<string> => {
|
|
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
|
nanoid(),
|
|
_ => undefined
|
|
);
|
|
blockSuiteWorkspace.meta.setName(name);
|
|
const id = await LocalPlugin.CRUD.create(blockSuiteWorkspace);
|
|
set(workspaces => [
|
|
...workspaces,
|
|
{
|
|
id,
|
|
flavour: RemWorkspaceFlavour.LOCAL,
|
|
},
|
|
]);
|
|
return id;
|
|
},
|
|
[set]
|
|
),
|
|
deleteWorkspace: useCallback(
|
|
async (workspaceId: string) => {
|
|
const targetJotaiWorkspace = jotaiWorkspaces.find(
|
|
ws => ws.id === workspaceId
|
|
);
|
|
const targetWorkspace = workspaces.find(ws => ws.id === workspaceId);
|
|
if (!targetJotaiWorkspace || !targetWorkspace) {
|
|
throw new Error('page cannot be found');
|
|
}
|
|
|
|
// delete workspace from plugin
|
|
await WorkspacePlugins[targetWorkspace.flavour].CRUD.delete(
|
|
// fixme: type casting
|
|
targetWorkspace as any
|
|
);
|
|
// delete workspace from jotai storage
|
|
set(workspaces => workspaces.filter(ws => ws.id !== workspaceId));
|
|
},
|
|
[jotaiWorkspaces, set, workspaces]
|
|
),
|
|
};
|
|
}
|
|
|
|
export const useElementResizeEffect = (
|
|
element: Element | null,
|
|
fn: () => void | (() => () => void),
|
|
// TODO: add throttle
|
|
throttle = 0
|
|
) => {
|
|
useEffect(() => {
|
|
if (!element) {
|
|
return;
|
|
}
|
|
let dispose: void | (() => void);
|
|
const resizeObserver = new ResizeObserver(entries => {
|
|
dispose = fn();
|
|
});
|
|
resizeObserver.observe(element);
|
|
return () => {
|
|
dispose?.();
|
|
resizeObserver.disconnect();
|
|
};
|
|
}, [element, fn]);
|
|
};
|