mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
refactor!: next generation AFFiNE code structure (#1176)
This commit is contained in:
220
apps/web/src/plugins/local/index.tsx
Normal file
220
apps/web/src/plugins/local/index.tsx
Normal file
@@ -0,0 +1,220 @@
|
||||
import { assertEquals, uuidv4 } from '@blocksuite/store';
|
||||
import React from 'react';
|
||||
import { IndexeddbPersistence } from 'y-indexeddb';
|
||||
|
||||
import { createLocalProviders } from '../../blocksuite';
|
||||
import { PageNotFoundError } from '../../components/affine/affine-error-eoundary';
|
||||
import { WorkspaceSettingDetail } from '../../components/affine/workspace-setting-detail';
|
||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||
import { PageDetailEditor } from '../../components/page-detail-editor';
|
||||
import {
|
||||
LoadPriority,
|
||||
LocalWorkspace,
|
||||
RemWorkspaceFlavour,
|
||||
} from '../../shared';
|
||||
import { config } from '../../shared/env';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
import { WorkspacePlugin } from '..';
|
||||
|
||||
export const kStoreKey = 'affine-local-workspace';
|
||||
|
||||
export const LocalPlugin: WorkspacePlugin<RemWorkspaceFlavour.LOCAL> = {
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
loadPriority: LoadPriority.LOW,
|
||||
createWorkspace: async blockSuiteWorkspace => {
|
||||
let ids: string[] = [];
|
||||
try {
|
||||
ids = JSON.parse(localStorage.getItem(kStoreKey) ?? '[]');
|
||||
if (!Array.isArray(ids)) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
} catch (e) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
const id = uuidv4();
|
||||
const persistence = new IndexeddbPersistence(id, blockSuiteWorkspace.doc);
|
||||
await persistence.whenSynced.then(() => {
|
||||
persistence.destroy();
|
||||
});
|
||||
ids.push(id);
|
||||
localStorage.setItem(kStoreKey, JSON.stringify(ids));
|
||||
return id;
|
||||
},
|
||||
deleteWorkspace: async workspace => {
|
||||
const id = workspace.id;
|
||||
let ids: string[];
|
||||
try {
|
||||
ids = JSON.parse(localStorage.getItem(kStoreKey) ?? '[]');
|
||||
if (!Array.isArray(ids)) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
} catch (e) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
const idx = ids.findIndex(x => x === id);
|
||||
if (idx === -1) {
|
||||
throw new Error('cannot find local workspace from localStorage');
|
||||
}
|
||||
workspace.providers.forEach(p => p.cleanup());
|
||||
ids.splice(idx, 1);
|
||||
assertEquals(
|
||||
ids.every(id => typeof id === 'string'),
|
||||
true
|
||||
);
|
||||
localStorage.setItem(kStoreKey, JSON.stringify(ids));
|
||||
},
|
||||
prefetchData: async (dataCenter, signal) => {
|
||||
if (typeof window === 'undefined') {
|
||||
// SSR mode, no local data
|
||||
return;
|
||||
}
|
||||
if (signal?.aborted) {
|
||||
return;
|
||||
}
|
||||
let ids: string[];
|
||||
try {
|
||||
ids = JSON.parse(localStorage.getItem(kStoreKey) ?? '[]');
|
||||
if (!Array.isArray(ids)) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
} catch (e) {
|
||||
localStorage.setItem(kStoreKey, '[]');
|
||||
ids = [];
|
||||
}
|
||||
if (config.enableIndexedDBProvider) {
|
||||
const workspaces = await Promise.all(
|
||||
ids.map(id => {
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(id);
|
||||
const workspace: LocalWorkspace = {
|
||||
id,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace: blockSuiteWorkspace,
|
||||
providers: [...createLocalProviders(blockSuiteWorkspace)],
|
||||
syncBinary: async () => {
|
||||
if (!config.enableIndexedDBProvider) {
|
||||
return {
|
||||
...workspace,
|
||||
};
|
||||
}
|
||||
const persistence = new IndexeddbPersistence(
|
||||
blockSuiteWorkspace.room as string,
|
||||
blockSuiteWorkspace.doc
|
||||
);
|
||||
return persistence.whenSynced.then(() => {
|
||||
persistence.destroy();
|
||||
return {
|
||||
...workspace,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
return workspace.syncBinary();
|
||||
})
|
||||
);
|
||||
workspaces.forEach(workspace => {
|
||||
if (workspace) {
|
||||
const exist = dataCenter.workspaces.findIndex(
|
||||
w => w.id === workspace.id
|
||||
);
|
||||
if (exist === -1) {
|
||||
dataCenter.workspaces = [...dataCenter.workspaces, workspace];
|
||||
} else {
|
||||
dataCenter.workspaces[exist] = workspace;
|
||||
dataCenter.workspaces = [...dataCenter.workspaces];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (dataCenter.workspaces.length === 0) {
|
||||
if (signal?.aborted) {
|
||||
return;
|
||||
}
|
||||
console.info('no local workspace found, create a new one');
|
||||
const workspaceId = uuidv4();
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(workspaceId);
|
||||
blockSuiteWorkspace.meta.setName('Untitled Workspace');
|
||||
localStorage.setItem(kStoreKey, JSON.stringify([workspaceId]));
|
||||
blockSuiteWorkspace.createPage(uuidv4());
|
||||
const workspace: LocalWorkspace = {
|
||||
id: workspaceId,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace: blockSuiteWorkspace,
|
||||
providers: [...createLocalProviders(blockSuiteWorkspace)],
|
||||
syncBinary: async () => {
|
||||
if (!config.enableIndexedDBProvider) {
|
||||
return {
|
||||
...workspace,
|
||||
};
|
||||
}
|
||||
const persistence = new IndexeddbPersistence(
|
||||
blockSuiteWorkspace.room as string,
|
||||
blockSuiteWorkspace.doc
|
||||
);
|
||||
return persistence.whenSynced.then(() => {
|
||||
persistence.destroy();
|
||||
return {
|
||||
...workspace,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
await workspace.syncBinary();
|
||||
if (signal?.aborted) {
|
||||
const persistence = new IndexeddbPersistence(
|
||||
blockSuiteWorkspace.room as string,
|
||||
blockSuiteWorkspace.doc
|
||||
);
|
||||
await persistence.clearData();
|
||||
return;
|
||||
}
|
||||
dataCenter.workspaces = [workspace];
|
||||
}
|
||||
},
|
||||
PageDetail: ({ currentWorkspace, currentPageId }) => {
|
||||
const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
|
||||
if (!page) {
|
||||
throw new PageNotFoundError(
|
||||
currentWorkspace.blockSuiteWorkspace,
|
||||
currentPageId
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<PageDetailEditor
|
||||
pageId={currentPageId}
|
||||
blockSuiteWorkspace={currentWorkspace.blockSuiteWorkspace}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
},
|
||||
PageList: ({ blockSuiteWorkspace, onOpenPage }) => {
|
||||
return (
|
||||
<BlockSuitePageList
|
||||
onOpenPage={onOpenPage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
);
|
||||
},
|
||||
SettingsDetail: ({
|
||||
currentWorkspace,
|
||||
onChangeTab,
|
||||
currentTab,
|
||||
onDeleteWorkspace,
|
||||
onTransformWorkspace,
|
||||
}) => {
|
||||
return (
|
||||
<WorkspaceSettingDetail
|
||||
onDeleteWorkspace={onDeleteWorkspace}
|
||||
onChangeTab={onChangeTab}
|
||||
currentTab={currentTab}
|
||||
workspace={currentWorkspace}
|
||||
onTransferWorkspace={onTransformWorkspace}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user