feat: add affine global channel (#1762)

This commit is contained in:
Himself65
2023-03-30 18:21:26 -05:00
committed by GitHub
parent 3fa7d17dca
commit bb1224f9ee
38 changed files with 358 additions and 162 deletions

View File

@@ -1,13 +1,13 @@
import type { WorkspaceFlavour } from '@affine/workspace/type';
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, createStore } from 'jotai';
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { unstable_batchedUpdates } from 'react-dom';
import { WorkspacePlugins } from '../plugins';
import type { RemWorkspace } from '../shared';
import type { AllWorkspace } from '../shared';
// workspace necessary atoms
export const currentWorkspaceIdAtom = atom<string | null>(null);
export const currentPageIdAtom = atom<string | null>(null);
@@ -34,19 +34,7 @@ export const openWorkspacesModalAtom = atom(false);
export const openCreateWorkspaceModalAtom = atom(false);
export const openQuickSearchModalAtom = atom(false);
export const jotaiStore = createStore();
type JotaiWorkspace = {
id: string;
flavour: WorkspaceFlavour;
};
export const jotaiWorkspacesAtom = atomWithStorage<JotaiWorkspace[]>(
'jotai-workspaces',
[]
);
export const workspacesAtom = atom<Promise<RemWorkspace[]>>(async get => {
export const workspacesAtom = atom<Promise<AllWorkspace[]>>(async get => {
const flavours: string[] = Object.values(WorkspacePlugins).map(
plugin => plugin.flavour
);
@@ -62,7 +50,7 @@ export const workspacesAtom = atom<Promise<RemWorkspace[]>>(async get => {
return CRUD.get(workspace.id);
})
);
return workspaces.filter(workspace => workspace !== null) as RemWorkspace[];
return workspaces.filter(workspace => workspace !== null) as AllWorkspace[];
});
type View = { id: string; mode: 'page' | 'edgeless' };

View File

@@ -1,6 +1,7 @@
import { config } from '@affine/env';
import type { Provider } from '@affine/workspace/type';
import type { BlockSuiteWorkspace, Provider } from '../shared';
import type { BlockSuiteWorkspace } from '../shared';
import {
createAffineWebSocketProvider,
createBroadCastChannelProvider,

View File

@@ -1,6 +1,6 @@
import type { AffineDownloadProvider } from '@affine/workspace/type';
import { assertExists } from '@blocksuite/store';
import type { AffineDownloadProvider } from '../../../shared';
import { BlockSuiteWorkspace } from '../../../shared';
import { affineApis } from '../../../shared/apis';
import { providerLogger } from '../../logger';

View File

@@ -1,3 +1,4 @@
import type { BroadCastChannelProvider } from '@affine/workspace/type';
import { assertExists } from '@blocksuite/store';
import type { Awareness } from 'y-protocols/awareness';
import {
@@ -5,7 +6,6 @@ import {
encodeAwarenessUpdate,
} from 'y-protocols/awareness';
import type { BroadCastChannelProvider } from '../../../shared';
import { BlockSuiteWorkspace } from '../../../shared';
import { providerLogger } from '../../logger';
import type {

View File

@@ -1,13 +1,13 @@
import { KeckProvider } from '@affine/workspace/affine/keck';
import { getLoginStorage } from '@affine/workspace/affine/login';
import type {
AffineWebSocketProvider,
LocalIndexedDBProvider,
} from '@affine/workspace/type';
import { assertExists } from '@blocksuite/store';
import { IndexeddbPersistence } from 'y-indexeddb';
import type {
AffineWebSocketProvider,
BlockSuiteWorkspace,
LocalIndexedDBProvider,
} from '../../shared';
import type { BlockSuiteWorkspace } from '../../shared';
import { providerLogger } from '../logger';
import { createBroadCastChannelProvider } from './broad-cast-channel';

View File

@@ -1,6 +1,7 @@
import { Button, IconButton, Menu, MenuItem, Wrapper } from '@affine/component';
import { useTranslation } from '@affine/i18n';
import { PermissionType } from '@affine/workspace/affine/api';
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import {
DeleteTemporarilyIcon,
@@ -11,7 +12,6 @@ import type React from 'react';
import { useCallback, useState } from 'react';
import { useMembers } from '../../../../../hooks/affine/use-members';
import type { AffineWorkspace, LocalWorkspace } from '../../../../../shared';
import { toast } from '../../../../../utils';
import { Unreachable } from '../../../affine-error-eoundary';
import { TransformWorkspaceToAffineModal } from '../../../transform-workspace-to-affine-modal';

View File

@@ -6,17 +6,14 @@ import {
Wrapper,
} from '@affine/component';
import { useTranslation } from '@affine/i18n';
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { Box } from '@mui/material';
import type React from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useToggleWorkspacePublish } from '../../../../../hooks/affine/use-toggle-workspace-publish';
import type {
AffineOfficialWorkspace,
AffineWorkspace,
LocalWorkspace,
} from '../../../../../shared';
import type { AffineOfficialWorkspace } from '../../../../../shared';
import { toast } from '../../../../../utils';
import { Unreachable } from '../../../affine-error-eoundary';
import { EnableAffineCloudModal } from '../../../enable-affine-cloud-modal';

View File

@@ -5,6 +5,7 @@ import {
setLoginStorage,
SignMethod,
} from '@affine/workspace/affine/login';
import type { LocalWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import {
CloudWorkspaceIcon,
@@ -18,10 +19,7 @@ import React, { useEffect, useState } from 'react';
import { affineAuth } from '../../../../hooks/affine/use-affine-log-in';
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
import { useTransformWorkspace } from '../../../../hooks/use-transform-workspace';
import type {
AffineOfficialWorkspace,
LocalWorkspace,
} from '../../../../shared';
import type { AffineOfficialWorkspace } from '../../../../shared';
import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal';
const IconWrapper = styled('div')(({ theme }) => {

View File

@@ -3,7 +3,7 @@ import type React from 'react';
import { memo } from 'react';
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../hooks/use-blocksuite-workspace-avatar-url';
import type { BlockSuiteWorkspace, RemWorkspace } from '../../../shared';
import type { AllWorkspace, BlockSuiteWorkspace } from '../../../shared';
import { stringToColour } from '../../../utils';
interface AvatarProps {
@@ -75,7 +75,7 @@ export const Avatar: React.FC<AvatarProps> = memo<AvatarProps>(function Avatar({
export type WorkspaceUnitAvatarProps = {
size?: number;
workspace: RemWorkspace | null;
workspace: AllWorkspace | null;
style?: React.CSSProperties;
};

View File

@@ -6,7 +6,7 @@ import type React from 'react';
import { useCallback } from 'react';
import { useBlockSuiteWorkspaceName } from '../../../hooks/use-blocksuite-workspace-name';
import type { RemWorkspace } from '../../../shared';
import type { AllWorkspace } from '../../../shared';
import {
CloudWorkspaceIcon,
JoinedWorkspaceIcon,
@@ -22,7 +22,7 @@ import {
StyleWorkspaceTitle,
} from './styles';
export type WorkspaceTypeProps = {
workspace: RemWorkspace;
workspace: AllWorkspace;
};
const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
@@ -58,9 +58,9 @@ const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
export type WorkspaceCardProps = {
currentWorkspaceId: string | null;
workspace: RemWorkspace;
onClick: (workspace: RemWorkspace) => void;
onSettingClick: (workspace: RemWorkspace) => void;
workspace: AllWorkspace;
onClick: (workspace: AllWorkspace) => void;
onSettingClick: (workspace: AllWorkspace) => void;
};
export const WorkspaceCard: React.FC<WorkspaceCardProps> = ({

View File

@@ -8,7 +8,7 @@ import { useTranslation } from '@affine/i18n';
import type { AccessTokenMessage } from '@affine/workspace/affine/login';
import { HelpIcon, PlusIcon } from '@blocksuite/icons';
import type { RemWorkspace } from '../../../shared';
import type { AllWorkspace } from '../../../shared';
import { Footer } from '../footer';
import { WorkspaceCard } from '../workspace-card';
import { LanguageMenu } from './language-menu';
@@ -28,12 +28,12 @@ import {
interface WorkspaceModalProps {
user: AccessTokenMessage | null;
workspaces: RemWorkspace[];
currentWorkspaceId: RemWorkspace['id'] | null;
workspaces: AllWorkspace[];
currentWorkspaceId: AllWorkspace['id'] | null;
open: boolean;
onClose: () => void;
onClickWorkspace: (workspace: RemWorkspace) => void;
onClickWorkspaceSetting: (workspace: RemWorkspace) => void;
onClickWorkspace: (workspace: AllWorkspace) => void;
onClickWorkspaceSetting: (workspace: AllWorkspace) => void;
onClickLogin: () => void;
onClickLogout: () => void;
onCreateWorkspace: () => void;

View File

@@ -5,7 +5,7 @@ import type { PageMeta } from '@blocksuite/store';
import type { MouseEvent } from 'react';
import { useCallback, useMemo, useState } from 'react';
import type { RemWorkspace } from '../../../shared';
import type { AllWorkspace } from '../../../shared';
import type { TreeNode } from '../../affine/pivots';
import {
PivotRender,
@@ -20,7 +20,7 @@ export const PivotInternal = ({
openPage,
allMetas,
}: {
currentWorkspace: RemWorkspace;
currentWorkspace: AllWorkspace;
openPage: (pageId: string) => void;
allMetas: PageMeta[];
}) => {
@@ -68,7 +68,7 @@ export const Pivots = ({
openPage,
allMetas,
}: {
currentWorkspace: RemWorkspace;
currentWorkspace: AllWorkspace;
openPage: (pageId: string) => void;
allMetas: PageMeta[];
}) => {

View File

@@ -3,7 +3,7 @@ import type React from 'react';
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
import { useBlockSuiteWorkspaceName } from '../../../../hooks/use-blocksuite-workspace-name';
import type { RemWorkspace } from '../../../../shared';
import type { AllWorkspace } from '../../../../shared';
import { WorkspaceAvatar } from '../../workspace-avatar';
import {
StyledSelectorContainer,
@@ -13,7 +13,7 @@ import {
} from './styles';
export type WorkspaceSelectorProps = {
currentWorkspace: RemWorkspace | null;
currentWorkspace: AllWorkspace | null;
onClick: () => void;
};

View File

@@ -13,7 +13,7 @@ import { useCallback } from 'react';
import { useSidebarStatus } from '../../../hooks/affine/use-sidebar-status';
import { usePageMeta } from '../../../hooks/use-page-meta';
import type { RemWorkspace } from '../../../shared';
import type { AllWorkspace } from '../../../shared';
import { SidebarSwitch } from '../../affine/sidebar-switch';
import { ChangeLog } from './changeLog';
import Favorite from './favorite';
@@ -39,7 +39,7 @@ export type WorkSpaceSliderBarProps = {
isPublicWorkspace: boolean;
onOpenQuickSearchModal: () => void;
onOpenWorkspaceListModal: () => void;
currentWorkspace: RemWorkspace | null;
currentWorkspace: AllWorkspace | null;
currentPageId: string | null;
openPage: (pageId: string) => void;
createPage: () => Page;

View File

@@ -5,6 +5,8 @@ import 'fake-indexeddb/auto';
import assert from 'node:assert';
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
import type { LocalWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import type { Page } from '@blocksuite/store';
@@ -17,13 +19,8 @@ import { createDynamicRouteParser } from 'next-router-mock/dynamic-routes';
import type React from 'react';
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
import {
currentWorkspaceIdAtom,
jotaiWorkspacesAtom,
workspacesAtom,
} from '../../atoms';
import { currentWorkspaceIdAtom, workspacesAtom } from '../../atoms';
import { LocalPlugin } from '../../plugins/local';
import type { LocalWorkspace } from '../../shared';
import { BlockSuiteWorkspace, WorkspaceSubPath } from '../../shared';
import {
useGuideHidden,

View File

@@ -1,11 +1,11 @@
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
import { clearLoginStorage } from '@affine/workspace/affine/login';
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { useSetAtom } from 'jotai';
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import { jotaiWorkspacesAtom } from '../../atoms';
import { WorkspacePlugins } from '../../plugins';
export function useAffineLogOut() {

View File

@@ -1,9 +1,9 @@
import { jotaiStore, jotaiWorkspacesAtom } from '@affine/workspace/atom';
import type { AffineWorkspace } from '@affine/workspace/type';
import { useCallback } from 'react';
import useSWR from 'swr';
import { jotaiStore, jotaiWorkspacesAtom } from '../../atoms';
import { QueryKey } from '../../plugins/affine/fetcher';
import type { AffineWorkspace } from '../../shared';
import { affineApis } from '../../shared/apis';
export function useToggleWorkspacePublish(workspace: AffineWorkspace) {

View File

@@ -7,9 +7,9 @@ import {
currentWorkspaceIdAtom,
workspacesAtom,
} from '../../atoms';
import type { RemWorkspace } from '../../shared';
import type { AllWorkspace } from '../../shared';
export const currentWorkspaceAtom = atom<Promise<RemWorkspace | null>>(
export const currentWorkspaceAtom = atom<Promise<AllWorkspace | null>>(
async get => {
const id = get(currentWorkspaceIdAtom);
const workspaces = await get(workspacesAtom);
@@ -23,7 +23,7 @@ export const lastWorkspaceIdAtom = atomWithStorage<string | null>(
);
export function useCurrentWorkspace(): [
RemWorkspace | null,
AllWorkspace | null,
(id: string | null) => void
] {
const currentWorkspace = useAtomValue(currentWorkspaceAtom);

View File

@@ -1,11 +1,11 @@
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
import { useAtom } from 'jotai';
import { useEffect } from 'react';
import { jotaiWorkspacesAtom } from '../atoms';
import { LocalPlugin } from '../plugins/local';
export function useCreateFirstWorkspace() {

View File

@@ -1,9 +1,10 @@
import { jotaiStore } from '@affine/workspace/atom';
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 { currentPageIdAtom } from '../atoms';
import type { AllWorkspace } from '../shared';
import { WorkspaceSubPath } from '../shared';
import { useCurrentPageId } from './current/use-current-page-id';
import { useCurrentWorkspace } from './current/use-current-workspace';
@@ -11,7 +12,7 @@ import { RouteLogic, useRouterHelper } from './use-router-helper';
import { useWorkspaces } from './use-workspaces';
export function findSuitablePageId(
workspace: RemWorkspace,
workspace: AllWorkspace,
targetId: string
): string | null {
switch (workspace.flavour) {

View File

@@ -1,9 +1,9 @@
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
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';
/**

View File

@@ -1,15 +1,17 @@
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
import type { LocalWorkspace } from '@affine/workspace/type';
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';
import { jotaiWorkspacesAtom, workspacesAtom } from '../atoms';
import { workspacesAtom } from '../atoms';
import { WorkspacePlugins } from '../plugins';
import { LocalPlugin } from '../plugins/local';
import type { LocalWorkspace, RemWorkspace } from '../shared';
import type { AllWorkspace } from '../shared';
export function useWorkspaces(): RemWorkspace[] {
export function useWorkspaces(): AllWorkspace[] {
return useAtomValue(workspacesAtom);
}

View File

@@ -1,5 +1,8 @@
import { DebugLogger } from '@affine/debug';
import { setUpLanguage, useTranslation } from '@affine/i18n';
import { createAffineGlobalChannel } from '@affine/workspace/affine/sync';
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { assertExists, nanoid } from '@blocksuite/store';
import { NoSsr } from '@mui/material';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
@@ -11,7 +14,6 @@ import { Suspense, useCallback, useEffect } from 'react';
import {
currentWorkspaceIdAtom,
jotaiWorkspacesAtom,
openQuickSearchModalAtom,
openWorkspacesModalAtom,
workspaceLockAtom,
@@ -33,13 +35,13 @@ import { useRouterTitle } from '../hooks/use-router-title';
import { useWorkspaces } from '../hooks/use-workspaces';
import { WorkspacePlugins } from '../plugins';
import { ModalProvider } from '../providers/ModalProvider';
import type { RemWorkspace } from '../shared';
import type { AllWorkspace } from '../shared';
import { pathGenerator, publicPathGenerator } from '../shared';
import { StyledPage, StyledToolWrapper, StyledWrapper } from './styles';
declare global {
// eslint-disable-next-line no-var
var currentWorkspace: RemWorkspace;
var currentWorkspace: AllWorkspace;
}
const QuickSearchModal = dynamic(
@@ -89,6 +91,10 @@ export const QuickSearch: React.FC = () => {
};
const logger = new DebugLogger('workspace-layout');
const affineGlobalChannel = createAffineGlobalChannel(
WorkspacePlugins[WorkspaceFlavour.AFFINE].CRUD
);
export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
function WorkspacesSuspense({ children }) {
const { i18n } = useTranslation();
@@ -105,6 +111,7 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
const lists = Object.values(WorkspacePlugins)
.sort((a, b) => a.loadPriority - b.loadPriority)
.map(({ CRUD }) => CRUD.list);
async function fetch() {
const items = [];
for (const list of lists) {
@@ -121,6 +128,7 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
set([...items]);
logger.info('mount first data:', items);
}
fetch();
return () => {
controller.abort();
@@ -128,6 +136,19 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
};
}, [set]);
const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom);
const jotaiWorkspaces = useAtomValue(jotaiWorkspacesAtom);
useEffect(() => {
const flavour = jotaiWorkspaces.find(
x => x.id === currentWorkspaceId
)?.flavour;
if (flavour === WorkspaceFlavour.AFFINE) {
affineGlobalChannel.connect();
return () => {
affineGlobalChannel.disconnect();
};
}
}, [currentWorkspaceId, jotaiWorkspaces]);
return (
<NoSsr>
{/* fixme(himself65): don't re-render whole modals */}

View File

@@ -2,6 +2,7 @@ import '../styles/globals.css';
import { config, setupGlobal } from '@affine/env';
import { createI18n, I18nextProvider } from '@affine/i18n';
import { jotaiStore } from '@affine/workspace/atom';
import type { EmotionCache } from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { Provider } from 'jotai';
@@ -11,7 +12,6 @@ import { useRouter } from 'next/router';
import type { ReactElement } from 'react';
import React, { Suspense, useEffect, useMemo } from 'react';
import { jotaiStore } from '../atoms';
import { AffineErrorBoundary } from '../components/affine/affine-error-eoundary';
import { ProviderComposer } from '../components/provider-composer';
import { PageLoading } from '../components/pure/loading';

View File

@@ -1,5 +1,6 @@
import { Button } from '@affine/component';
import { DebugLogger } from '@affine/debug';
import type { BroadCastChannelProvider } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { nanoid } from '@blocksuite/store';
import { Typography } from '@mui/material';
@@ -9,7 +10,6 @@ import { useEffect, useMemo, useState } from 'react';
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 { toast } from '../../utils';
const logger = new DebugLogger('broadcast');

View File

@@ -1,4 +1,5 @@
import { useTranslation } from '@affine/i18n';
import type { LocalIndexedDBProvider } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { FolderIcon } from '@blocksuite/icons';
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
@@ -17,10 +18,7 @@ import { useRouterHelper } from '../../../hooks/use-router-helper';
import { useSyncRouterWithCurrentWorkspace } from '../../../hooks/use-sync-router-with-current-workspace';
import { WorkspaceLayout } from '../../../layouts';
import { WorkspacePlugins } from '../../../plugins';
import type {
LocalIndexedDBProvider,
NextPageWithLayout,
} from '../../../shared';
import type { NextPageWithLayout } from '../../../shared';
const AllPage: NextPageWithLayout = () => {
const router = useRouter();

View File

@@ -1,12 +1,13 @@
import { getLoginStorage } from '@affine/workspace/affine/login';
import { jotaiStore } from '@affine/workspace/atom';
import type { AffineWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { assertExists } from '@blocksuite/store';
import { jotaiStore, workspacesAtom } from '../../atoms';
import { workspacesAtom } from '../../atoms';
import { createAffineProviders } from '../../blocksuite';
import { Unreachable } from '../../components/affine/affine-error-eoundary';
import type { AffineWorkspace } from '../../shared';
import { affineApis } from '../../shared/apis';
type Query = (typeof QueryKey)[keyof typeof QueryKey];

View File

@@ -1,4 +1,5 @@
import { getLoginStorage } from '@affine/workspace/affine/login';
import type { AffineWorkspace } from '@affine/workspace/type';
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { createJSONStorage } from 'jotai/utils';
@@ -11,7 +12,6 @@ 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 type { AffineWorkspace } from '../../shared';
import { BlockSuiteWorkspace } from '../../shared';
import { affineApis } from '../../shared/apis';
import { initPage } from '../../utils';

View File

@@ -5,17 +5,9 @@ import type {
} from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import type { AffineWorkspace, LocalWorkspace } from '../shared';
import { AffinePlugin } from './affine';
import { LocalPlugin } from './local';
declare module '@affine/workspace/type' {
interface WorkspaceRegistry {
[WorkspaceFlavour.AFFINE]: AffineWorkspace;
[WorkspaceFlavour.LOCAL]: LocalWorkspace;
}
}
export interface WorkspacePlugin<Flavour extends WorkspaceFlavour> {
flavour: Flavour;
// Plugin will be loaded according to the priority

View File

@@ -1,4 +1,5 @@
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
import type { LocalWorkspace } from '@affine/workspace/type';
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { nanoid } from '@blocksuite/store';
@@ -12,9 +13,8 @@ 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 type { LocalWorkspace } from '../../shared';
import { BlockSuiteWorkspace } from '../../shared';
import { initPage } from '../../utils/blocksuite';
import { initPage } from '../../utils';
import type { WorkspacePlugin } from '..';
const getStorage = () => createJSONStorage(() => localStorage);

View File

@@ -6,8 +6,8 @@ import {
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
import type { LoginResponse } from '@affine/workspace/affine/login';
import { parseIdToken, setLoginStorage } from '@affine/workspace/affine/login';
import { jotaiStore } from '@affine/workspace/atom';
import { jotaiStore } from '../atoms';
import { isValidIPAddress } from '../utils';
let prefixUrl = '/';

View File

@@ -1,5 +1,4 @@
import type { Workspace as RemoteWorkspace } from '@affine/workspace/affine/api';
import type { WorkspaceFlavour } from '@affine/workspace/type';
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
import type { NextPage } from 'next';
import type { ReactElement, ReactNode } from 'react';
@@ -12,59 +11,9 @@ declare global {
}
}
export interface AffineWorkspace extends RemoteWorkspace {
flavour: WorkspaceFlavour.AFFINE;
// empty
blockSuiteWorkspace: BlockSuiteWorkspace;
providers: Provider[];
}
export interface LocalWorkspace {
flavour: WorkspaceFlavour.LOCAL;
id: string;
blockSuiteWorkspace: BlockSuiteWorkspace;
providers: Provider[];
}
export type BaseProvider = {
flavour: string;
// if this is true, we will connect the provider on the background
background: boolean;
connect: () => void;
disconnect: () => void;
// cleanup data when workspace is removed
cleanup: () => void;
};
export interface BackgroundProvider extends BaseProvider {
background: true;
callbacks: Set<() => void>;
}
export interface AffineDownloadProvider extends BaseProvider {
flavour: 'affine-download';
}
export interface BroadCastChannelProvider extends BaseProvider {
flavour: 'broadcast-channel';
}
export interface LocalIndexedDBProvider extends BackgroundProvider {
flavour: 'local-indexeddb';
}
export interface AffineWebSocketProvider extends BaseProvider {
flavour: 'affine-websocket';
}
export type Provider =
| LocalIndexedDBProvider
| AffineWebSocketProvider
| BroadCastChannelProvider;
export type AffineOfficialWorkspace = AffineWorkspace | LocalWorkspace;
export type RemWorkspace = AffineOfficialWorkspace;
export type AllWorkspace = AffineOfficialWorkspace;
export type NextPageWithLayout<P = Record<string, unknown>, IP = P> = NextPage<
P,