From 6a535b94c3bb567cf7975b4ff1a39a42a736355f Mon Sep 17 00:00:00 2001 From: CatsJuice Date: Fri, 12 Apr 2024 09:55:45 +0000 Subject: [PATCH] feat(core): create and open cloud workspace if not exists after logged in (#6511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only execute when `initCloud=true` is specified in the URL search params. --- .../core/src/hooks/use-navigate-helper.ts | 11 ++-- packages/frontend/core/src/pages/index.tsx | 63 +++++++++++++++++-- packages/frontend/core/src/pages/sign-in.tsx | 8 ++- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/packages/frontend/core/src/hooks/use-navigate-helper.ts b/packages/frontend/core/src/hooks/use-navigate-helper.ts index c7f6538a9b..ae6ed54c9a 100644 --- a/packages/frontend/core/src/hooks/use-navigate-helper.ts +++ b/packages/frontend/core/src/hooks/use-navigate-helper.ts @@ -130,10 +130,13 @@ export function useNavigateHelper() { ); const jumpToIndex = useCallback( - (logic: RouteLogic = RouteLogic.PUSH) => { - return navigate('/', { - replace: logic === RouteLogic.REPLACE, - }); + (logic: RouteLogic = RouteLogic.PUSH, opt?: { search?: string }) => { + return navigate( + { pathname: '/', search: opt?.search }, + { + replace: logic === RouteLogic.REPLACE, + } + ); }, [navigate] ); diff --git a/packages/frontend/core/src/pages/index.tsx b/packages/frontend/core/src/pages/index.tsx index 7a14883d9d..00bdf6bd70 100644 --- a/packages/frontend/core/src/pages/index.tsx +++ b/packages/frontend/core/src/pages/index.tsx @@ -1,16 +1,26 @@ import { Menu } from '@affine/component/ui/menu'; +import { WorkspaceFlavour } from '@affine/env/workspace'; import { + initEmptyPage, useLiveData, useService, WorkspaceListService, WorkspaceManager, } from '@toeverything/infra'; -import { lazy, useEffect, useLayoutEffect, useState } from 'react'; -import type { LoaderFunction } from 'react-router-dom'; +import { + lazy, + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from 'react'; +import { type LoaderFunction, useSearchParams } from 'react-router-dom'; import { createFirstAppData } from '../bootstrap/first-app-data'; import { UserWithWorkspaceList } from '../components/pure/workspace-slider-bar/user-with-workspace-list'; import { WorkspaceFallback } from '../components/workspace'; +import { useSession } from '../hooks/affine/use-current-user'; import { useNavigateHelper } from '../hooks/use-navigate-helper'; import { WorkspaceSubPath } from '../shared'; @@ -28,12 +38,48 @@ export const Component = () => { // navigating and creating may be slow, to avoid flickering, we show workspace fallback const [navigating, setNavigating] = useState(false); const [creating, setCreating] = useState(false); + const { status } = useSession(); + const workspaceManager = useService(WorkspaceManager); - const list = useLiveData(useService(WorkspaceListService).workspaceList$); + const workspaceListService = useService(WorkspaceListService); + const list = useLiveData(workspaceListService.workspaceList$); + const workspaceListStatus = useLiveData(workspaceListService.status$); const { openPage } = useNavigateHelper(); + const [searchParams] = useSearchParams(); + + const createOnceRef = useRef(false); + + const createCloudWorkspace = useCallback(() => { + if (createOnceRef.current) return; + createOnceRef.current = true; + workspaceManager + .createWorkspace(WorkspaceFlavour.AFFINE_CLOUD, async workspace => { + workspace.meta.setName('AFFiNE Cloud'); + const page = workspace.createDoc(); + initEmptyPage(page); + }) + .then(workspace => openPage(workspace.id, WorkspaceSubPath.ALL)) + .catch(err => console.error('Failed to create cloud workspace', err)); + }, [openPage, workspaceManager]); useLayoutEffect(() => { + if (workspaceListStatus.loading) { + return; + } + + // check is user logged in && has cloud workspace + if ( + searchParams.get('initCloud') === 'true' && + status === 'authenticated' + ) { + searchParams.delete('initCloud'); + if (list.every(w => w.flavour !== WorkspaceFlavour.AFFINE_CLOUD)) { + createCloudWorkspace(); + return; + } + } + if (list.length === 0) { return; } @@ -44,9 +90,14 @@ export const Component = () => { const openWorkspace = list.find(w => w.id === lastId) ?? list[0]; openPage(openWorkspace.id, WorkspaceSubPath.ALL); setNavigating(true); - }, [list, openPage]); - - const workspaceManager = useService(WorkspaceManager); + }, [ + createCloudWorkspace, + list, + openPage, + searchParams, + status, + workspaceListStatus.loading, + ]); useEffect(() => { setCreating(true); diff --git a/packages/frontend/core/src/pages/sign-in.tsx b/packages/frontend/core/src/pages/sign-in.tsx index e62f502e2f..bae4df966d 100644 --- a/packages/frontend/core/src/pages/sign-in.tsx +++ b/packages/frontend/core/src/pages/sign-in.tsx @@ -3,7 +3,7 @@ import { SignInPageContainer } from '@affine/component/auth-components'; import { useAtom } from 'jotai'; import { useCallback, useEffect, useRef } from 'react'; // eslint-disable-next-line @typescript-eslint/no-restricted-imports -import { useLocation, useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; import { authAtom } from '../atoms'; import type { AuthProps } from '../components/affine/auth'; @@ -27,6 +27,7 @@ export const SignIn = () => { const navigate = useNavigate(); const { jumpToIndex } = useNavigateHelper(); const subscriptionData = useSubscriptionSearch(); + const [searchParams] = useSearchParams(); const isLoggedIn = loginStatus === 'authenticated'; @@ -49,7 +50,9 @@ export const SignIn = () => { replace: true, }); } else { - jumpToIndex(RouteLogic.REPLACE); + jumpToIndex(RouteLogic.REPLACE, { + search: searchParams.toString(), + }); } } }, [ @@ -59,6 +62,7 @@ export const SignIn = () => { setAuthAtom, subscriptionData, isLoggedIn, + searchParams, ]); const onSetEmailType = useCallback(