From b2fe31dc02a9d6100999dadcd2af171bd4700fa3 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 10 Jan 2023 18:34:26 +0800 Subject: [PATCH 01/43] feat: modify style --- packages/app/src/components/page-list/index.tsx | 2 +- packages/app/src/ui/table/styles.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/app/src/components/page-list/index.tsx b/packages/app/src/components/page-list/index.tsx index 2501f13ba..d31767b81 100644 --- a/packages/app/src/components/page-list/index.tsx +++ b/packages/app/src/components/page-list/index.tsx @@ -51,7 +51,7 @@ const FavoriteTag = ({ style={{ color: favorite ? theme.colors.primaryColor : theme.colors.iconColor, }} - className="favorite-button" + className={favorite ? '' : 'favorite-button'} > {favorite ? ( diff --git a/packages/app/src/ui/table/styles.ts b/packages/app/src/ui/table/styles.ts index 009888e8b..ab1a2629d 100644 --- a/packages/app/src/ui/table/styles.ts +++ b/packages/app/src/ui/table/styles.ts @@ -9,7 +9,7 @@ export const StyledTable = styled.table<{ tableLayout: 'auto' | 'fixed' }>( tableLayout, width: '100%', borderCollapse: 'separate', - borderSpacing: '0 25px', + borderSpacing: '0', }; } ); @@ -52,7 +52,6 @@ export const StyledTableHead = styled.thead(() => { export const StyledTableRow = styled.tr(({ theme }) => { return { - marginBottom: '25px', td: { transition: 'background .15s', }, From 33400f1c5a8b3352c9d940446c3d99730794a4d3 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 10 Jan 2023 19:15:56 +0800 Subject: [PATCH 02/43] feat: modify loading style --- packages/app/src/components/loading/styled.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/app/src/components/loading/styled.ts b/packages/app/src/components/loading/styled.ts index b98a8bfaa..31906e1b7 100644 --- a/packages/app/src/components/loading/styled.ts +++ b/packages/app/src/components/loading/styled.ts @@ -1,19 +1,22 @@ import { styled } from '@/styles'; // Inspired by https://codepen.io/graphilla/pen/rNvBMYY -export const StyledLoadingWrapper = styled.div<{ size?: number }>( - ({ size = 40 }) => { - return { - width: size * 4, - height: size * 4, - position: 'relative', - }; - } -); +export const StyledLoadingWrapper = styled('div', { + shouldForwardProp: prop => { + return !['size'].includes(prop); + }, +})<{ size?: number }>(({ size = 40 }) => { + return { + width: size * 4, + height: size * 4, + position: 'relative', + }; +}); export const StyledLoading = styled.div` position: absolute; left: 25%; - top: 25%; + top: 50%; + transform: rotateX(55deg) rotateZ(-45deg); @keyframes slide { 0% { transform: translate(var(--sx), var(--sy)); From e8431122c9a289858cd57ddac432c046f426fb5f Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 10 Jan 2023 19:41:19 +0800 Subject: [PATCH 03/43] feat: refactor provider logic --- .../src/components/workspace-modal/index.tsx | 2 +- .../app/src/hooks/use-ensure-workspace.ts | 8 ++----- .../providers/app-state-provider/Provider.tsx | 23 ++++++++----------- .../providers/app-state-provider/interface.ts | 2 +- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx index 3621d22e4..08372b52b 100644 --- a/packages/app/src/components/workspace-modal/index.tsx +++ b/packages/app/src/components/workspace-modal/index.tsx @@ -55,7 +55,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => { router.replace(`/workspace/${item.id}`); onClose(); }} - active={item.id === currentWorkspace.room} + active={item.id === currentWorkspace?.room} key={index} > diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 205443aee..03d50f26f 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -1,14 +1,11 @@ import { useState, useEffect } from 'react'; import { useAppState } from '@/providers/app-state-provider'; import { useRouter } from 'next/router'; -const defaultOutLineWorkspaceId = 'affine'; -// 'local-first-' + '85b4ca0b9081421d903bbc2501ea280f'; // It is a fully effective hook // Cause it not just ensure workspace loaded, but also have router change. export const useEnsureWorkspace = () => { const [workspaceLoaded, setWorkspaceLoaded] = useState(false); const { workspaceList, loadWorkspace, user } = useAppState(); - console.log('workspaceList: ', workspaceList); const router = useRouter(); // const defaultOutLineWorkspaceId = '99ce7eb7'; @@ -36,9 +33,8 @@ export const useEnsureWorkspace = () => { // return; // } - const workspaceId = user - ? (router.query.workspaceId as string) || workspaceList[0]?.id - : (router.query.workspaceId as string) || defaultOutLineWorkspaceId; + const workspaceId = + (router.query.workspaceId as string) || workspaceList[0]?.id; loadWorkspace(workspaceId).finally(() => { setWorkspaceLoaded(true); diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index 2c85e560e..e0a833d81 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -22,34 +22,29 @@ export const AppStateProvider = ({ const [appState, setAppState] = useState({} as AppStateValue); useEffect(() => { - const init = async () => { + const initState = async () => { const dataCenter = await getDataCenter(); + // Ensure datacenter has at least one workspace if (dataCenter.workspaces.length === 0) { await createDefaultWorkspace(dataCenter); } - const currentWorkspace = await dataCenter.loadWorkspace( - dataCenter.workspaces[0].id - ); - const currentMetaWorkSpace = dataCenter.workspaces.find(item => { - return item.id === currentWorkspace.room; - }); setAppState({ dataCenter, user: (await dataCenter.getUserInfo()) || null, workspaceList: dataCenter.workspaces, - currentWorkspaceId: dataCenter.workspaces[0].id, - currentWorkspace, - pageList: currentWorkspace.meta.pageMetas as PageMeta[], + currentWorkspaceId: '', + currentWorkspace: null, + pageList: [], currentPage: null, editor: null, synced: true, - currentMetaWorkSpace: currentMetaWorkSpace ?? null, + currentMetaWorkSpace: null, }); }; - init(); + initState(); }, []); useEffect(() => { @@ -94,6 +89,8 @@ export const AppStateProvider = ({ const loadWorkspace = useRef(); loadWorkspace.current = async (workspaceId: string) => { + console.log('loadWorkspace'); + const { dataCenter, workspaceList, currentWorkspaceId, currentWorkspace } = appState; if (!workspaceList.find(v => v.id === workspaceId)) { @@ -113,7 +110,7 @@ export const AppStateProvider = ({ currentWorkspace: workspace, currentWorkspaceId: workspaceId, currentMetaWorkSpace: currentMetaWorkSpace ?? null, - pageList: currentWorkspace.meta.pageMetas as PageMeta[], + pageList: currentWorkspace?.meta.pageMetas as PageMeta[], currentPage: null, editor: null, }); diff --git a/packages/app/src/providers/app-state-provider/interface.ts b/packages/app/src/providers/app-state-provider/interface.ts index 4e5ec6a9b..ca178781f 100644 --- a/packages/app/src/providers/app-state-provider/interface.ts +++ b/packages/app/src/providers/app-state-provider/interface.ts @@ -19,7 +19,7 @@ export type AppStateValue = { dataCenter: DataCenter; user: User | null; workspaceList: WorkspaceInfo[]; - currentWorkspace: StoreWorkspace; + currentWorkspace: StoreWorkspace | null; currentMetaWorkSpace: WorkspaceInfo | null; currentWorkspaceId: string; pageList: PageMeta[]; From 3be4e4015eb0c057fd2b4c3e95e6d4590dd8306a Mon Sep 17 00:00:00 2001 From: DiamondThree <857159145@qq.com> Date: Tue, 10 Jan 2023 20:08:31 +0800 Subject: [PATCH 04/43] feat: enable workspace cloud --- packages/app/src/hooks/use-ensure-workspace.ts | 2 +- packages/app/src/pages/workspace/[workspaceId]/index.tsx | 2 ++ packages/app/src/pages/workspace/index.tsx | 1 + packages/app/src/providers/app-state-provider/Provider.tsx | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 205443aee..93140dd92 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -8,7 +8,6 @@ const defaultOutLineWorkspaceId = 'affine'; export const useEnsureWorkspace = () => { const [workspaceLoaded, setWorkspaceLoaded] = useState(false); const { workspaceList, loadWorkspace, user } = useAppState(); - console.log('workspaceList: ', workspaceList); const router = useRouter(); // const defaultOutLineWorkspaceId = '99ce7eb7'; @@ -41,6 +40,7 @@ export const useEnsureWorkspace = () => { : (router.query.workspaceId as string) || defaultOutLineWorkspaceId; loadWorkspace(workspaceId).finally(() => { + console.log('workspaceId: ', workspaceId); setWorkspaceLoaded(true); }); }, [loadWorkspace, router, user, workspaceList]); diff --git a/packages/app/src/pages/workspace/[workspaceId]/index.tsx b/packages/app/src/pages/workspace/[workspaceId]/index.tsx index d502f5798..37144ff7c 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/index.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/index.tsx @@ -10,6 +10,7 @@ const WorkspaceIndex = () => { const { currentWorkspaceId, currentWorkspace } = useAppState(); const { createPage } = usePageHelper(); const { workspaceLoaded } = useEnsureWorkspace(); + console.log('workspaceLoaded: ', workspaceLoaded); useEffect(() => { const initPage = async () => { @@ -17,6 +18,7 @@ const WorkspaceIndex = () => { return; } const savedPageId = currentWorkspace?.meta.pageMetas[0]?.id; + console.log('savedPageId: ', savedPageId); if (savedPageId) { router.replace(`/workspace/${currentWorkspaceId}/${savedPageId}`); return; diff --git a/packages/app/src/pages/workspace/index.tsx b/packages/app/src/pages/workspace/index.tsx index 1fe3ba2c1..145e47e89 100644 --- a/packages/app/src/pages/workspace/index.tsx +++ b/packages/app/src/pages/workspace/index.tsx @@ -11,6 +11,7 @@ export const WorkspaceIndex = () => { useEffect(() => { if (workspaceLoaded) { + console.log('workspaceLoaded: ', workspaceLoaded); router.push(`/workspace/${currentWorkspaceId}`); } }, [currentWorkspaceId, router, workspaceLoaded]); diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index 2c85e560e..40a3f8775 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -28,6 +28,7 @@ export const AppStateProvider = ({ if (dataCenter.workspaces.length === 0) { await createDefaultWorkspace(dataCenter); } + const currentWorkspace = await dataCenter.loadWorkspace( dataCenter.workspaces[0].id ); From b86a03642aa94718eb31bc7c7f3845e4342b6d66 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 10 Jan 2023 20:42:00 +0800 Subject: [PATCH 05/43] fix: add judgement of currentWorkspace --- packages/app/src/components/workspace-setting/SyncPage.tsx | 2 +- .../app/src/components/workspace-setting/general/General.tsx | 5 +++-- packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx index 6c15773d9..fb0dc5aab 100644 --- a/packages/app/src/components/workspace-setting/SyncPage.tsx +++ b/packages/app/src/components/workspace-setting/SyncPage.tsx @@ -40,7 +40,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceInfo }) => { confirmText: user ? 'Enable' : 'Sign in and Enable', cancelText: 'Skip', }).then(async confirm => { - if (confirm) { + if (confirm && currentWorkspace) { // if (user) { // await login(); // } diff --git a/packages/app/src/components/workspace-setting/general/General.tsx b/packages/app/src/components/workspace-setting/general/General.tsx index 116b5863e..26802b4cc 100644 --- a/packages/app/src/components/workspace-setting/general/General.tsx +++ b/packages/app/src/components/workspace-setting/general/General.tsx @@ -42,14 +42,15 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceInfo }) => { }; const handleUpdateWorkspaceName = () => { console.log('currentWorkspace: ', currentWorkspace); - updateWorkspace({ name: workspaceName }, currentWorkspace); + currentWorkspace && + updateWorkspace({ name: workspaceName }, currentWorkspace); }; const fileChange = async (file: File) => { // console.log('file: ', file); // setUploading(true); const blob = new Blob([file], { type: file.type }); - updateWorkspace({ avatarBlob: blob }, currentWorkspace); + currentWorkspace && updateWorkspace({ avatarBlob: blob }, currentWorkspace); }; return workspace ? ( diff --git a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx index 2fc86ff58..2ede23582 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -31,7 +31,7 @@ const Page: NextPageWithLayout = () => { - {currentPage && ( + {currentPage && currentWorkspace && ( Date: Tue, 10 Jan 2023 21:08:28 +0800 Subject: [PATCH 06/43] fix: ensure return activeWorkspaceId --- .../app/src/components/workspace-setting/SyncPage.tsx | 2 +- packages/app/src/hooks/use-ensure-workspace.ts | 7 +++++-- .../app/src/pages/workspace/[workspaceId]/index.tsx | 10 +++++----- packages/app/src/pages/workspace/index.tsx | 1 - .../app/src/providers/app-state-provider/Provider.tsx | 6 +++--- packages/data-center/src/workspace-meta-collection.ts | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx index 6c15773d9..fb0dc5aab 100644 --- a/packages/app/src/components/workspace-setting/SyncPage.tsx +++ b/packages/app/src/components/workspace-setting/SyncPage.tsx @@ -40,7 +40,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceInfo }) => { confirmText: user ? 'Enable' : 'Sign in and Enable', cancelText: 'Skip', }).then(async confirm => { - if (confirm) { + if (confirm && currentWorkspace) { // if (user) { // await login(); // } diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index ce1fed074..a59f73881 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -7,6 +7,9 @@ export const useEnsureWorkspace = () => { const [workspaceLoaded, setWorkspaceLoaded] = useState(false); const { workspaceList, loadWorkspace, user } = useAppState(); const router = useRouter(); + const [activeWorkspaceId, setActiveWorkspaceId] = useState( + router.query.workspaceId as string + ); // const defaultOutLineWorkspaceId = '99ce7eb7'; // console.log(defaultOutLineWorkspaceId); @@ -35,15 +38,15 @@ export const useEnsureWorkspace = () => { const workspaceId = (router.query.workspaceId as string) || workspaceList[0]?.id; - loadWorkspace(workspaceId).finally(() => { - console.log('workspaceId: ', workspaceId); setWorkspaceLoaded(true); + setActiveWorkspaceId(activeWorkspaceId); }); }, [loadWorkspace, router, user, workspaceList]); return { workspaceLoaded, + activeWorkspaceId, }; }; diff --git a/packages/app/src/pages/workspace/[workspaceId]/index.tsx b/packages/app/src/pages/workspace/[workspaceId]/index.tsx index 37144ff7c..d0a9e086d 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/index.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/index.tsx @@ -9,23 +9,23 @@ const WorkspaceIndex = () => { const router = useRouter(); const { currentWorkspaceId, currentWorkspace } = useAppState(); const { createPage } = usePageHelper(); - const { workspaceLoaded } = useEnsureWorkspace(); - console.log('workspaceLoaded: ', workspaceLoaded); + const { workspaceLoaded, activeWorkspaceId } = useEnsureWorkspace(); useEffect(() => { const initPage = async () => { if (!workspaceLoaded) { return; } + const savedPageId = currentWorkspace?.meta.pageMetas[0]?.id; - console.log('savedPageId: ', savedPageId); + if (savedPageId) { - router.replace(`/workspace/${currentWorkspaceId}/${savedPageId}`); + router.replace(`/workspace/${activeWorkspaceId}/${savedPageId}`); return; } const pageId = await createPage(); - router.replace(`/workspace/${currentWorkspaceId}/${pageId}`); + router.replace(`/workspace/${activeWorkspaceId}/${pageId}`); }; initPage(); }, [ diff --git a/packages/app/src/pages/workspace/index.tsx b/packages/app/src/pages/workspace/index.tsx index 145e47e89..1fe3ba2c1 100644 --- a/packages/app/src/pages/workspace/index.tsx +++ b/packages/app/src/pages/workspace/index.tsx @@ -11,7 +11,6 @@ export const WorkspaceIndex = () => { useEffect(() => { if (workspaceLoaded) { - console.log('workspaceLoaded: ', workspaceLoaded); router.push(`/workspace/${currentWorkspaceId}`); } }, [currentWorkspaceId, router, workspaceLoaded]); diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index e0a833d81..33f650d02 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -89,22 +89,22 @@ export const AppStateProvider = ({ const loadWorkspace = useRef(); loadWorkspace.current = async (workspaceId: string) => { - console.log('loadWorkspace'); - const { dataCenter, workspaceList, currentWorkspaceId, currentWorkspace } = appState; - if (!workspaceList.find(v => v.id === workspaceId)) { + if (!workspaceList.find(v => v.id.toString() === workspaceId)) { return null; } if (workspaceId === currentWorkspaceId) { return currentWorkspace; } + const workspace = await dataCenter.loadWorkspace(workspaceId); const currentMetaWorkSpace = dataCenter.workspaces.find( (item: WorkspaceInfo) => { return item.id === workspace.room; } ); + setAppState({ ...appState, currentWorkspace: workspace, diff --git a/packages/data-center/src/workspace-meta-collection.ts b/packages/data-center/src/workspace-meta-collection.ts index 6b7ce4a35..c50b93dca 100644 --- a/packages/data-center/src/workspace-meta-collection.ts +++ b/packages/data-center/src/workspace-meta-collection.ts @@ -41,7 +41,7 @@ export class WorkspaceMetaCollection extends Observable<'change'> { if (this._workspacesMap.has(workspace.id)) { throw new Error(`Duplicate workspace id.`); } - this._workspacesMap.set(workspace.id, workspace); + this._workspacesMap.set(workspace.id.toString(), workspace); scopedWorkspaceIds.add(workspace.id); this.emit('change', [ From 2780beddbba4593b415972cb85c6ffbd78c16db3 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 10 Jan 2023 21:09:38 +0800 Subject: [PATCH 07/43] feat: refactor user & login function --- .../src/components/workspace-modal/index.tsx | 5 +--- .../components/workspace-setting/SyncPage.tsx | 4 +-- packages/app/src/hooks/use-user-helper.ts | 28 ------------------- .../providers/app-state-provider/Provider.tsx | 24 +++++++++++++++- .../providers/app-state-provider/interface.ts | 3 ++ 5 files changed, 28 insertions(+), 36 deletions(-) delete mode 100644 packages/app/src/hooks/use-user-helper.ts diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx index 08372b52b..5380f71fc 100644 --- a/packages/app/src/components/workspace-modal/index.tsx +++ b/packages/app/src/components/workspace-modal/index.tsx @@ -10,12 +10,10 @@ import { UsersIcon, AddIcon, } from '@blocksuite/icons'; -// import { useConfirm } from '@/providers/ConfirmProvider'; import { toast } from '@/ui/toast'; import { WorkspaceAvatar } from '@/components/workspace-avatar'; import { useAppState } from '@/providers/app-state-provider'; import { useRouter } from 'next/router'; -import { useUserHelper } from '@/hooks/use-user-helper'; interface WorkspaceModalProps { open: boolean; @@ -25,8 +23,7 @@ interface WorkspaceModalProps { export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => { const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false); // const { confirm } = useConfirm(); - const { workspaceList, currentWorkspace } = useAppState(); - const { login, user } = useUserHelper(); + const { workspaceList, currentWorkspace, login, user } = useAppState(); const router = useRouter(); return (
diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx index fb0dc5aab..afd19b700 100644 --- a/packages/app/src/components/workspace-setting/SyncPage.tsx +++ b/packages/app/src/components/workspace-setting/SyncPage.tsx @@ -11,14 +11,12 @@ import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; import { useAppState } from '@/providers/app-state-provider'; import { useConfirm } from '@/providers/ConfirmProvider'; import { toast } from '@/ui/toast'; -import { useUserHelper } from '@/hooks/use-user-helper'; import { useRouter } from 'next/router'; export const SyncPage = ({ workspace }: { workspace: WorkspaceInfo }) => { // console.log('workspace: ', workspace); const { enableWorkspace } = useWorkspaceHelper(); - const { currentWorkspace } = useAppState(); + const { currentWorkspace, user } = useAppState(); const { confirm } = useConfirm(); - const { user, login } = useUserHelper(); const router = useRouter(); return (
diff --git a/packages/app/src/hooks/use-user-helper.ts b/packages/app/src/hooks/use-user-helper.ts deleted file mode 100644 index 7d837cec5..000000000 --- a/packages/app/src/hooks/use-user-helper.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { useAppState } from '@/providers/app-state-provider'; -import { User } from '@affine/datacenter'; -import { useEffect, useState } from 'react'; - -export const useUserHelper = () => { - const { dataCenter } = useAppState(); - const [user, setUser] = useState(undefined); - useEffect(() => { - dataCenter - .getUserInfo() - .then(user => { - setUser(user); - }) - .catch(e => { - setUser(undefined); - }); - }, []); - - const login = async () => { - await dataCenter.login(); - const user = await dataCenter.getUserInfo(); - setUser(user); - }; - return { - user, - login, - }; -}; diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index e0a833d81..ea83020a5 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -8,7 +8,7 @@ import { PageMeta, } from './interface'; import { createDefaultWorkspace } from './utils'; -import { WorkspaceInfo } from '@affine/datacenter'; +import { WorkspaceInfo, User } from '@affine/datacenter'; type AppStateContextProps = PropsWithChildren>; @@ -127,6 +127,26 @@ export const AppStateProvider = ({ }); }; + const login = async () => { + const { dataCenter } = appState; + await dataCenter.login(); + const user = (await dataCenter.getUserInfo()) as User; + setAppState({ + ...appState, + user, + }); + return user; + }; + + const logout = async () => { + const { dataCenter } = appState; + await dataCenter.logout(); + setAppState({ + ...appState, + user: null, + }); + }; + return ( {children} diff --git a/packages/app/src/providers/app-state-provider/interface.ts b/packages/app/src/providers/app-state-provider/interface.ts index ca178781f..de1577af7 100644 --- a/packages/app/src/providers/app-state-provider/interface.ts +++ b/packages/app/src/providers/app-state-provider/interface.ts @@ -33,6 +33,9 @@ export type AppStateFunction = { loadWorkspace: (workspaceId: string) => Promise; loadPage: (pageId: string) => void; + + login: () => Promise; + logout: () => Promise; }; export type AppStateContext = AppStateValue & AppStateFunction; From 30679763abce60535a2114a24938d82186506aaf Mon Sep 17 00:00:00 2001 From: DiamondThree <857159145@qq.com> Date: Tue, 10 Jan 2023 21:59:09 +0800 Subject: [PATCH 08/43] feat: change workspaceInfo type --- .../app/src/components/quick-search/Input.tsx | 2 +- .../app/src/components/quick-search/index.tsx | 2 +- .../src/components/workspace-modal/index.tsx | 2 +- .../workspace-setting/ExportPage.tsx | 4 +- .../workspace-setting/MembersPage.tsx | 4 +- .../workspace-setting/PublishPage.tsx | 8 +- .../components/workspace-setting/SyncPage.tsx | 4 +- .../workspace-setting/general/General.tsx | 4 +- .../general/delete/Delete.tsx | 4 +- .../pages/workspace/[workspaceId]/setting.tsx | 4 +- .../providers/app-state-provider/Provider.tsx | 19 +-- .../providers/app-state-provider/interface.ts | 6 +- packages/data-center/src/index.ts | 1 + .../src/workspace-meta-collection.ts | 127 ------------------ .../src/workspace-unit-collection.ts | 2 +- 15 files changed, 35 insertions(+), 158 deletions(-) delete mode 100644 packages/data-center/src/workspace-meta-collection.ts diff --git a/packages/app/src/components/quick-search/Input.tsx b/packages/app/src/components/quick-search/Input.tsx index 69d47a16a..e12dc655b 100644 --- a/packages/app/src/components/quick-search/Input.tsx +++ b/packages/app/src/components/quick-search/Input.tsx @@ -20,7 +20,7 @@ export const Input = (props: { const { currentWorkspaceId, workspaceList, currentWorkspace } = useAppState(); const isPublish = workspaceList.find( meta => String(meta.id) === String(currentWorkspaceId) - )?.isPublish; + )?.published; useEffect(() => { inputRef.current?.addEventListener( 'blur', diff --git a/packages/app/src/components/quick-search/index.tsx b/packages/app/src/components/quick-search/index.tsx index 8199493a4..1450531f5 100644 --- a/packages/app/src/components/quick-search/index.tsx +++ b/packages/app/src/components/quick-search/index.tsx @@ -29,7 +29,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => { const [showCreatePage, setShowCreatePage] = useState(true); const { triggerQuickSearchModal } = useModal(); - const isPublish = currentMetaWorkSpace?.isPublish; + const isPublish = currentMetaWorkSpace?.published; // Add ‘⌘+K’ shortcut keys as switches useEffect(() => { diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx index 5380f71fc..dbe5146c5 100644 --- a/packages/app/src/components/workspace-modal/index.tsx +++ b/packages/app/src/components/workspace-modal/index.tsx @@ -98,7 +98,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => { {item.provider === 'affine' && ( )} - {item.isPublish && } + {item.published && } {/* {item.isLocal ? 'isLocal' : ''}/ */} diff --git a/packages/app/src/components/workspace-setting/ExportPage.tsx b/packages/app/src/components/workspace-setting/ExportPage.tsx index 3742b71a3..e3bde461f 100644 --- a/packages/app/src/components/workspace-setting/ExportPage.tsx +++ b/packages/app/src/components/workspace-setting/ExportPage.tsx @@ -1,5 +1,5 @@ import { styled } from '@/styles'; -import { WorkspaceInfo } from '@affine/datacenter'; +import { WorkspaceUnit } from '@affine/datacenter'; export const ExportPageTitleContainer = styled('div')(() => { return { @@ -9,7 +9,7 @@ export const ExportPageTitleContainer = styled('div')(() => { flex: 1, }; }); -export const ExportPage = ({ workspace }: { workspace: WorkspaceInfo }) => { +export const ExportPage = ({ workspace }: { workspace: WorkspaceUnit }) => { return ( Export Workspace{' '} diff --git a/packages/app/src/components/workspace-setting/MembersPage.tsx b/packages/app/src/components/workspace-setting/MembersPage.tsx index 32639f874..3859bcbd2 100644 --- a/packages/app/src/components/workspace-setting/MembersPage.tsx +++ b/packages/app/src/components/workspace-setting/MembersPage.tsx @@ -24,13 +24,13 @@ import { Empty } from '@/ui/empty'; // User, // Workspace, // } from '@/hooks/mock-data/mock'; -import { WorkspaceInfo } from '@affine/datacenter'; +import { WorkspaceUnit } from '@affine/datacenter'; import { useTemporaryHelper } from '@/providers/temporary-helper-provider'; import { StyledMemberWarp } from './general/style'; import { useConfirm } from '@/providers/ConfirmProvider'; // import { useAppState } from '@/providers/app-state-provider'; -export const MembersPage = ({ workspace }: { workspace: WorkspaceInfo }) => { +export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const [isInviteModalShow, setIsInviteModalShow] = useState(false); const [members, setMembers] = useState<[{ name: string; email: string }]>([ { name: 'affine', email: 'tttt' }, diff --git a/packages/app/src/components/workspace-setting/PublishPage.tsx b/packages/app/src/components/workspace-setting/PublishPage.tsx index e931041fa..dce254dc2 100644 --- a/packages/app/src/components/workspace-setting/PublishPage.tsx +++ b/packages/app/src/components/workspace-setting/PublishPage.tsx @@ -12,9 +12,9 @@ import { toast } from '@/ui/toast'; import { useConfirm } from '@/providers/ConfirmProvider'; // import { useAppState } from '@/providers/app-state-provider3'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; -import { WorkspaceInfo } from '@affine/datacenter'; +import { WorkspaceUnit } from '@affine/datacenter'; -export const PublishPage = ({ workspace }: { workspace: WorkspaceInfo }) => { +export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const shareUrl = window.location.host + '/workspace/' + workspace.id + '?share=true'; const { publishWorkspace } = useWorkspaceHelper(); @@ -53,7 +53,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceInfo }) => { {workspace.provider === 'cloud' ? (
- {workspace?.isPublish ? ( + {workspace?.published ? ( <> Publishing to web requires AFFiNE Cloud service . @@ -75,7 +75,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceInfo }) => { )} - {workspace.isPublish ? ( + {workspace.published ? (
) : (
{ // await login(); // } const id = await enableWorkspace(currentWorkspace); - router.push(`/workspace/${id}`); + router.push(`/workspace/${id}/setting`); toast('Enabled success'); } }); diff --git a/packages/app/src/components/workspace-setting/general/General.tsx b/packages/app/src/components/workspace-setting/general/General.tsx index ec541b9f1..0b0194147 100644 --- a/packages/app/src/components/workspace-setting/general/General.tsx +++ b/packages/app/src/components/workspace-setting/general/General.tsx @@ -48,9 +48,11 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const fileChange = async (file: File) => { // console.log('file: ', file); - // setUploading(true); + setUploading(true); const blob = new Blob([file], { type: file.type }); - currentWorkspace && updateWorkspace({ avatarBlob: blob }, currentWorkspace); + currentWorkspace && + (await updateWorkspace({ avatarBlob: blob }, currentWorkspace)); + setUploading(false); }; return workspace ? ( diff --git a/packages/app/src/components/workspace-setting/style.ts b/packages/app/src/components/workspace-setting/style.ts index a6b162fab..f750ef859 100644 --- a/packages/app/src/components/workspace-setting/style.ts +++ b/packages/app/src/components/workspace-setting/style.ts @@ -2,7 +2,7 @@ import { styled } from '@/styles'; import { Button } from '@/ui/button'; import MuiAvatar from '@mui/material/Avatar'; -export const StyledSettingContainer = styled('div')(({ theme }) => { +export const StyledSettingContainer = styled('div')(() => { return { display: 'flex', padding: '50px', @@ -12,7 +12,7 @@ export const StyledSettingContainer = styled('div')(({ theme }) => { }; }); -export const StyledSettingSidebar = styled('div')(({ theme }) => { +export const StyledSettingSidebar = styled('div')(() => { { return { flexShrink: 0, diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index a59f73881..0ef15580a 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -18,7 +18,8 @@ export const useEnsureWorkspace = () => { // If workspaceList is empty, we need to create a default workspace but not jump to 404 if ( workspaceList.length && - router.query.workspaceId && + // FIXME: router is not ready when this hook is called + location.pathname.startsWith(`/workspace/${router.query.workspaceId}`) && workspaceList.findIndex( meta => meta.id.toString() === router.query.workspaceId ) === -1 @@ -35,14 +36,13 @@ export const useEnsureWorkspace = () => { // router.push('/404'); // return; // } - const workspaceId = (router.query.workspaceId as string) || workspaceList[0]?.id; loadWorkspace(workspaceId).finally(() => { setWorkspaceLoaded(true); setActiveWorkspaceId(activeWorkspaceId); }); - }, [loadWorkspace, router, user, workspaceList]); + }, [loadWorkspace, router, user, workspaceList, activeWorkspaceId]); return { workspaceLoaded, diff --git a/packages/app/src/pages/workspace/[workspaceId]/index.tsx b/packages/app/src/pages/workspace/[workspaceId]/index.tsx index d0a9e086d..cdfd343af 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/index.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/index.tsx @@ -16,9 +16,7 @@ const WorkspaceIndex = () => { if (!workspaceLoaded) { return; } - const savedPageId = currentWorkspace?.meta.pageMetas[0]?.id; - if (savedPageId) { router.replace(`/workspace/${activeWorkspaceId}/${savedPageId}`); return; @@ -34,6 +32,7 @@ const WorkspaceIndex = () => { createPage, router, workspaceLoaded, + activeWorkspaceId, ]); return ; diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index 9c2afcf75..619b7fc2c 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -100,7 +100,6 @@ export const AppStateProvider = ({ if (workspaceId === currentWorkspaceId) { return currentWorkspace; } - const workspace = await dataCenter.loadWorkspace(workspaceId); const currentMetaWorkSpace = dataCenter.workspaces.find( (item: WorkspaceUnit) => { diff --git a/packages/app/src/providers/app-state-provider/utils.ts b/packages/app/src/providers/app-state-provider/utils.ts index 066ef7a2c..6dc3c8cca 100644 --- a/packages/app/src/providers/app-state-provider/utils.ts +++ b/packages/app/src/providers/app-state-provider/utils.ts @@ -4,7 +4,6 @@ const DEFAULT_WORKSPACE_NAME = 'affine'; export const createDefaultWorkspace = async (dataCenter: DataCenter) => { return dataCenter.createWorkspace({ - avatar: 'test', name: DEFAULT_WORKSPACE_NAME, }); }; diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index 8e70718c3..76499b11e 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -43,8 +43,8 @@ export class DataCenter { }; }; // TODO: switch different provider - dc.registerProvider(new LocalProvider(getInitParams())); - dc.registerProvider(new AffineProvider(getInitParams())); + await dc.registerProvider(new LocalProvider(getInitParams())); + await dc.registerProvider(new AffineProvider(getInitParams())); for (const provider of dc.providerMap.values()) { await provider.loadWorkspaces(); @@ -57,12 +57,12 @@ export class DataCenter { * Register provider. * We will automatically set the first provider to default provider. */ - registerProvider(provider: BaseProvider) { + async registerProvider(provider: BaseProvider) { if (!this._mainProvider) { this._mainProvider = provider; } - provider.init(); + await provider.init(); this.providerMap.set(provider.id, provider); } @@ -123,7 +123,7 @@ export class DataCenter { const workspaceInfo = this._workspaceUnitCollection.find(workspaceId); assert(workspaceInfo, 'Workspace not found'); return ( - this._workspaceInstances.get(workspaceId) || + // this._workspaceInstances.get(workspaceId) || createBlocksuiteWorkspace(workspaceId) ); } diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index 890fc6dc0..1ba3524fe 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -212,6 +212,7 @@ export class AffineProvider extends BaseProvider { } public override async getUserInfo(): Promise { + await this.init(); const user = this._apis.token.user; return user ? { diff --git a/packages/data-center/src/provider/affine/apis/workspace.ts b/packages/data-center/src/provider/affine/apis/workspace.ts index 8bdc25b21..29a729ae6 100644 --- a/packages/data-center/src/provider/affine/apis/workspace.ts +++ b/packages/data-center/src/provider/affine/apis/workspace.ts @@ -84,7 +84,10 @@ export interface CreateWorkspaceParams { export async function createWorkspace( params: CreateWorkspaceParams ): Promise<{ id: string }> { - return client.post('api/workspace', { json: params }).json(); + // FIXME: avatar should be optional + return client + .post('api/workspace', { json: { ...params, avatar: '123' } }) + .json(); } export interface UpdateWorkspaceParams { From ee6138134d9df3383807789aa63a0f2733e5e8b8 Mon Sep 17 00:00:00 2001 From: DiamondThree <857159145@qq.com> Date: Wed, 11 Jan 2023 12:12:12 +0800 Subject: [PATCH 10/43] feat: publish workspace --- .../workspace-setting/MembersPage.tsx | 2 +- .../workspace-setting/PublishPage.tsx | 32 ++++--------------- .../components/workspace-setting/SyncPage.tsx | 26 ++------------- .../app/src/hooks/use-workspace-helper.ts | 32 +++++++++++++++---- .../providers/app-state-provider/Provider.tsx | 2 +- .../data-center/src/provider/affine/affine.ts | 1 + 6 files changed, 38 insertions(+), 57 deletions(-) diff --git a/packages/app/src/components/workspace-setting/MembersPage.tsx b/packages/app/src/components/workspace-setting/MembersPage.tsx index 3859bcbd2..08b2640c9 100644 --- a/packages/app/src/components/workspace-setting/MembersPage.tsx +++ b/packages/app/src/components/workspace-setting/MembersPage.tsx @@ -64,7 +64,7 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => { return (
- {workspace.provider === 'cloud' ? ( + {workspace.provider === 'affine' ? ( <> diff --git a/packages/app/src/components/workspace-setting/PublishPage.tsx b/packages/app/src/components/workspace-setting/PublishPage.tsx index dce254dc2..c5c39cc2d 100644 --- a/packages/app/src/components/workspace-setting/PublishPage.tsx +++ b/packages/app/src/components/workspace-setting/PublishPage.tsx @@ -9,20 +9,17 @@ import { import { Button } from '@/ui/button'; import Input from '@/ui/input'; import { toast } from '@/ui/toast'; -import { useConfirm } from '@/providers/ConfirmProvider'; // import { useAppState } from '@/providers/app-state-provider3'; -import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; import { WorkspaceUnit } from '@affine/datacenter'; +import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const shareUrl = window.location.host + '/workspace/' + workspace.id + '?share=true'; - const { publishWorkspace } = useWorkspaceHelper(); + const { publishWorkspace, enableWorkspace } = useWorkspaceHelper(); - const { confirm } = useConfirm(); - - const togglePublic = (flag: boolean) => { - workspace.id && publishWorkspace(workspace?.id, flag); + const togglePublic = async (flag: boolean) => { + await publishWorkspace(workspace.id.toString(), flag); }; const copyUrl = () => { @@ -30,27 +27,12 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => { toast('Copied url to clipboard'); }; - const enableAffineCloud = () => { - confirm({ - title: 'Enable AFFiNE Cloud?', - content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`, - confirmText: - workspace.provider === 'local' ? 'Enable' : 'Sign in and Enable', - cancelText: 'Skip', - }).then(confirm => { - if (confirm) { - // if (user) { - // updateWorkspaceMeta(workspace.id, { type: 'cloud' }); - // } else { - // login(); - // updateWorkspaceMeta(workspace.id, { type: 'cloud' }); - // } - } - }); + const enableAffineCloud = async () => { + await enableWorkspace(); }; return ( <> - {workspace.provider === 'cloud' ? ( + {workspace.provider === 'affine' ? (
{workspace?.published ? ( diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx index 37ba8ab3f..d6345a294 100644 --- a/packages/app/src/components/workspace-setting/SyncPage.tsx +++ b/packages/app/src/components/workspace-setting/SyncPage.tsx @@ -8,16 +8,8 @@ import { Button } from '@/ui/button'; import { Menu, MenuItem } from '@/ui/menu'; import { WorkspaceUnit } from '@affine/datacenter'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; -import { useAppState } from '@/providers/app-state-provider'; -import { useConfirm } from '@/providers/ConfirmProvider'; -import { toast } from '@/ui/toast'; -import { useRouter } from 'next/router'; export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => { - // console.log('workspace: ', workspace); const { enableWorkspace } = useWorkspaceHelper(); - const { currentWorkspace, user } = useAppState(); - const { confirm } = useConfirm(); - const router = useRouter(); return (
@@ -31,22 +23,8 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => { - { - setIsInviteModalShow(false); - }} - onInviteSuccess={() => { - setMembersList(); - setIsInviteModalShow(false); - // refreshMembers(); - }} - workspaceId={workspace.id} - open={isInviteModalShow} - > - - - ) : ( - - <>Collaborating with other members requires AFFiNE Cloud service. - - - - - )} -
- ); -}; diff --git a/packages/app/src/components/workspace-setting/general/style.ts b/packages/app/src/components/workspace-setting/general/style.ts index 4a82017e9..739ec24ae 100644 --- a/packages/app/src/components/workspace-setting/general/style.ts +++ b/packages/app/src/components/workspace-setting/general/style.ts @@ -26,11 +26,3 @@ export const StyledSettingAvatarContent = styled('div')(() => { export const StyledSettingAvatar = styled(MuiAvatar)(() => { return { height: '72px', width: '72px', marginRight: '24px' }; }); - -export const StyledMemberWarp = styled('div')(() => { - return { - display: 'flex', - flexDirection: 'column', - padding: '40px 0', - }; -}); diff --git a/packages/app/src/components/workspace-setting/index.ts b/packages/app/src/components/workspace-setting/index.ts index c0eea1cfb..0468074d2 100644 --- a/packages/app/src/components/workspace-setting/index.ts +++ b/packages/app/src/components/workspace-setting/index.ts @@ -1,5 +1,5 @@ export * from './general'; export * from './ExportPage'; -export * from './MembersPage'; +export * from './member'; export * from './SyncPage'; export * from './PublishPage'; diff --git a/packages/app/src/components/invite-members/index.tsx b/packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx similarity index 77% rename from packages/app/src/components/invite-members/index.tsx rename to packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx index 6fb020fc5..c066908ed 100644 --- a/packages/app/src/components/invite-members/index.tsx +++ b/packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx @@ -4,9 +4,9 @@ import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; import { useState } from 'react'; -// import { getDataCenter } from '@affine/datacenter'; import { Avatar } from '@mui/material'; -import { setMember } from '@/hooks/mock-data/mock'; +import useMembers from '@/hooks/use-members'; +import { User } from '@affine/datacenter'; interface LoginModalProps { open: boolean; onClose: () => void; @@ -43,46 +43,27 @@ export const debounce = any>( }; const gmailReg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@gmail\.com$/; -export const InviteMembers = ({ +export const InviteMemberModal = ({ open, onClose, - workspaceId, onInviteSuccess, }: LoginModalProps) => { const [email, setEmail] = useState(''); const [showMember, setShowMember] = useState(false); const [showTip, setShowTip] = useState(false); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const [userData, setUserData] = useState({}); + const [userData, setUserData] = useState(null); + const { inviteMember, getUserByEmail } = useMembers(); const inputChange = (value: string) => { setShowMember(true); if (gmailReg.test(value)) { setEmail(value); setShowTip(false); - setUserData({ - name: 'wxl', - avatar: 'https://avatars.githubusercontent.com/u/20501502?v=4', - email: value, + getUserByEmail(value).then(data => { + if (data?.name) { + setUserData(data); + setShowTip(false); + } }); - // debounce( - // () => { - // getDataCenter() - // .then(dc => - // dc.apis.getUserByEmail({ - // email: value, - // workspace_id: workspaceId, - // }) - // ) - // .then(data => { - // if (data?.name) { - // setUserData(data); - // setShowTip(false); - // } - // }); - // }, - // 300, - // true - // )(); } else { setShowTip(true); } @@ -118,8 +99,8 @@ export const InviteMembers = ({ Non-Gmail is not supported ) : ( - {userData?.avatar_url ? ( - + {userData?.avatar ? ( + ) : ( @@ -139,19 +120,9 @@ export const InviteMembers = ({ + { + setIsInviteModalShow(false); + }} + onInviteSuccess={() => { + setIsInviteModalShow(false); + // refreshMembers(); + }} + workspaceId={workspace.id} + open={isInviteModalShow} + > + + + ); + } + + return ( + + <>Collaborating with other members requires AFFiNE Cloud service. + + + + + ); +}; diff --git a/packages/app/src/components/workspace-setting/member/index.ts b/packages/app/src/components/workspace-setting/member/index.ts new file mode 100644 index 000000000..aced79efe --- /dev/null +++ b/packages/app/src/components/workspace-setting/member/index.ts @@ -0,0 +1 @@ +export * from './MembersPage'; diff --git a/packages/app/src/components/workspace-setting/member/style.ts b/packages/app/src/components/workspace-setting/member/style.ts new file mode 100644 index 000000000..a5bf612f9 --- /dev/null +++ b/packages/app/src/components/workspace-setting/member/style.ts @@ -0,0 +1,107 @@ +import { styled } from '@/styles'; +import MuiAvatar from '@mui/material/Avatar'; +import { Button } from '@/ui/button'; + +export const StyledMemberTitleContainer = styled('div')(() => { + return { + display: 'flex', + marginTop: '60px', + fontWeight: '500', + flex: 1, + }; +}); + +export const StyledMemberAvatar = styled(MuiAvatar)(() => { + return { height: '40px', width: '40px' }; +}); + +export const StyledMemberNameContainer = styled('div')(() => { + return { + display: 'flex', + alignItems: 'center', + width: '402px', + }; +}); + +export const StyledMemberRoleContainer = styled('div')(() => { + return { + display: 'flex', + alignItems: 'center', + width: '222px', + }; +}); + +export const StyledMemberListContainer = styled('ul')(() => { + return { + marginTop: '15px', + overflowY: 'scroll', + }; +}); + +export const StyledMemberListItem = styled('li')(() => { + return { + display: 'flex', + alignItems: 'center', + height: '72px', + }; +}); + +export const StyledMemberInfo = styled('div')(() => { + return { + paddingLeft: '12px', + }; +}); + +export const StyledMemberName = styled('div')(({ theme }) => { + return { + fontWeight: '400', + fontSize: '18px', + lineHeight: '16px', + color: theme.colors.textColor, + }; +}); + +export const StyledMemberEmail = styled('div')(({ theme }) => { + return { + fontWeight: '400', + fontSize: '16px', + lineHeight: '22px', + color: theme.colors.iconColor, + }; +}); + +export const StyledMemberButtonContainer = styled('div')(() => { + return { + marginTop: '14px', + }; +}); + +export const StyledMoreVerticalButton = styled('button')(() => { + return { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '24px', + height: '24px', + cursor: 'pointer', + }; +}); + +export const StyledPublishExplanation = styled('div')(() => { + return { + paddingRight: '48px', + fontWeight: '500', + fontSize: '18px', + lineHeight: '26px', + flex: 1, + marginTop: '60px', + }; +}); + +export const StyledMemberWarp = styled('div')(() => { + return { + display: 'flex', + flexDirection: 'column', + padding: '40px 0', + }; +}); diff --git a/packages/app/src/components/workspace-setting/style.ts b/packages/app/src/components/workspace-setting/style.ts index f750ef859..1809ed428 100644 --- a/packages/app/src/components/workspace-setting/style.ts +++ b/packages/app/src/components/workspace-setting/style.ts @@ -96,99 +96,6 @@ export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>( } ); -export const StyledAvatarUploadBtn = styled(Button)(({ theme }) => { - return { - backgroundColor: theme.colors.hoverBackground, - color: theme.colors.primaryColor, - margin: '0 12px 0 24px', - }; -}); - -export const StyledMemberTitleContainer = styled('div')(() => { - return { - display: 'flex', - marginTop: '60px', - fontWeight: '500', - flex: 1, - }; -}); - -export const StyledMemberAvatar = styled(MuiAvatar)(() => { - return { height: '40px', width: '40px' }; -}); - -export const StyledMemberNameContainer = styled('div')(() => { - return { - display: 'flex', - alignItems: 'center', - width: '402px', - }; -}); - -export const StyledMemberRoleContainer = styled('div')(() => { - return { - display: 'flex', - alignItems: 'center', - width: '222px', - }; -}); - -export const StyledMemberListContainer = styled('ul')(() => { - return { - marginTop: '15px', - overflowY: 'scroll', - }; -}); - -export const StyledMemberListItem = styled('li')(() => { - return { - display: 'flex', - alignItems: 'center', - height: '72px', - }; -}); - -export const StyledMemberInfo = styled('div')(() => { - return { - paddingLeft: '12px', - }; -}); - -export const StyledMemberName = styled('div')(({ theme }) => { - return { - fontWeight: '400', - fontSize: '18px', - lineHeight: '16px', - color: theme.colors.textColor, - }; -}); - -export const StyledMemberEmail = styled('div')(({ theme }) => { - return { - fontWeight: '400', - fontSize: '16px', - lineHeight: '22px', - color: theme.colors.iconColor, - }; -}); - -export const StyledMemberButtonContainer = styled('div')(() => { - return { - marginTop: '14px', - }; -}); - -export const StyledMoreVerticalButton = styled('button')(() => { - return { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - width: '24px', - height: '24px', - cursor: 'pointer', - }; -}); - export const StyledPublishExplanation = styled('div')(() => { return { paddingRight: '48px', diff --git a/packages/app/src/hooks/use-members.ts b/packages/app/src/hooks/use-members.ts new file mode 100644 index 000000000..3011c94f8 --- /dev/null +++ b/packages/app/src/hooks/use-members.ts @@ -0,0 +1,51 @@ +import { useCallback, useEffect, useState } from 'react'; +import { Member } from '@affine/datacenter'; +import { useAppState } from '@/providers/app-state-provider'; +export const useMembers = () => { + const { dataCenter, currentWorkspace } = useAppState(); + const [members, setMembers] = useState([]); + const [loaded, setLoaded] = useState(false); + const refreshMembers = useCallback(async () => { + if (!currentWorkspace || !dataCenter) return; + const members = await dataCenter.getMembers(currentWorkspace.id); + setMembers(members); + }, [dataCenter, currentWorkspace]); + + useEffect(() => { + const init = async () => { + await refreshMembers(); + setLoaded(true); + }; + init(); + }, [refreshMembers]); + + const inviteMember = async (email: string) => { + currentWorkspace && + dataCenter && + (await dataCenter.inviteMember(currentWorkspace?.id, email)); + }; + + const removeMember = async (permissionId: number) => { + if (!currentWorkspace || !dataCenter) { + return; + } + setLoaded(false); + await dataCenter.removeMember(currentWorkspace.id, permissionId); + await refreshMembers(); + setLoaded(true); + }; + + const getUserByEmail = async (email: string) => { + if (!currentWorkspace) return null; + return dataCenter?.getUserByEmail(currentWorkspace.id, email); + }; + return { + members, + removeMember, + inviteMember, + getUserByEmail, + loaded, + }; +}; + +export default useMembers; diff --git a/packages/app/src/hooks/use-workspace-helper.ts b/packages/app/src/hooks/use-workspace-helper.ts index f67a3b152..397371e52 100644 --- a/packages/app/src/hooks/use-workspace-helper.ts +++ b/packages/app/src/hooks/use-workspace-helper.ts @@ -56,16 +56,10 @@ export const useWorkspaceHelper = () => { }); }; - const inviteMember = async (email: string) => { - currentWorkspace && - (await dataCenter.inviteMember(currentWorkspace?.id, email)); - }; - return { createWorkspace, publishWorkspace, updateWorkspace, enableWorkspace, - inviteMember, }; }; diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index 710bf8185..ef6c594b0 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -20,11 +20,9 @@ export const AppStateProvider = ({ children, }: PropsWithChildren) => { const [appState, setAppState] = useState({} as AppStateValue); - useEffect(() => { const initState = async () => { const dataCenter = await getDataCenter(); - // Ensure datacenter has at least one workspace if (dataCenter.workspaces.length === 0) { await createDefaultWorkspace(dataCenter); diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index fd199935f..591a83b14 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -26,7 +26,7 @@ const _initializeDataCenter = () => { export const getDataCenter = _initializeDataCenter(); export type { DataCenter }; -export type { AccessTokenMessage } from './provider/affine/apis'; +export * from './provider/affine/apis'; export { WorkspaceUnit } from './workspace-unit'; export { getLogger } from './logger'; export * from './message'; From 49eff042fe66cbc2e3c8aac287c370aebb199e97 Mon Sep 17 00:00:00 2001 From: MingLiang Wang Date: Wed, 11 Jan 2023 21:35:40 +0800 Subject: [PATCH 30/43] feat: add accept invite --- packages/data-center/src/datacenter.ts | 12 ++++++++++++ packages/data-center/src/provider/affine/affine.ts | 5 +++++ packages/data-center/src/provider/base.ts | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index c15861223..add13ec0e 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -438,6 +438,18 @@ export class DataCenter { return []; } + /** + * accept invitation + * @param {string} inviteCode + */ + async acceptInvitation(inviteCode: string, providerStr = 'affine') { + const provider = this.providerMap.get(providerStr); + if (provider) { + return await provider.acceptInvitation(inviteCode); + } + return []; + } + onMessage(cb: (message: Message) => void) { return this._messageCenter.onMessage(cb); } diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index 41b93b7dc..acc1ce0cf 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -99,6 +99,7 @@ export class AffineProvider extends BaseProvider { ws_details: Record; metadata: Record; }) { + this._logger('receive server message'); Object.entries(ws_details).forEach(([id, detail]) => { const { name, avatar } = metadata[id]; assert(name); @@ -442,4 +443,8 @@ export class AffineProvider extends BaseProvider { public override async getWorkspaceMembers(id: string) { return this._apis.getWorkspaceMembers({ id }); } + + public override async acceptInvitation(invitingCode: string): Promise { + await this._apis.acceptInviting({ invitingCode }); + } } diff --git a/packages/data-center/src/provider/base.ts b/packages/data-center/src/provider/base.ts index fed862681..11547c6a6 100644 --- a/packages/data-center/src/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -233,4 +233,14 @@ export class BaseProvider { workspaceId; return Promise.resolve([]); } + + /** + * accept invitation + * @param {string} inviteCode + * @returns + */ + public async acceptInvitation(inviteCode: string): Promise { + inviteCode; + return; + } } From 9d431dbc183723c5a5c2882d63a22d3efa95e115 Mon Sep 17 00:00:00 2001 From: DiamondThree <857159145@qq.com> Date: Wed, 11 Jan 2023 21:44:32 +0800 Subject: [PATCH 31/43] feat:add logout --- .../src/components/create-workspace/index.tsx | 3 +- .../src/components/workspace-modal/index.tsx | 28 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/app/src/components/create-workspace/index.tsx b/packages/app/src/components/create-workspace/index.tsx index e4645df8e..7b473afbf 100644 --- a/packages/app/src/components/create-workspace/index.tsx +++ b/packages/app/src/components/create-workspace/index.tsx @@ -7,6 +7,7 @@ import { KeyboardEvent } from 'react'; import { useTranslation } from '@affine/i18n'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; import { useRouter } from 'next/router'; +import { toast } from '@/ui/toast'; interface ModalProps { open: boolean; @@ -23,7 +24,7 @@ export const CreateWorkspaceModal = ({ open, onClose }: ModalProps) => { router.replace(`/workspace/${workspace.id}`); onClose(); } else { - console.log('create error'); + toast('create error'); } }; const handleKeyDown = (event: KeyboardEvent) => { diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx index 419654fde..4328224d8 100644 --- a/packages/app/src/components/workspace-modal/index.tsx +++ b/packages/app/src/components/workspace-modal/index.tsx @@ -2,7 +2,6 @@ import { styled } from '@/styles'; import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; import { useState } from 'react'; -import { SignOut } from '@/hooks/mock-data/mock'; import { CreateWorkspaceModal } from '../create-workspace'; import { CloudUnsyncedIcon, @@ -14,6 +13,7 @@ import { toast } from '@/ui/toast'; import { WorkspaceAvatar } from '@/components/workspace-avatar'; import { useAppState } from '@/providers/app-state-provider'; import { useRouter } from 'next/router'; +import { useConfirm } from '@/providers/ConfirmProvider'; interface WorkspaceModalProps { open: boolean; @@ -22,8 +22,9 @@ interface WorkspaceModalProps { export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => { const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false); - // const { confirm } = useConfirm(); - const { workspaceList, currentWorkspace, login, user } = useAppState(); + const { confirm } = useConfirm(); + const { workspaceList, currentWorkspace, login, user, logout } = + useAppState(); const router = useRouter(); return (
@@ -134,9 +135,9 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {