mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-29 16:19:43 +08:00
refactor: ui adapter (#2577)
This commit is contained in:
@@ -96,7 +96,7 @@ function AuthContext({ children }: PropsWithChildren): ReactElement {
|
|||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AffinePlugin: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
|
export const AffineAdapter: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
|
||||||
releaseType: ReleaseType.STABLE,
|
releaseType: ReleaseType.STABLE,
|
||||||
flavour: WorkspaceFlavour.AFFINE,
|
flavour: WorkspaceFlavour.AFFINE,
|
||||||
loadPriority: LoadPriority.HIGH,
|
loadPriority: LoadPriority.HIGH,
|
||||||
@@ -175,7 +175,7 @@ export const AffinePlugin: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
|
|||||||
|
|
||||||
await mutate(matcher => matcher === QueryKey.getWorkspaces);
|
await mutate(matcher => matcher === QueryKey.getWorkspaces);
|
||||||
// refresh the local storage
|
// refresh the local storage
|
||||||
await AffinePlugin.CRUD.list();
|
await AffineAdapter.CRUD.list();
|
||||||
return id;
|
return id;
|
||||||
},
|
},
|
||||||
delete: async workspace => {
|
delete: async workspace => {
|
||||||
@@ -208,7 +208,7 @@ export const AffinePlugin: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const workspaces: AffineLegacyCloudWorkspace[] =
|
const workspaces: AffineLegacyCloudWorkspace[] =
|
||||||
await AffinePlugin.CRUD.list();
|
await AffineAdapter.CRUD.list();
|
||||||
return (
|
return (
|
||||||
workspaces.find(workspace => workspace.id === workspaceId) ?? null
|
workspaces.find(workspace => workspace.id === workspaceId) ?? null
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const PageDetailEditor = lazy(() =>
|
|||||||
|
|
||||||
const logger = new DebugLogger('use-create-first-workspace');
|
const logger = new DebugLogger('use-create-first-workspace');
|
||||||
|
|
||||||
export const LocalPlugin: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
|
export const LocalAdapter: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
|
||||||
releaseType: ReleaseType.STABLE,
|
releaseType: ReleaseType.STABLE,
|
||||||
flavour: WorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
loadPriority: LoadPriority.LOW,
|
loadPriority: LoadPriority.LOW,
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import type { AppEvents } from '@affine/workspace/type';
|
import { Unreachable } from '@affine/env';
|
||||||
|
import type { AppEvents, WorkspaceUISchema } from '@affine/workspace/type';
|
||||||
import {
|
import {
|
||||||
LoadPriority,
|
LoadPriority,
|
||||||
ReleaseType,
|
ReleaseType,
|
||||||
WorkspaceFlavour,
|
WorkspaceFlavour,
|
||||||
} from '@affine/workspace/type';
|
} from '@affine/workspace/type';
|
||||||
|
|
||||||
import { AffinePlugin } from './affine';
|
import { AffineAdapter } from './affine';
|
||||||
import { LocalPlugin } from './local';
|
import { LocalAdapter } from './local';
|
||||||
import type { WorkspaceAdapter } from './type';
|
import type { WorkspaceAdapter } from './type';
|
||||||
|
|
||||||
const unimplemented = () => {
|
const unimplemented = () => {
|
||||||
@@ -14,8 +15,8 @@ const unimplemented = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const WorkspaceAdapters = {
|
export const WorkspaceAdapters = {
|
||||||
[WorkspaceFlavour.AFFINE]: AffinePlugin,
|
[WorkspaceFlavour.AFFINE]: AffineAdapter,
|
||||||
[WorkspaceFlavour.LOCAL]: LocalPlugin,
|
[WorkspaceFlavour.LOCAL]: LocalAdapter,
|
||||||
[WorkspaceFlavour.AFFINE_CLOUD]: {
|
[WorkspaceFlavour.AFFINE_CLOUD]: {
|
||||||
releaseType: ReleaseType.UNRELEASED,
|
releaseType: ReleaseType.UNRELEASED,
|
||||||
flavour: WorkspaceFlavour.AFFINE_CLOUD,
|
flavour: WorkspaceFlavour.AFFINE_CLOUD,
|
||||||
@@ -59,3 +60,13 @@ export const WorkspaceAdapters = {
|
|||||||
} satisfies {
|
} satisfies {
|
||||||
[Key in WorkspaceFlavour]: WorkspaceAdapter<Key>;
|
[Key in WorkspaceFlavour]: WorkspaceAdapter<Key>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getUIAdapter<Flavour extends WorkspaceFlavour>(
|
||||||
|
flavour: Flavour
|
||||||
|
): WorkspaceUISchema<Flavour> {
|
||||||
|
const ui = WorkspaceAdapters[flavour].UI as WorkspaceUISchema<Flavour>;
|
||||||
|
if (!ui) {
|
||||||
|
throw new Unreachable();
|
||||||
|
}
|
||||||
|
return ui;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { createDynamicRouteParser } from 'next-router-mock/dynamic-routes';
|
|||||||
import type { FC, PropsWithChildren } from 'react';
|
import type { FC, PropsWithChildren } from 'react';
|
||||||
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
|
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||||
|
|
||||||
import { LocalPlugin } from '../../adapters/local';
|
import { LocalAdapter } from '../../adapters/local';
|
||||||
import { workspacesAtom } from '../../atoms';
|
import { workspacesAtom } from '../../atoms';
|
||||||
import { BlockSuiteWorkspace } from '../../shared';
|
import { BlockSuiteWorkspace } from '../../shared';
|
||||||
import { WorkspaceSubPath } from '../../shared';
|
import { WorkspaceSubPath } from '../../shared';
|
||||||
@@ -92,7 +92,7 @@ describe('useRecentlyViewed', () => {
|
|||||||
flavour: WorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
LocalPlugin.CRUD.get = vi.fn().mockResolvedValue({
|
LocalAdapter.CRUD.get = vi.fn().mockResolvedValue({
|
||||||
id: workspaceId,
|
id: workspaceId,
|
||||||
flavour: WorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
blockSuiteWorkspace,
|
blockSuiteWorkspace,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { nanoid } from '@blocksuite/store';
|
|||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { LocalPlugin } from '../adapters/local';
|
import { LocalAdapter } from '../adapters/local';
|
||||||
import { WorkspaceAdapters } from '../adapters/workspace';
|
import { WorkspaceAdapters } from '../adapters/workspace';
|
||||||
import { workspacesAtom } from '../atoms';
|
import { workspacesAtom } from '../atoms';
|
||||||
import type { AllWorkspace } from '../shared';
|
import type { AllWorkspace } from '../shared';
|
||||||
@@ -62,7 +62,7 @@ export function useAppHelper() {
|
|||||||
WorkspaceFlavour.LOCAL
|
WorkspaceFlavour.LOCAL
|
||||||
);
|
);
|
||||||
blockSuiteWorkspace.meta.setName(name);
|
blockSuiteWorkspace.meta.setName(name);
|
||||||
const id = await LocalPlugin.CRUD.create(blockSuiteWorkspace);
|
const id = await LocalAdapter.CRUD.create(blockSuiteWorkspace);
|
||||||
set(workspaces => [
|
set(workspaces => [
|
||||||
...workspaces,
|
...workspaces,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||||
import type { BlockSuiteFeatureFlags } from '@affine/env';
|
import type { BlockSuiteFeatureFlags } from '@affine/env';
|
||||||
import { config } from '@affine/env';
|
import { config } from '@affine/env';
|
||||||
import { Unreachable } from '@affine/env/constant';
|
|
||||||
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
@@ -13,7 +11,7 @@ import { useRouter } from 'next/router';
|
|||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import { WorkspaceAdapters } from '../../../adapters/workspace';
|
import { getUIAdapter } from '../../../adapters/workspace';
|
||||||
import { rootCurrentWorkspaceAtom } from '../../../atoms/root';
|
import { rootCurrentWorkspaceAtom } from '../../../atoms/root';
|
||||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||||
import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views';
|
import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views';
|
||||||
@@ -57,28 +55,15 @@ const WorkspaceDetail: React.FC = () => {
|
|||||||
setEditorFlags(currentWorkspace.blockSuiteWorkspace);
|
setEditorFlags(currentWorkspace.blockSuiteWorkspace);
|
||||||
}
|
}
|
||||||
}, [currentWorkspace]);
|
}, [currentWorkspace]);
|
||||||
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
|
||||||
const PageDetail =
|
const { PageDetail } = getUIAdapter(currentWorkspace.flavour);
|
||||||
WorkspaceAdapters[currentWorkspace.flavour].UI.PageDetail;
|
return (
|
||||||
return (
|
<PageDetail
|
||||||
<PageDetail
|
currentWorkspace={currentWorkspace}
|
||||||
currentWorkspace={currentWorkspace}
|
currentPageId={currentPageId}
|
||||||
currentPageId={currentPageId}
|
onLoadEditor={onLoad}
|
||||||
onLoadEditor={onLoad}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
|
||||||
const PageDetail =
|
|
||||||
WorkspaceAdapters[currentWorkspace.flavour].UI.PageDetail;
|
|
||||||
return (
|
|
||||||
<PageDetail
|
|
||||||
currentWorkspace={currentWorkspace}
|
|
||||||
currentPageId={currentPageId}
|
|
||||||
onLoadEditor={onLoad}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw new Unreachable();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const WorkspaceDetailPage: NextPageWithLayout = () => {
|
const WorkspaceDetailPage: NextPageWithLayout = () => {
|
||||||
|
|||||||
@@ -6,16 +6,15 @@ import {
|
|||||||
ViewList,
|
ViewList,
|
||||||
} from '@affine/component/page-list';
|
} from '@affine/component/page-list';
|
||||||
import { config } from '@affine/env';
|
import { config } from '@affine/env';
|
||||||
import { QueryParamError, Unreachable } from '@affine/env/constant';
|
import { QueryParamError } from '@affine/env/constant';
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
|
||||||
import { FolderIcon } from '@blocksuite/icons';
|
import { FolderIcon } from '@blocksuite/icons';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
import { WorkspaceAdapters } from '../../../adapters/workspace';
|
import { getUIAdapter } from '../../../adapters/workspace';
|
||||||
import { PageLoading } from '../../../components/pure/loading';
|
import { PageLoading } from '../../../components/pure/loading';
|
||||||
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
||||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||||
@@ -78,58 +77,31 @@ const AllPage: NextPageWithLayout = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
|
||||||
const PageList = WorkspaceAdapters[currentWorkspace.flavour].UI.PageList;
|
const { PageList } = getUIAdapter(currentWorkspace.flavour);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{t['All pages']()} - AFFiNE</title>
|
<title>{t['All pages']()} - AFFiNE</title>
|
||||||
</Head>
|
</Head>
|
||||||
<WorkspaceTitle
|
<WorkspaceTitle
|
||||||
workspace={currentWorkspace}
|
workspace={currentWorkspace}
|
||||||
currentPage={null}
|
currentPage={null}
|
||||||
isPreview={false}
|
isPreview={false}
|
||||||
isPublic={false}
|
isPublic={false}
|
||||||
icon={<FolderIcon />}
|
icon={<FolderIcon />}
|
||||||
leftSlot={leftSlot}
|
leftSlot={leftSlot}
|
||||||
>
|
>
|
||||||
{t['All pages']()}
|
{t['All pages']()}
|
||||||
</WorkspaceTitle>
|
</WorkspaceTitle>
|
||||||
{filterContainer}
|
{filterContainer}
|
||||||
<PageList
|
<PageList
|
||||||
view={setting.currentView}
|
view={setting.currentView}
|
||||||
onOpenPage={onClickPage}
|
onOpenPage={onClickPage}
|
||||||
blockSuiteWorkspace={currentWorkspace.blockSuiteWorkspace}
|
blockSuiteWorkspace={currentWorkspace.blockSuiteWorkspace}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
|
||||||
const PageList = WorkspaceAdapters[currentWorkspace.flavour].UI.PageList;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>{t['All pages']()} - AFFiNE</title>
|
|
||||||
</Head>
|
|
||||||
<WorkspaceTitle
|
|
||||||
workspace={currentWorkspace}
|
|
||||||
currentPage={null}
|
|
||||||
isPreview={false}
|
|
||||||
isPublic={false}
|
|
||||||
icon={<FolderIcon />}
|
|
||||||
leftSlot={leftSlot}
|
|
||||||
>
|
|
||||||
{t['All pages']()}
|
|
||||||
</WorkspaceTitle>
|
|
||||||
{filterContainer}
|
|
||||||
<PageList
|
|
||||||
view={setting.currentView}
|
|
||||||
onOpenPage={onClickPage}
|
|
||||||
blockSuiteWorkspace={currentWorkspace.blockSuiteWorkspace}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw new Unreachable();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AllPage;
|
export default AllPage;
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
import { Unreachable } from '@affine/env/constant';
|
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||||
import type { SettingPanel } from '@affine/workspace/type';
|
import type { SettingPanel } from '@affine/workspace/type';
|
||||||
import {
|
import { settingPanel, settingPanelValues } from '@affine/workspace/type';
|
||||||
settingPanel,
|
|
||||||
settingPanelValues,
|
|
||||||
WorkspaceFlavour,
|
|
||||||
} from '@affine/workspace/type';
|
|
||||||
import { SettingsIcon } from '@blocksuite/icons';
|
import { SettingsIcon } from '@blocksuite/icons';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import { useAtom, useAtomValue } from 'jotai';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
@@ -16,7 +11,7 @@ import type { NextRouter } from 'next/router';
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import { WorkspaceAdapters } from '../../../adapters/workspace';
|
import { getUIAdapter } from '../../../adapters/workspace';
|
||||||
import { PageLoading } from '../../../components/pure/loading';
|
import { PageLoading } from '../../../components/pure/loading';
|
||||||
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
||||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||||
@@ -119,60 +114,31 @@ const SettingPage: NextPageWithLayout = () => {
|
|||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
} else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
|
} else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
|
||||||
const Setting =
|
|
||||||
WorkspaceAdapters[currentWorkspace.flavour].UI.SettingsDetail;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>{t['Settings']()} - AFFiNE</title>
|
|
||||||
</Head>
|
|
||||||
<WorkspaceTitle
|
|
||||||
workspace={currentWorkspace}
|
|
||||||
currentPage={null}
|
|
||||||
isPreview={false}
|
|
||||||
isPublic={false}
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
>
|
|
||||||
{t['Workspace Settings']()}
|
|
||||||
</WorkspaceTitle>
|
|
||||||
<Setting
|
|
||||||
onTransformWorkspace={onTransformWorkspace}
|
|
||||||
onDeleteWorkspace={onDeleteWorkspace}
|
|
||||||
currentWorkspace={currentWorkspace}
|
|
||||||
currentTab={currentTab as SettingPanel}
|
|
||||||
onChangeTab={onChangeTab}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
|
||||||
const Setting =
|
|
||||||
WorkspaceAdapters[currentWorkspace.flavour].UI.SettingsDetail;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>{t['Settings']()} - AFFiNE</title>
|
|
||||||
</Head>
|
|
||||||
<WorkspaceTitle
|
|
||||||
workspace={currentWorkspace}
|
|
||||||
currentPage={null}
|
|
||||||
isPreview={false}
|
|
||||||
isPublic={false}
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
>
|
|
||||||
{t['Workspace Settings']()}
|
|
||||||
</WorkspaceTitle>
|
|
||||||
<Setting
|
|
||||||
onTransformWorkspace={onTransformWorkspace}
|
|
||||||
onDeleteWorkspace={onDeleteWorkspace}
|
|
||||||
currentWorkspace={currentWorkspace}
|
|
||||||
currentTab={currentTab as SettingPanel}
|
|
||||||
onChangeTab={onChangeTab}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
throw new Unreachable();
|
const { SettingsDetail } = getUIAdapter(currentWorkspace.flavour);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{t['Settings']()} - AFFiNE</title>
|
||||||
|
</Head>
|
||||||
|
<WorkspaceTitle
|
||||||
|
workspace={currentWorkspace}
|
||||||
|
currentPage={null}
|
||||||
|
isPreview={false}
|
||||||
|
isPublic={false}
|
||||||
|
icon={<SettingsIcon />}
|
||||||
|
>
|
||||||
|
{t['Workspace Settings']()}
|
||||||
|
</WorkspaceTitle>
|
||||||
|
<SettingsDetail
|
||||||
|
onTransformWorkspace={onTransformWorkspace}
|
||||||
|
onDeleteWorkspace={onDeleteWorkspace}
|
||||||
|
currentWorkspace={currentWorkspace}
|
||||||
|
currentTab={currentTab as SettingPanel}
|
||||||
|
onChangeTab={onChangeTab}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SettingPage;
|
export default SettingPage;
|
||||||
|
|||||||
Reference in New Issue
Block a user