mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
refactor: init package @affine/workspace (#1661)
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/i18n": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/workspace": "workspace:*",
|
||||
"@blocksuite/blocks": "0.5.0-20230323085636-3110abb",
|
||||
"@blocksuite/editor": "0.5.0-20230323085636-3110abb",
|
||||
"@blocksuite/icons": "2.0.23",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
@@ -6,7 +7,7 @@ import { atomWithStorage } from 'jotai/utils';
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
|
||||
import { WorkspacePlugins } from '../plugins';
|
||||
import type { RemWorkspace, RemWorkspaceFlavour } from '../shared';
|
||||
import type { RemWorkspace } from '../shared';
|
||||
// workspace necessary atoms
|
||||
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
||||
export const currentPageIdAtom = atom<string | null>(null);
|
||||
@@ -37,7 +38,7 @@ export const jotaiStore = createStore();
|
||||
|
||||
type JotaiWorkspace = {
|
||||
id: string;
|
||||
flavour: RemWorkspaceFlavour;
|
||||
flavour: WorkspaceFlavour;
|
||||
};
|
||||
|
||||
export const jotaiWorkspacesAtom = atomWithStorage<JotaiWorkspace[]>(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { atom } from 'jotai/index';
|
||||
|
||||
import { BlockSuiteWorkspace } from '../../shared';
|
||||
import { apis } from '../../shared/apis';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
|
||||
export const publicWorkspaceIdAtom = atom<string | null>(null);
|
||||
export const publicBlockSuiteAtom = atom<Promise<BlockSuiteWorkspace>>(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { Generator } from '@blocksuite/store';
|
||||
import type React from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../../utils';
|
||||
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
||||
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
import 'fake-indexeddb/auto';
|
||||
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { render, renderHook } from '@testing-library/react';
|
||||
import { createStore, getDefaultStore, Provider } from 'jotai';
|
||||
@@ -20,7 +21,7 @@ import {
|
||||
import { useBlockSuiteWorkspaceHelper } from '../../hooks/use-blocksuite-workspace-helper';
|
||||
import { useWorkspacesHelper } from '../../hooks/use-workspaces';
|
||||
import { ThemeProvider } from '../../providers/ThemeProvider';
|
||||
import { pathGenerator, RemWorkspaceFlavour } from '../../shared';
|
||||
import { pathGenerator } from '../../shared';
|
||||
import { WorkSpaceSliderBar } from '../pure/workspace-slider-bar';
|
||||
|
||||
vi.mock('../blocksuite/header/editor-mode-switch/CustomLottie', () => ({
|
||||
@@ -92,7 +93,7 @@ describe('WorkSpaceSliderBar', () => {
|
||||
currentWorkspaceHook.result.current[1](id);
|
||||
const currentWorkspace = await store.get(currentWorkspaceAtom);
|
||||
expect(currentWorkspace).toBeDefined();
|
||||
expect(currentWorkspace?.flavour).toBe(RemWorkspaceFlavour.LOCAL);
|
||||
expect(currentWorkspace?.flavour).toBe(WorkspaceFlavour.LOCAL);
|
||||
expect(currentWorkspace?.id).toBe(id);
|
||||
const app = render(<App />);
|
||||
const card = await app.findByTestId('current-workspace');
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import type { SettingPanel, WorkspaceRegistry } from '@affine/workspace/type';
|
||||
import { settingPanel, WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type { MouseEvent } from 'react';
|
||||
import type React from 'react';
|
||||
import { Suspense, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
@@ -6,12 +8,7 @@ import { preload } from 'swr';
|
||||
|
||||
import { useIsWorkspaceOwner } from '../../../hooks/affine/use-is-workspace-owner';
|
||||
import { fetcher, QueryKey } from '../../../plugins/affine/fetcher';
|
||||
import type {
|
||||
AffineOfficialWorkspace,
|
||||
FlavourToWorkspace,
|
||||
SettingPanel,
|
||||
} from '../../../shared';
|
||||
import { RemWorkspaceFlavour, settingPanel } from '../../../shared';
|
||||
import type { AffineOfficialWorkspace } from '../../../shared';
|
||||
import { CollaborationPanel } from './panel/collaboration';
|
||||
import { ExportPanel } from './panel/export';
|
||||
import { GeneralPanel } from './panel/general';
|
||||
@@ -31,12 +28,12 @@ export type WorkspaceSettingDetailProps = {
|
||||
onChangeTab: (tab: SettingPanel) => void;
|
||||
onDeleteWorkspace: () => void;
|
||||
onTransferWorkspace: <
|
||||
From extends RemWorkspaceFlavour,
|
||||
To extends RemWorkspaceFlavour
|
||||
From extends WorkspaceFlavour,
|
||||
To extends WorkspaceFlavour
|
||||
>(
|
||||
from: From,
|
||||
to: To,
|
||||
workspace: FlavourToWorkspace[From]
|
||||
workspace: WorkspaceRegistry[From]
|
||||
) => void;
|
||||
};
|
||||
|
||||
@@ -49,8 +46,7 @@ const panelMap = {
|
||||
},
|
||||
[settingPanel.Sync]: {
|
||||
name: 'Sync',
|
||||
enable: (flavour: RemWorkspaceFlavour) =>
|
||||
flavour === RemWorkspaceFlavour.AFFINE,
|
||||
enable: (flavour: WorkspaceFlavour) => flavour === WorkspaceFlavour.AFFINE,
|
||||
ui: SyncPanel,
|
||||
},
|
||||
[settingPanel.Collaboration]: {
|
||||
@@ -68,7 +64,7 @@ const panelMap = {
|
||||
} satisfies {
|
||||
[Key in SettingPanel]: {
|
||||
name: string;
|
||||
enable?: (flavour: RemWorkspaceFlavour) => boolean;
|
||||
enable?: (flavour: WorkspaceFlavour) => boolean;
|
||||
ui: React.FC<PanelProps>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '@affine/component';
|
||||
import { PermissionType } from '@affine/datacenter';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import {
|
||||
DeleteTemporarilyIcon,
|
||||
EmailIcon,
|
||||
@@ -18,7 +19,6 @@ import { useCallback, useState } from 'react';
|
||||
|
||||
import { useMembers } from '../../../../../hooks/affine/use-members';
|
||||
import type { AffineWorkspace, LocalWorkspace } from '../../../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
||||
import { Unreachable } from '../../../affine-error-eoundary';
|
||||
import { TransformWorkspaceToAffineModal } from '../../../transform-workspace-to-affine-modal';
|
||||
import type { PanelProps } from '../../index';
|
||||
@@ -194,8 +194,8 @@ const LocalCollaborationPanel: React.FC<
|
||||
}}
|
||||
onConform={() => {
|
||||
onTransferWorkspace(
|
||||
RemWorkspaceFlavour.LOCAL,
|
||||
RemWorkspaceFlavour.AFFINE,
|
||||
WorkspaceFlavour.LOCAL,
|
||||
WorkspaceFlavour.AFFINE,
|
||||
workspace
|
||||
);
|
||||
setOpen(false);
|
||||
@@ -207,13 +207,13 @@ const LocalCollaborationPanel: React.FC<
|
||||
|
||||
export const CollaborationPanel: React.FC<PanelProps> = props => {
|
||||
switch (props.workspace.flavour) {
|
||||
case RemWorkspaceFlavour.AFFINE: {
|
||||
case WorkspaceFlavour.AFFINE: {
|
||||
const workspace = props.workspace as AffineWorkspace;
|
||||
return (
|
||||
<AffineRemoteCollaborationPanel {...props} workspace={workspace} />
|
||||
);
|
||||
}
|
||||
case RemWorkspaceFlavour.LOCAL: {
|
||||
case WorkspaceFlavour.LOCAL: {
|
||||
const workspace = props.workspace as LocalWorkspace;
|
||||
return <LocalCollaborationPanel {...props} workspace={workspace} />;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Button, Input, Modal, ModalCloseButton } from '@affine/component';
|
||||
import { Trans, useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { useBlockSuiteWorkspaceName } from '../../../../../../hooks/use-blocksuite-workspace-name';
|
||||
import type { AffineOfficialWorkspace } from '../../../../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../../../../shared';
|
||||
import {
|
||||
StyledButtonContent,
|
||||
StyledInputContent,
|
||||
@@ -43,7 +43,7 @@ export const WorkspaceDeleteModal = ({
|
||||
<StyledModalWrapper>
|
||||
<ModalCloseButton onClick={onClose} />
|
||||
<StyledModalHeader>{t('Delete Workspace')}?</StyledModalHeader>
|
||||
{workspace.flavour === RemWorkspaceFlavour.LOCAL ? (
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<StyledTextContent>
|
||||
<Trans i18nKey="Delete Workspace Description">
|
||||
Deleting (
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Button, FlexWrapper, MuiFade } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type React from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useIsWorkspaceOwner } from '../../../../../hooks/affine/use-is-workspace-owner';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
||||
import { Upload } from '../../../../pure/file-upload';
|
||||
import {
|
||||
CloudWorkspaceIcon,
|
||||
@@ -161,7 +161,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
<StyledRow>
|
||||
<StyledSettingKey>{t('Workspace Type')}</StyledSettingKey>
|
||||
{isOwner ? (
|
||||
workspace.flavour === RemWorkspaceFlavour.LOCAL ? (
|
||||
workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<StyledWorkspaceInfo>
|
||||
<LocalWorkspaceIcon />
|
||||
<span>{t('Local Workspace')}</span>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Wrapper,
|
||||
} from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { Box } from '@mui/material';
|
||||
import type React from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
@@ -17,7 +18,6 @@ import type {
|
||||
AffineWorkspace,
|
||||
LocalWorkspace,
|
||||
} from '../../../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
||||
import { Unreachable } from '../../../affine-error-eoundary';
|
||||
import { EnableAffineCloudModal } from '../../../enable-affine-cloud-modal';
|
||||
import type { WorkspaceSettingDetailProps } from '../../index';
|
||||
@@ -133,8 +133,8 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
||||
}}
|
||||
onConfirm={() => {
|
||||
onTransferWorkspace(
|
||||
RemWorkspaceFlavour.LOCAL,
|
||||
RemWorkspaceFlavour.AFFINE,
|
||||
WorkspaceFlavour.LOCAL,
|
||||
WorkspaceFlavour.AFFINE,
|
||||
workspace
|
||||
);
|
||||
setOpen(false);
|
||||
@@ -145,9 +145,9 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
||||
};
|
||||
|
||||
export const PublishPanel: React.FC<PublishPanelProps> = props => {
|
||||
if (props.workspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
||||
if (props.workspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||
return <PublishPanelAffine {...props} workspace={props.workspace} />;
|
||||
} else if (props.workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
} else if (props.workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
return <PublishPanelLocal {...props} workspace={props.workspace} />;
|
||||
}
|
||||
throw new Unreachable();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Content, FlexWrapper, styled } from '@affine/component';
|
||||
import { Trans, useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type React from 'react';
|
||||
|
||||
import { useCurrentUser } from '../../../../../hooks/current/use-current-user';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
||||
import { WorkspaceAvatar } from '../../../../pure/footer';
|
||||
import type { PanelProps } from '../../index';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const StyledWorkspaceName = styled('span')(({ theme }) => {
|
||||
});
|
||||
|
||||
export const SyncPanel: React.FC<PanelProps> = ({ workspace }) => {
|
||||
if (workspace.flavour !== RemWorkspaceFlavour.AFFINE) {
|
||||
if (workspace.flavour !== WorkspaceFlavour.AFFINE) {
|
||||
throw new TypeError('SyncPanel can only be used with Affine workspace');
|
||||
}
|
||||
const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { displayFlex, IconButton, styled, Tooltip } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import {
|
||||
CloudWorkspaceIcon,
|
||||
LocalWorkspaceIcon,
|
||||
@@ -15,7 +16,6 @@ import type {
|
||||
AffineOfficialWorkspace,
|
||||
LocalWorkspace,
|
||||
} from '../../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../../shared';
|
||||
import { apis } from '../../../../shared/apis';
|
||||
import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal';
|
||||
|
||||
@@ -117,10 +117,10 @@ export const SyncUser = () => {
|
||||
router.reload();
|
||||
return;
|
||||
}
|
||||
assertEquals(workspace.flavour, RemWorkspaceFlavour.LOCAL);
|
||||
assertEquals(workspace.flavour, WorkspaceFlavour.LOCAL);
|
||||
const id = await transformWorkspace(
|
||||
RemWorkspaceFlavour.LOCAL,
|
||||
RemWorkspaceFlavour.AFFINE,
|
||||
WorkspaceFlavour.LOCAL,
|
||||
WorkspaceFlavour.AFFINE,
|
||||
workspace as LocalWorkspace
|
||||
);
|
||||
// fixme(himself65): refactor this
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { PermissionType } from '@affine/datacenter';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { SettingsIcon } from '@blocksuite/icons';
|
||||
import type React from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useBlockSuiteWorkspaceName } from '../../../hooks/use-blocksuite-workspace-name';
|
||||
import type { RemWorkspace } from '../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../shared';
|
||||
import {
|
||||
CloudWorkspaceIcon,
|
||||
JoinedWorkspaceIcon,
|
||||
@@ -28,13 +28,13 @@ export type WorkspaceTypeProps = {
|
||||
const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
|
||||
const { t } = useTranslation();
|
||||
let isOwner = true;
|
||||
if (workspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
||||
if (workspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||
isOwner = workspace.permission === PermissionType.Owner;
|
||||
} else if (workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
} else if (workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
isOwner = true;
|
||||
}
|
||||
|
||||
if (workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
if (workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
return (
|
||||
<p title={t('Local Workspace')}>
|
||||
<LocalWorkspaceIcon />
|
||||
@@ -85,19 +85,18 @@ export const WorkspaceCard: React.FC<WorkspaceCardProps> = ({
|
||||
<StyleWorkspaceInfo>
|
||||
<StyleWorkspaceTitle>{name}</StyleWorkspaceTitle>
|
||||
<WorkspaceType workspace={workspace} />
|
||||
{workspace.flavour === RemWorkspaceFlavour.LOCAL && (
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL && (
|
||||
<p title={t('Available Offline')}>
|
||||
<LocalDataIcon />
|
||||
<span>{t('Available Offline')}</span>
|
||||
</p>
|
||||
)}
|
||||
{workspace.flavour === RemWorkspaceFlavour.AFFINE &&
|
||||
workspace.public && (
|
||||
<p title={t('Published to Web')}>
|
||||
<PublishIcon />
|
||||
<span>{t('Published to Web')}</span>
|
||||
</p>
|
||||
)}
|
||||
{workspace.flavour === WorkspaceFlavour.AFFINE && workspace.public && (
|
||||
<p title={t('Published to Web')}>
|
||||
<PublishIcon />
|
||||
<span>{t('Published to Web')}</span>
|
||||
</p>
|
||||
)}
|
||||
</StyleWorkspaceInfo>
|
||||
<StyledSettingLink
|
||||
className="setting-entry"
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'fake-indexeddb/auto';
|
||||
|
||||
import assert from 'node:assert';
|
||||
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
@@ -23,7 +24,7 @@ import {
|
||||
} from '../../atoms';
|
||||
import { LocalPlugin } from '../../plugins/local';
|
||||
import type { LocalWorkspace } from '../../shared';
|
||||
import { BlockSuiteWorkspace, RemWorkspaceFlavour } from '../../shared';
|
||||
import { BlockSuiteWorkspace } from '../../shared';
|
||||
import { useIsFirstLoad, useOpenTips } from '../affine/use-is-first-load';
|
||||
import {
|
||||
useRecentlyViewed,
|
||||
@@ -181,7 +182,7 @@ describe('useWorkspaces', () => {
|
||||
expect(result2.current.length).toEqual(1);
|
||||
const firstWorkspace = result2.current[0];
|
||||
expect(firstWorkspace.flavour).toBe('local');
|
||||
assert(firstWorkspace.flavour === RemWorkspaceFlavour.LOCAL);
|
||||
assert(firstWorkspace.flavour === WorkspaceFlavour.LOCAL);
|
||||
expect(firstWorkspace.blockSuiteWorkspace.meta.name).toBe('test');
|
||||
});
|
||||
});
|
||||
@@ -266,12 +267,12 @@ describe('useRecentlyViewed', () => {
|
||||
store.set(jotaiWorkspacesAtom, [
|
||||
{
|
||||
id: workspaceId,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
LocalPlugin.CRUD.get = vi.fn().mockResolvedValue({
|
||||
id: workspaceId,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace,
|
||||
providers: [],
|
||||
} satisfies LocalWorkspace);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
||||
import { useAtom } from 'jotai/index';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { jotaiWorkspacesAtom } from '../atoms';
|
||||
import { LocalPlugin } from '../plugins/local';
|
||||
import { RemWorkspaceFlavour } from '../shared';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../utils';
|
||||
|
||||
export function useCreateFirstWorkspace() {
|
||||
const [jotaiWorkspaces, set] = useAtom(jotaiWorkspacesAtom);
|
||||
@@ -29,7 +29,7 @@ export function useCreateFirstWorkspace() {
|
||||
set([
|
||||
{
|
||||
id: workspace.id,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
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';
|
||||
@@ -13,7 +13,7 @@ export function findSuitablePageId(
|
||||
targetId: string
|
||||
): string | null {
|
||||
switch (workspace.flavour) {
|
||||
case RemWorkspaceFlavour.AFFINE: {
|
||||
case WorkspaceFlavour.AFFINE: {
|
||||
return (
|
||||
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
||||
page => page.id === targetId
|
||||
@@ -22,7 +22,7 @@ export function findSuitablePageId(
|
||||
null
|
||||
);
|
||||
}
|
||||
case RemWorkspaceFlavour.LOCAL: {
|
||||
case WorkspaceFlavour.LOCAL: {
|
||||
return (
|
||||
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
||||
page => page.id === targetId
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type { WorkspaceRegistry } from '@affine/workspace/type';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { jotaiWorkspacesAtom } from '../atoms';
|
||||
import { WorkspacePlugins } from '../plugins';
|
||||
import type { FlavourToWorkspace, RemWorkspaceFlavour } from '../shared';
|
||||
|
||||
/**
|
||||
* Transform workspace from one flavour to another
|
||||
@@ -13,10 +14,10 @@ import type { FlavourToWorkspace, RemWorkspaceFlavour } from '../shared';
|
||||
export function useTransformWorkspace() {
|
||||
const set = useSetAtom(jotaiWorkspacesAtom);
|
||||
return useCallback(
|
||||
async <From extends RemWorkspaceFlavour, To extends RemWorkspaceFlavour>(
|
||||
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||
from: From,
|
||||
to: To,
|
||||
workspace: FlavourToWorkspace[From]
|
||||
workspace: WorkspaceRegistry[From]
|
||||
): Promise<string> => {
|
||||
await WorkspacePlugins[from].CRUD.delete(workspace as any);
|
||||
const newId = await WorkspacePlugins[to].CRUD.create(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
@@ -6,8 +8,6 @@ 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);
|
||||
@@ -43,7 +43,7 @@ export function useWorkspacesHelper() {
|
||||
...workspaces,
|
||||
{
|
||||
id,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
return id;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Button, toast } from '@affine/component';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { Typography } from '@mui/material';
|
||||
import type React from 'react';
|
||||
@@ -9,7 +10,6 @@ import { createBroadCastChannelProvider } from '../../blocksuite/providers';
|
||||
import PageList from '../../components/blocksuite/block-suite-page-list/page-list';
|
||||
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
||||
import type { BroadCastChannelProvider } from '../../shared';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
|
||||
const logger = new DebugLogger('broadcast');
|
||||
|
||||
|
||||
78
apps/web/src/pages/_debug/login.dev.tsx
Normal file
78
apps/web/src/pages/_debug/login.dev.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Button, toast } from '@affine/component';
|
||||
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
|
||||
import {
|
||||
clearLoginStorage,
|
||||
createAffineAuth,
|
||||
getLoginStorage,
|
||||
isExpired,
|
||||
parseIdToken,
|
||||
setLoginStorage,
|
||||
SignMethod,
|
||||
} from '@affine/workspace/affine/login';
|
||||
import { useAtom } from 'jotai';
|
||||
import type { NextPage } from 'next';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
||||
|
||||
const LoginDevPage: NextPage = () => {
|
||||
const [user, setUser] = useAtom(currentAffineUserAtom);
|
||||
const auth = useMemo(() => createAffineAuth(), []);
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledWrapper>
|
||||
<h1>LoginDevPage</h1>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const storage = getLoginStorage();
|
||||
if (storage) {
|
||||
const user = parseIdToken(storage.token);
|
||||
if (isExpired(user)) {
|
||||
await auth.refreshToken(storage);
|
||||
}
|
||||
}
|
||||
const response = await auth.generateToken(SignMethod.Google);
|
||||
if (response) {
|
||||
setLoginStorage(response);
|
||||
const user = parseIdToken(response.token);
|
||||
setUser(user);
|
||||
} else {
|
||||
toast('Login failed');
|
||||
}
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const storage = getLoginStorage();
|
||||
if (!storage) {
|
||||
throw new Error('No storage');
|
||||
}
|
||||
const response = await auth.refreshToken(storage);
|
||||
if (response) {
|
||||
setLoginStorage(response);
|
||||
const user = parseIdToken(response.token);
|
||||
setUser(user);
|
||||
} else {
|
||||
toast('Login failed');
|
||||
}
|
||||
}}
|
||||
>
|
||||
Refresh Token
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
clearLoginStorage();
|
||||
setUser(null);
|
||||
}}
|
||||
>
|
||||
Reset Storage
|
||||
</Button>
|
||||
{user && JSON.stringify(user)}
|
||||
</StyledWrapper>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginDevPage;
|
||||
@@ -1,3 +1,4 @@
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { ContentParser } from '@blocksuite/blocks/content-parser';
|
||||
import type {
|
||||
GetStaticPaths,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
StyledWrapper,
|
||||
} from '../../layouts/styles';
|
||||
import type { BlockSuiteWorkspace } from '../../shared';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
|
||||
export type PreviewPageProps = {
|
||||
text: string;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { useRouter } from 'next/router';
|
||||
import type React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
@@ -11,7 +12,6 @@ import { useSyncRouterWithCurrentWorkspaceAndPage } from '../../../hooks/use-syn
|
||||
import { WorkspaceLayout } from '../../../layouts';
|
||||
import { WorkspacePlugins } from '../../../plugins';
|
||||
import type { BlockSuiteWorkspace, NextPageWithLayout } from '../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../shared';
|
||||
|
||||
function enableFullFlags(blockSuiteWorkspace: BlockSuiteWorkspace) {
|
||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_set_remote_flag', false);
|
||||
@@ -38,12 +38,12 @@ const WorkspaceDetail: React.FC = () => {
|
||||
if (!pageId) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
||||
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
||||
return (
|
||||
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
||||
);
|
||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
||||
return (
|
||||
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { FolderIcon } from '@blocksuite/icons';
|
||||
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
||||
import Head from 'next/head';
|
||||
@@ -20,7 +21,6 @@ import type {
|
||||
LocalIndexedDBProvider,
|
||||
NextPageWithLayout,
|
||||
} from '../../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../../shared';
|
||||
|
||||
const AllPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
@@ -78,7 +78,7 @@ const AllPage: NextPageWithLayout = () => {
|
||||
if (currentWorkspace === null) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
||||
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
||||
return (
|
||||
<>
|
||||
@@ -92,7 +92,7 @@ const AllPage: NextPageWithLayout = () => {
|
||||
/>
|
||||
</>
|
||||
);
|
||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import type { SettingPanel, WorkspaceRegistry } from '@affine/workspace/type';
|
||||
import {
|
||||
settingPanel,
|
||||
settingPanelValues,
|
||||
WorkspaceFlavour,
|
||||
} from '@affine/workspace/type';
|
||||
import { SettingsIcon } from '@blocksuite/icons';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { useAtom } from 'jotai';
|
||||
@@ -16,16 +22,7 @@ import { useTransformWorkspace } from '../../../hooks/use-transform-workspace';
|
||||
import { useWorkspacesHelper } from '../../../hooks/use-workspaces';
|
||||
import { WorkspaceLayout } from '../../../layouts';
|
||||
import { WorkspacePlugins } from '../../../plugins';
|
||||
import type {
|
||||
FlavourToWorkspace,
|
||||
NextPageWithLayout,
|
||||
SettingPanel,
|
||||
} from '../../../shared';
|
||||
import {
|
||||
RemWorkspaceFlavour,
|
||||
settingPanel,
|
||||
settingPanelValues,
|
||||
} from '../../../shared';
|
||||
import type { NextPageWithLayout } from '../../../shared';
|
||||
import { apis } from '../../../shared/apis';
|
||||
|
||||
const settingPanelAtom = atomWithStorage<SettingPanel>(
|
||||
@@ -105,13 +102,12 @@ const SettingPage: NextPageWithLayout = () => {
|
||||
}, [currentWorkspace, helper]);
|
||||
const transformWorkspace = useTransformWorkspace();
|
||||
const onTransformWorkspace = useCallback(
|
||||
async <From extends RemWorkspaceFlavour, To extends RemWorkspaceFlavour>(
|
||||
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||
from: From,
|
||||
to: To,
|
||||
workspace: FlavourToWorkspace[From]
|
||||
workspace: WorkspaceRegistry[From]
|
||||
): Promise<void> => {
|
||||
const needRefresh =
|
||||
to === RemWorkspaceFlavour.AFFINE && !apis.auth.isLogin;
|
||||
const needRefresh = to === WorkspaceFlavour.AFFINE && !apis.auth.isLogin;
|
||||
if (needRefresh) {
|
||||
await apis.signInWithGoogle();
|
||||
}
|
||||
@@ -135,7 +131,7 @@ const SettingPage: NextPageWithLayout = () => {
|
||||
return <PageLoading />;
|
||||
} else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
|
||||
return <PageLoading />;
|
||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||
const Setting =
|
||||
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
||||
return (
|
||||
@@ -155,7 +151,7 @@ const SettingPage: NextPageWithLayout = () => {
|
||||
/>
|
||||
</>
|
||||
);
|
||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
||||
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
const Setting =
|
||||
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
||||
return (
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
|
||||
import { jotaiStore, workspacesAtom } from '../../atoms';
|
||||
import { createAffineProviders } from '../../blocksuite';
|
||||
import { Unreachable } from '../../components/affine/affine-error-eoundary';
|
||||
import type { AffineWorkspace } from '../../shared';
|
||||
import { RemWorkspaceFlavour } from '../../shared';
|
||||
import { apis } from '../../shared/apis';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
|
||||
type Query = (typeof QueryKey)[keyof typeof QueryKey];
|
||||
|
||||
@@ -73,7 +73,7 @@ export const fetcher = async (
|
||||
);
|
||||
const remWorkspace: AffineWorkspace = {
|
||||
...workspace,
|
||||
flavour: RemWorkspaceFlavour.AFFINE,
|
||||
flavour: WorkspaceFlavour.AFFINE,
|
||||
blockSuiteWorkspace,
|
||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { createJSONStorage } from 'jotai/utils';
|
||||
import React from 'react';
|
||||
import { mutate } from 'swr';
|
||||
@@ -9,13 +11,8 @@ import { WorkspaceSettingDetail } from '../../components/affine/workspace-settin
|
||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||
import { PageDetailEditor } from '../../components/page-detail-editor';
|
||||
import type { AffineWorkspace } from '../../shared';
|
||||
import {
|
||||
BlockSuiteWorkspace,
|
||||
LoadPriority,
|
||||
RemWorkspaceFlavour,
|
||||
} from '../../shared';
|
||||
import { BlockSuiteWorkspace } from '../../shared';
|
||||
import { apis, clientAuth } from '../../shared/apis';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
import { initPage } from '../../utils/blocksuite';
|
||||
import type { WorkspacePlugin } from '..';
|
||||
import { QueryKey } from './fetcher';
|
||||
@@ -46,7 +43,7 @@ const getPersistenceAllWorkspace = () => {
|
||||
);
|
||||
const affineWorkspace: AffineWorkspace = {
|
||||
...item,
|
||||
flavour: RemWorkspaceFlavour.AFFINE,
|
||||
flavour: WorkspaceFlavour.AFFINE,
|
||||
blockSuiteWorkspace,
|
||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||
};
|
||||
@@ -57,8 +54,8 @@ const getPersistenceAllWorkspace = () => {
|
||||
return allWorkspaces;
|
||||
};
|
||||
|
||||
export const AffinePlugin: WorkspacePlugin<RemWorkspaceFlavour.AFFINE> = {
|
||||
flavour: RemWorkspaceFlavour.AFFINE,
|
||||
export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
|
||||
flavour: WorkspaceFlavour.AFFINE,
|
||||
loadPriority: LoadPriority.HIGH,
|
||||
cleanup: () => {
|
||||
storage.removeItem(kAffineLocal);
|
||||
@@ -167,7 +164,7 @@ export const AffinePlugin: WorkspacePlugin<RemWorkspaceFlavour.AFFINE> = {
|
||||
|
||||
const affineWorkspace: AffineWorkspace = {
|
||||
...workspace,
|
||||
flavour: RemWorkspaceFlavour.AFFINE,
|
||||
flavour: WorkspaceFlavour.AFFINE,
|
||||
blockSuiteWorkspace,
|
||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||
};
|
||||
|
||||
@@ -1,74 +1,35 @@
|
||||
import type React from 'react';
|
||||
|
||||
import type {
|
||||
BlockSuiteWorkspace,
|
||||
FlavourToWorkspace,
|
||||
LoadPriority,
|
||||
SettingPanel,
|
||||
} from '../shared';
|
||||
import { RemWorkspaceFlavour } from '../shared';
|
||||
WorkspaceCRUD,
|
||||
WorkspaceUISchema,
|
||||
} from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
|
||||
import type { AffineWorkspace, LocalWorkspace } from '../shared';
|
||||
import { AffinePlugin } from './affine';
|
||||
import { LocalPlugin } from './local';
|
||||
|
||||
type UIBaseProps<Flavour extends RemWorkspaceFlavour> = {
|
||||
currentWorkspace: FlavourToWorkspace[Flavour];
|
||||
};
|
||||
declare module '@affine/workspace/type' {
|
||||
interface WorkspaceRegistry {
|
||||
[WorkspaceFlavour.AFFINE]: AffineWorkspace;
|
||||
[WorkspaceFlavour.LOCAL]: LocalWorkspace;
|
||||
}
|
||||
}
|
||||
|
||||
type SettingProps<Flavour extends RemWorkspaceFlavour> =
|
||||
UIBaseProps<Flavour> & {
|
||||
currentTab: SettingPanel;
|
||||
onChangeTab: (tab: SettingPanel) => void;
|
||||
onDeleteWorkspace: () => void;
|
||||
onTransformWorkspace: <
|
||||
From extends RemWorkspaceFlavour,
|
||||
To extends RemWorkspaceFlavour
|
||||
>(
|
||||
from: From,
|
||||
to: To,
|
||||
workspace: FlavourToWorkspace[From]
|
||||
) => void;
|
||||
};
|
||||
|
||||
type PageDetailProps<Flavour extends RemWorkspaceFlavour> =
|
||||
UIBaseProps<Flavour> & {
|
||||
currentPageId: string;
|
||||
};
|
||||
|
||||
type PageListProps<Flavour extends RemWorkspaceFlavour> = {
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
onOpenPage: (pageId: string, newTab?: boolean) => void;
|
||||
};
|
||||
|
||||
type SideBarMenuProps<Flavour extends RemWorkspaceFlavour> =
|
||||
UIBaseProps<Flavour> & {
|
||||
setSideBarOpen: (open: boolean) => void;
|
||||
};
|
||||
|
||||
export interface WorkspacePlugin<Flavour extends RemWorkspaceFlavour> {
|
||||
export interface WorkspacePlugin<Flavour extends WorkspaceFlavour> {
|
||||
flavour: Flavour;
|
||||
// Plugin will be loaded according to the priority
|
||||
loadPriority: LoadPriority;
|
||||
// fixme: this is a hack
|
||||
cleanup?: () => void;
|
||||
// Fetch necessary data for the first render
|
||||
CRUD: {
|
||||
create: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise<string>;
|
||||
delete: (workspace: FlavourToWorkspace[Flavour]) => Promise<void>;
|
||||
get: (workspaceId: string) => Promise<FlavourToWorkspace[Flavour] | null>;
|
||||
// not supported yet
|
||||
// update: (workspace: FlavourToWorkspace[Flavour]) => Promise<void>;
|
||||
list: () => Promise<FlavourToWorkspace[Flavour][]>;
|
||||
};
|
||||
UI: {
|
||||
PageDetail: React.FC<PageDetailProps<Flavour>>;
|
||||
PageList: React.FC<PageListProps<Flavour>>;
|
||||
SettingsDetail: React.FC<SettingProps<Flavour>>;
|
||||
};
|
||||
CRUD: WorkspaceCRUD<Flavour>;
|
||||
UI: WorkspaceUISchema<Flavour>;
|
||||
}
|
||||
|
||||
export const WorkspacePlugins = {
|
||||
[RemWorkspaceFlavour.AFFINE]: AffinePlugin,
|
||||
[RemWorkspaceFlavour.LOCAL]: LocalPlugin,
|
||||
[WorkspaceFlavour.AFFINE]: AffinePlugin,
|
||||
[WorkspaceFlavour.LOCAL]: LocalPlugin,
|
||||
} satisfies {
|
||||
[Key in RemWorkspaceFlavour]: WorkspacePlugin<Key>;
|
||||
[Key in WorkspaceFlavour]: WorkspacePlugin<Key>;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
||||
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { createJSONStorage } from 'jotai/utils';
|
||||
import React from 'react';
|
||||
@@ -11,12 +13,7 @@ import { WorkspaceSettingDetail } from '../../components/affine/workspace-settin
|
||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||
import { PageDetailEditor } from '../../components/page-detail-editor';
|
||||
import type { LocalWorkspace } from '../../shared';
|
||||
import {
|
||||
BlockSuiteWorkspace,
|
||||
LoadPriority,
|
||||
RemWorkspaceFlavour,
|
||||
} from '../../shared';
|
||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
||||
import { BlockSuiteWorkspace } from '../../shared';
|
||||
import { initPage } from '../../utils/blocksuite';
|
||||
import type { WorkspacePlugin } from '..';
|
||||
|
||||
@@ -25,8 +22,8 @@ const getStorage = () => createJSONStorage(() => localStorage);
|
||||
export const kStoreKey = 'affine-local-workspace';
|
||||
const schema = z.array(z.string());
|
||||
|
||||
export const LocalPlugin: WorkspacePlugin<RemWorkspaceFlavour.LOCAL> = {
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
export const LocalPlugin: WorkspacePlugin<WorkspaceFlavour.LOCAL> = {
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
loadPriority: LoadPriority.LOW,
|
||||
CRUD: {
|
||||
get: async workspaceId => {
|
||||
@@ -44,7 +41,7 @@ export const LocalPlugin: WorkspacePlugin<RemWorkspaceFlavour.LOCAL> = {
|
||||
);
|
||||
const workspace: LocalWorkspace = {
|
||||
id,
|
||||
flavour: RemWorkspaceFlavour.LOCAL,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace: blockSuiteWorkspace,
|
||||
providers: [...createLocalProviders(blockSuiteWorkspace)],
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ let prefixUrl = '/';
|
||||
if (typeof window === 'undefined') {
|
||||
// SSR
|
||||
const serverAPI = config.serverAPI;
|
||||
if (isValidIPAddress(serverAPI)) {
|
||||
if (isValidIPAddress(serverAPI.split(':')[0])) {
|
||||
// This is for Server side rendering support
|
||||
prefixUrl = new URL('http://' + config.serverAPI + '/').origin;
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Workspace as RemoteWorkspace } from '@affine/datacenter';
|
||||
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||
import type { NextPage } from 'next';
|
||||
import type { ReactElement, ReactNode } from 'react';
|
||||
@@ -11,25 +12,15 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export const enum RemWorkspaceFlavour {
|
||||
AFFINE = 'affine',
|
||||
LOCAL = 'local',
|
||||
}
|
||||
|
||||
export interface FlavourToWorkspace {
|
||||
[RemWorkspaceFlavour.AFFINE]: AffineWorkspace;
|
||||
[RemWorkspaceFlavour.LOCAL]: LocalWorkspace;
|
||||
}
|
||||
|
||||
export interface AffineWorkspace extends RemoteWorkspace {
|
||||
flavour: RemWorkspaceFlavour.AFFINE;
|
||||
flavour: WorkspaceFlavour.AFFINE;
|
||||
// empty
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
providers: Provider[];
|
||||
}
|
||||
|
||||
export interface LocalWorkspace {
|
||||
flavour: RemWorkspaceFlavour.LOCAL;
|
||||
flavour: WorkspaceFlavour.LOCAL;
|
||||
id: string;
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
providers: Provider[];
|
||||
@@ -89,16 +80,6 @@ export const enum WorkspaceSubPath {
|
||||
TRASH = 'trash',
|
||||
}
|
||||
|
||||
export const settingPanel = {
|
||||
General: 'general',
|
||||
Collaboration: 'collaboration',
|
||||
Publish: 'publish',
|
||||
Export: 'export',
|
||||
Sync: 'sync',
|
||||
} as const;
|
||||
export const settingPanelValues = [...Object.values(settingPanel)] as const;
|
||||
export type SettingPanel = (typeof settingPanel)[keyof typeof settingPanel];
|
||||
|
||||
export const WorkspaceSubPathName = {
|
||||
[WorkspaceSubPath.ALL]: 'All Pages',
|
||||
[WorkspaceSubPath.FAVORITE]: 'Favorites',
|
||||
@@ -125,9 +106,3 @@ export const publicPathGenerator = {
|
||||
} satisfies {
|
||||
[Path in WorkspaceSubPath]: (workspaceId: string) => string;
|
||||
};
|
||||
|
||||
export const enum LoadPriority {
|
||||
HIGH = 1,
|
||||
MEDIUM = 2,
|
||||
LOW = 3,
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||
import type { BlobOptionsGetter, Generator } from '@blocksuite/store';
|
||||
|
||||
import { BlockSuiteWorkspace } from '../shared';
|
||||
|
||||
export function stringToColour(str: string) {
|
||||
str = str || 'affine';
|
||||
let colour = '#';
|
||||
@@ -23,24 +18,3 @@ export function stringToColour(str: string) {
|
||||
|
||||
return colour;
|
||||
}
|
||||
|
||||
const hashMap = new Map<string, BlockSuiteWorkspace>();
|
||||
export const createEmptyBlockSuiteWorkspace = (
|
||||
id: string,
|
||||
blobOptionsGetter?: BlobOptionsGetter,
|
||||
idGenerator?: Generator
|
||||
): BlockSuiteWorkspace => {
|
||||
if (hashMap.has(id)) {
|
||||
return hashMap.get(id) as BlockSuiteWorkspace;
|
||||
}
|
||||
const workspace = new BlockSuiteWorkspace({
|
||||
id,
|
||||
isSSR: typeof window === 'undefined',
|
||||
blobOptionsGetter,
|
||||
idGenerator,
|
||||
})
|
||||
.register(AffineSchemas)
|
||||
.register(__unstableSchemas);
|
||||
hashMap.set(id, workspace);
|
||||
return workspace;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user