mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
fix: first workspace create logic (#1773)
This commit is contained in:
@@ -1,28 +1,19 @@
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import { atomWithSyncStorage } from '@affine/jotai';
|
||||
|
||||
export type Visibility = Record<string, boolean>;
|
||||
|
||||
const DEFAULT_VALUE = '0.0.0';
|
||||
//atomWithStorage always uses initial value when first render
|
||||
//https://github.com/pmndrs/jotai/discussions/1737
|
||||
|
||||
function getInitialValue() {
|
||||
if (typeof window !== 'undefined') {
|
||||
const storedValue = window.localStorage.getItem('lastVersion');
|
||||
if (storedValue) {
|
||||
return JSON.parse(storedValue);
|
||||
}
|
||||
}
|
||||
return DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
export const lastVersionAtom = atomWithStorage(
|
||||
export const lastVersionAtom = atomWithSyncStorage(
|
||||
'lastVersion',
|
||||
getInitialValue()
|
||||
DEFAULT_VALUE
|
||||
);
|
||||
export const guideHiddenAtom = atomWithSyncStorage<Visibility>(
|
||||
'guideHidden',
|
||||
{}
|
||||
);
|
||||
export const guideHiddenAtom = atomWithStorage<Visibility>('guideHidden', {});
|
||||
|
||||
export const guideHiddenUntilNextUpdateAtom = atomWithStorage<Visibility>(
|
||||
export const guideHiddenUntilNextUpdateAtom = atomWithSyncStorage<Visibility>(
|
||||
'guideHiddenUntilNextUpdate',
|
||||
{}
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { atomWithSyncStorage } from '@affine/jotai';
|
||||
import { jotaiStore, jotaiWorkspacesAtom } from '@affine/workspace/atom';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { atom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
|
||||
import { WorkspacePlugins } from '../plugins';
|
||||
@@ -57,16 +57,12 @@ type View = { id: string; mode: 'page' | 'edgeless' };
|
||||
|
||||
export type WorkspaceRecentViews = Record<string, View[]>;
|
||||
|
||||
export const workspaceRecentViewsAtom = atomWithStorage<WorkspaceRecentViews>(
|
||||
'recentViews',
|
||||
{}
|
||||
);
|
||||
export const workspaceRecentViewsAtom =
|
||||
atomWithSyncStorage<WorkspaceRecentViews>('recentViews', {});
|
||||
|
||||
export type PreferredModeRecord = Record<Page['id'], 'page' | 'edgeless'>;
|
||||
export const workspacePreferredModeAtom = atomWithStorage<PreferredModeRecord>(
|
||||
'preferredMode',
|
||||
{}
|
||||
);
|
||||
export const workspacePreferredModeAtom =
|
||||
atomWithSyncStorage<PreferredModeRecord>('preferredMode', {});
|
||||
|
||||
export const workspaceRecentViresWriteAtom = atom<null, [string, View], View[]>(
|
||||
null,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { atomWithSyncStorage } from '@affine/jotai';
|
||||
import { atom, useAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
|
||||
const sideBarOpenAtom = atomWithStorage('sidebarOpen', true);
|
||||
const sideBarWidthAtom = atomWithStorage('sidebarWidth', 256);
|
||||
const sideBarOpenAtom = atomWithSyncStorage('sidebarOpen', true);
|
||||
const sideBarWidthAtom = atomWithSyncStorage('sidebarWidth', 256);
|
||||
const sidebarResizingAtom = atom(false);
|
||||
|
||||
export function useSidebarStatus() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { atomWithSyncStorage } from '@affine/jotai';
|
||||
import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import {
|
||||
@@ -17,7 +17,7 @@ export const currentWorkspaceAtom = atom<Promise<AllWorkspace | null>>(
|
||||
}
|
||||
);
|
||||
|
||||
export const lastWorkspaceIdAtom = atomWithStorage<string | null>(
|
||||
export const lastWorkspaceIdAtom = atomWithSyncStorage<string | null>(
|
||||
'last_workspace_id',
|
||||
null
|
||||
);
|
||||
|
||||
@@ -1,47 +1,46 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
||||
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
|
||||
import { jotaiStore, 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 { LocalPlugin } from '../plugins/local';
|
||||
|
||||
export function useCreateFirstWorkspace() {
|
||||
const [jotaiWorkspaces, set] = useAtom(jotaiWorkspacesAtom);
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const logger = new DebugLogger('use-create-first-workspace');
|
||||
|
||||
/**
|
||||
* Create a first workspace, only just once for a browser
|
||||
*/
|
||||
async function createFirst() {
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
nanoid(),
|
||||
(_: string) => undefined
|
||||
);
|
||||
blockSuiteWorkspace.meta.setName(DEFAULT_WORKSPACE_NAME);
|
||||
const id = await LocalPlugin.CRUD.create(blockSuiteWorkspace);
|
||||
const workspace = await LocalPlugin.CRUD.get(id);
|
||||
assertExists(workspace);
|
||||
assertEquals(workspace.id, id);
|
||||
set([
|
||||
{
|
||||
id: workspace.id,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (
|
||||
jotaiWorkspaces.length === 0 &&
|
||||
localStorage.getItem('first') !== 'true'
|
||||
) {
|
||||
localStorage.setItem('first', 'true');
|
||||
createFirst();
|
||||
}
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [jotaiWorkspaces.length, set]);
|
||||
export function useCreateFirstWorkspace() {
|
||||
// may not need use effect at all, right?
|
||||
useEffect(() => {
|
||||
return jotaiStore.sub(jotaiWorkspacesAtom, () => {
|
||||
const workspaces = jotaiStore.get(jotaiWorkspacesAtom);
|
||||
|
||||
if (workspaces.length === 0) {
|
||||
createFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a first workspace, only just once for a browser
|
||||
*/
|
||||
async function createFirst() {
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
nanoid(),
|
||||
(_: string) => undefined
|
||||
);
|
||||
blockSuiteWorkspace.meta.setName(DEFAULT_WORKSPACE_NAME);
|
||||
const id = await LocalPlugin.CRUD.create(blockSuiteWorkspace);
|
||||
const workspace = await LocalPlugin.CRUD.get(id);
|
||||
assertExists(workspace);
|
||||
assertEquals(workspace.id, id);
|
||||
jotaiStore.set(jotaiWorkspacesAtom, [
|
||||
{
|
||||
id: workspace.id,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
logger.info('created local workspace', id);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { jotaiWorkspacesAtom } from '@affine/workspace/atom';
|
||||
import type { LocalWorkspace } from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
@@ -15,6 +16,8 @@ export function useWorkspaces(): AllWorkspace[] {
|
||||
return useAtomValue(workspacesAtom);
|
||||
}
|
||||
|
||||
const logger = new DebugLogger('use-workspaces');
|
||||
|
||||
export function useWorkspacesHelper() {
|
||||
const workspaces = useWorkspaces();
|
||||
const jotaiWorkspaces = useAtomValue(jotaiWorkspacesAtom);
|
||||
@@ -48,6 +51,7 @@ export function useWorkspacesHelper() {
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
},
|
||||
]);
|
||||
logger.debug('created local workspace', id);
|
||||
return id;
|
||||
},
|
||||
[set]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import type { NextPage } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { Suspense, useEffect } from 'react';
|
||||
@@ -9,6 +10,8 @@ import { RouteLogic, useRouterHelper } from '../hooks/use-router-helper';
|
||||
import { useWorkspaces } from '../hooks/use-workspaces';
|
||||
import { WorkspaceSubPath } from '../shared';
|
||||
|
||||
const logger = new DebugLogger('IndexPage');
|
||||
|
||||
const IndexPageInner = () => {
|
||||
const router = useRouter();
|
||||
const { jumpToPage, jumpToSubPath } = useRouterHelper(router);
|
||||
@@ -28,11 +31,13 @@ const IndexPageInner = () => {
|
||||
const pageId =
|
||||
targetWorkspace.blockSuiteWorkspace.meta.pageMetas.at(0)?.id;
|
||||
if (pageId) {
|
||||
logger.debug('Found target workspace. Jump to page', pageId);
|
||||
jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE);
|
||||
return;
|
||||
} else {
|
||||
const clearId = setTimeout(() => {
|
||||
dispose.dispose();
|
||||
logger.debug('Found target workspace. Jump to all pages');
|
||||
jumpToSubPath(
|
||||
targetWorkspace.id,
|
||||
WorkspaceSubPath.ALL,
|
||||
@@ -50,6 +55,7 @@ const IndexPageInner = () => {
|
||||
};
|
||||
}
|
||||
} else {
|
||||
logger.debug('No target workspace. jump to all pages');
|
||||
// fixme: should create new workspace
|
||||
jumpToSubPath('ERROR', WorkspaceSubPath.ALL, RouteLogic.REPLACE);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { atomWithSyncStorage } from '@affine/jotai';
|
||||
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
|
||||
import {
|
||||
getLoginStorage,
|
||||
@@ -15,7 +16,6 @@ import {
|
||||
import { SettingsIcon } from '@blocksuite/icons';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { useAtom, useSetAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
@@ -32,7 +32,7 @@ import { WorkspaceLayout } from '../../../layouts';
|
||||
import { WorkspacePlugins } from '../../../plugins';
|
||||
import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
const settingPanelAtom = atomWithStorage<SettingPanel>(
|
||||
const settingPanelAtom = atomWithSyncStorage<SettingPanel>(
|
||||
'workspaceId',
|
||||
settingPanel.General
|
||||
);
|
||||
|
||||
@@ -131,6 +131,9 @@ export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
|
||||
},
|
||||
list: async () => {
|
||||
const allWorkspaces = getPersistenceAllWorkspace();
|
||||
if (!getLoginStorage()) {
|
||||
return allWorkspaces;
|
||||
}
|
||||
try {
|
||||
const workspaces = await affineApis.getWorkspaces().then(workspaces => {
|
||||
return workspaces.map(workspace => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
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';
|
||||
@@ -90,15 +89,6 @@ export const LocalPlugin: WorkspacePlugin<WorkspaceFlavour.LOCAL> = {
|
||||
)
|
||||
)
|
||||
).filter(item => item !== null) as LocalWorkspace[];
|
||||
if (data.length === 0) {
|
||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||
nanoid(),
|
||||
(_: string) => undefined
|
||||
);
|
||||
blockSuiteWorkspace.meta.setName(DEFAULT_WORKSPACE_NAME);
|
||||
await LocalPlugin.CRUD.create(blockSuiteWorkspace);
|
||||
return LocalPlugin.CRUD.list();
|
||||
}
|
||||
return data;
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user