import { atomWithSyncStorage } from '@affine/jotai'; import { jotaiStore, jotaiWorkspacesAtom } from '@affine/workspace/atom'; import type { EditorContainer } from '@blocksuite/editor'; import type { Page } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store'; import { atom } from 'jotai'; import { unstable_batchedUpdates } from 'react-dom'; import { WorkspacePlugins } from '../plugins'; import type { AllWorkspace } from '../shared'; // workspace necessary atoms export const currentWorkspaceIdAtom = atom(null); export const currentPageIdAtom = atom(null); export const currentEditorAtom = atom | null>(null); // If the workspace is locked, it means that the user maybe updating the workspace // from local to remote or vice versa export const workspaceLockAtom = atom(false); export async function lockMutex(fn: () => Promise) { if (jotaiStore.get(workspaceLockAtom)) { throw new Error('Workspace is locked'); } unstable_batchedUpdates(() => { jotaiStore.set(workspaceLockAtom, true); }); await fn(); unstable_batchedUpdates(() => { jotaiStore.set(workspaceLockAtom, false); }); } // modal atoms export const openWorkspacesModalAtom = atom(false); export const openCreateWorkspaceModalAtom = atom(false); export const openQuickSearchModalAtom = atom(false); export const workspacesAtom = atom>(async get => { const flavours: string[] = Object.values(WorkspacePlugins).map( plugin => plugin.flavour ); const jotaiWorkspaces = get(jotaiWorkspacesAtom).filter(workspace => flavours.includes(workspace.flavour) ); const workspaces = await Promise.all( jotaiWorkspaces.map(workspace => { const plugin = WorkspacePlugins[workspace.flavour as keyof typeof WorkspacePlugins]; assertExists(plugin); const { CRUD } = plugin; return CRUD.get(workspace.id); }) ); return workspaces.filter(workspace => workspace !== null) as AllWorkspace[]; }); type View = { id: string; mode: 'page' | 'edgeless' }; export type WorkspaceRecentViews = Record; export const workspaceRecentViewsAtom = atomWithSyncStorage('recentViews', {}); export type PreferredModeRecord = Record; export const workspacePreferredModeAtom = atomWithSyncStorage('preferredMode', {}); export const workspaceRecentViresWriteAtom = atom( null, (get, set, id, value) => { const record = get(workspaceRecentViewsAtom); if (Array.isArray(record[id])) { const idx = record[id].findIndex(view => view.id === value.id); if (idx !== -1) { record[id].splice(idx, 1); } record[id] = [value, ...record[id]]; } else { record[id] = [value]; } record[id] = record[id].slice(0, 3); set(workspaceRecentViewsAtom, { ...record }); return record[id]; } );