feat: mock sync

This commit is contained in:
DiamondThree
2023-01-06 14:26:18 +08:00
parent 7bbf1d28ea
commit e7564b2e71
7 changed files with 156 additions and 109 deletions
@@ -8,7 +8,6 @@ import {
setActiveWorkspace, setActiveWorkspace,
Login, Login,
User, User,
getUserInfo,
SignOut, SignOut,
updateWorkspaceMeta, updateWorkspaceMeta,
} from '@/hooks/mock-data/mock'; } from '@/hooks/mock-data/mock';
@@ -22,6 +21,7 @@ import {
import { useConfirm } from '@/providers/confirm-provider'; import { useConfirm } from '@/providers/confirm-provider';
import { toast } from '@/ui/toast'; import { toast } from '@/ui/toast';
import { WorkspaceAvatar } from '@/components/workspace-avatar'; import { WorkspaceAvatar } from '@/components/workspace-avatar';
import useTemporaryHelper from '@/hooks/use-temporary-helper';
interface LoginModalProps { interface LoginModalProps {
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
@@ -29,23 +29,17 @@ interface LoginModalProps {
export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => { export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
const [workspaceList, setWorkspaceList] = useState<Workspace[]>([]); const [workspaceList, setWorkspaceList] = useState<Workspace[]>([]);
const [user, setUser] = useState<User | null>();
const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false); const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false);
const { confirm } = useConfirm(); const { confirm } = useConfirm();
const { user, login } = useTemporaryHelper();
useEffect(() => { useEffect(() => {
setList(); setList();
setUserInfo();
}, []); }, []);
const setList = () => { const setList = () => {
const data = getWorkspaces(); const data = getWorkspaces();
console.log('data: ', data);
setWorkspaceList(data); setWorkspaceList(data);
}; };
const setUserInfo = () => {
const data = getUserInfo();
setUser(data);
};
return ( return (
<div> <div>
@@ -151,9 +145,8 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
{!user ? ( {!user ? (
<Button <Button
onClick={() => { onClick={() => {
Login(); login();
toast('login success'); toast('login success');
setUserInfo();
}} }}
> >
Sign in AFFiNE Cloud Sign in AFFiNE Cloud
@@ -162,7 +155,6 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
<Button <Button
onClick={() => { onClick={() => {
SignOut(); SignOut();
setUserInfo();
}} }}
> >
Sign out of AFFiNE Cloud Sign out of AFFiNE Cloud
@@ -14,20 +14,22 @@ import { Button } from '@/ui/button';
import { getDataCenter } from '@affine/datacenter'; import { getDataCenter } from '@affine/datacenter';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useAppState } from '@/providers/app-state-provider'; import { useAppState } from '@/providers/app-state-provider';
import { deleteWorkspace, getWorkspaces } from '@/hooks/mock-data/mock'; import {
deleteWorkspace,
getWorkspaces,
Workspace,
} from '@/hooks/mock-data/mock';
interface WorkspaceDeleteProps { interface WorkspaceDeleteProps {
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
workspaceName: string; workspace: Workspace;
workspaceId: string;
} }
export const WorkspaceDelete = ({ export const WorkspaceDelete = ({
open, open,
onClose, onClose,
workspaceId, workspace,
workspaceName,
}: WorkspaceDeleteProps) => { }: WorkspaceDeleteProps) => {
const [deleteStr, setDeleteStr] = useState<string>(''); const [deleteStr, setDeleteStr] = useState<string>('');
const router = useRouter(); const router = useRouter();
@@ -40,7 +42,7 @@ export const WorkspaceDelete = ({
// const dc = await getDataCenter(); // const dc = await getDataCenter();
// await dc.apis.deleteWorkspace({ id: workspaceId }); // await dc.apis.deleteWorkspace({ id: workspaceId });
// router.push(`/workspace/${nextWorkSpaceId}`); // router.push(`/workspace/${nextWorkSpaceId}`);
deleteWorkspace(workspaceId); deleteWorkspace(workspace.id);
const workspaceList = getWorkspaces(); const workspaceList = getWorkspaces();
if (workspaceList.length) { if (workspaceList.length) {
router.push(`/workspace/${workspaceList[0].id}`); router.push(`/workspace/${workspaceList[0].id}`);
@@ -55,11 +57,20 @@ export const WorkspaceDelete = ({
<StyledModalWrapper> <StyledModalWrapper>
<ModalCloseButton onClick={onClose} /> <ModalCloseButton onClick={onClose} />
<StyledModalHeader>Delete Workspace</StyledModalHeader> <StyledModalHeader>Delete Workspace</StyledModalHeader>
<StyledTextContent> {workspace.type === 'local' ? (
This action cannot be undone. This will permanently delete ( <StyledTextContent>
<StyledWorkspaceName>{workspaceName}</StyledWorkspaceName>) along with Deleting (
all its content. <StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) cannot
</StyledTextContent> be undone, please proceed with caution. along with all its content.
</StyledTextContent>
) : (
<StyledTextContent>
Deleting (
<StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) will
delete both local and cloud data, this operation cannot be undone,
please proceed with caution.
</StyledTextContent>
)}
<StyledInputContent> <StyledInputContent>
<Input <Input
onChange={handlerInputChange} onChange={handlerInputChange}
@@ -16,7 +16,8 @@ export const StyledModalHeader = styled('div')(({ theme }) => {
width: '460px', width: '460px',
fontWeight: '600', fontWeight: '600',
fontSize: '20px;', fontSize: '20px;',
textAlign: 'center', textAlign: 'left',
paddingLeft: '20px',
color: theme.colors.popoverColor, color: theme.colors.popoverColor,
}; };
}); });
@@ -32,7 +33,7 @@ export const StyledTextContent = styled('div')(() => {
fontWeight: '400', fontWeight: '400',
fontSize: '18px', fontSize: '18px',
lineHeight: '26px', lineHeight: '26px',
textAlign: 'center', textAlign: 'left',
}; };
}); });
@@ -41,7 +42,7 @@ export const StyledInputContent = styled('div')(() => {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',
margin: '40px 0 24px 0', margin: '20px 0 24px 0',
}; };
}); });
@@ -77,11 +77,8 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
return workspace ? ( return workspace ? (
<div> <div>
<StyledSettingH2 marginTop={56}>Workspace Avatar</StyledSettingH2> <StyledSettingH2 marginTop={56}>Workspace Icon</StyledSettingH2>
<StyledSettingAvatarContent> <StyledSettingAvatarContent>
{/* <StyledSettingAvatar alt="workspace avatar" src={''}>
AFFiNE
</StyledSettingAvatar> */}
<div <div
style={{ style={{
float: 'left', float: 'left',
@@ -98,10 +95,6 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
<Button loading={uploading}>Upload</Button> <Button loading={uploading}>Upload</Button>
</Upload> </Upload>
{/* TODO: add upload logic */} {/* TODO: add upload logic */}
{/* {isOwner ? (
<StyledAvatarUploadBtn shape="round">upload</StyledAvatarUploadBtn>
) : null} */}
{/* <Button shape="round">remove</Button> */}
</StyledSettingAvatarContent> </StyledSettingAvatarContent>
<StyledSettingH2 marginTop={20}>Workspace Name</StyledSettingH2> <StyledSettingH2 marginTop={20}>Workspace Name</StyledSettingH2>
<StyledSettingInputContainer> <StyledSettingInputContainer>
@@ -122,7 +115,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
</TextButton> </TextButton>
</StyledSettingInputContainer> </StyledSettingInputContainer>
{userInfo ? ( {/* {userInfo ? (
<div> <div>
<StyledSettingH2 marginTop={20}>Workspace Owner</StyledSettingH2> <StyledSettingH2 marginTop={20}>Workspace Owner</StyledSettingH2>
<StyledSettingInputContainer> <StyledSettingInputContainer>
@@ -136,7 +129,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
</div> </div>
) : ( ) : (
'' ''
)} )} */}
<StyledSettingH2 marginTop={20}>Workspace Type</StyledSettingH2> <StyledSettingH2 marginTop={20}>Workspace Type</StyledSettingH2>
<StyledSettingInputContainer> <StyledSettingInputContainer>
@@ -151,8 +144,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
<WorkspaceDelete <WorkspaceDelete
open={showDelete} open={showDelete}
onClose={handleCloseDelete} onClose={handleCloseDelete}
workspaceName={workspaceName} workspace={workspace}
workspaceId={workspace.id}
/> />
</> </>
) : ( ) : (
@@ -199,11 +199,12 @@ export const StyledMoreVerticalButton = styled('button')(() => {
export const StyledPublishExplanation = styled('div')(() => { export const StyledPublishExplanation = styled('div')(() => {
return { return {
marginTop: '56px',
paddingRight: '48px', paddingRight: '48px',
fontWeight: '500', fontWeight: '500',
fontSize: '18px', fontSize: '18px',
lineHeight: '26px', lineHeight: '26px',
flex: 1,
marginTop: '60px',
}; };
}); });
@@ -213,7 +214,9 @@ export const StyledPublishCopyContainer = styled('div')(() => {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
height: '38px', height: '38px',
paddingTop: '20px',
}; };
}); });
@@ -226,5 +229,7 @@ export const StyledCopyButtonContainer = styled('div')(() => {
export const StyledPublishContent = styled('div')(() => { export const StyledPublishContent = styled('div')(() => {
return { return {
height: '494px', height: '494px',
display: 'flex',
flexDirection: 'column',
}; };
}); });
@@ -56,6 +56,8 @@ import {
User, User,
Workspace, Workspace,
} from '@/hooks/mock-data/mock'; } from '@/hooks/mock-data/mock';
import useTemporaryHelper from '@/hooks/use-temporary-helper';
import { useConfirm } from '@/providers/confirm-provider';
enum ActiveTab { enum ActiveTab {
'general' = 'general', 'general' = 'general',
@@ -364,66 +366,108 @@ const MembersPage = ({ workspace }: { workspace: Workspace }) => {
const PublishPage = ({ workspace }: { workspace: Workspace }) => { const PublishPage = ({ workspace }: { workspace: Workspace }) => {
const shareUrl = const shareUrl =
window.location.host + '/workspace/' + workspace.id + '?share=true'; window.location.host + '/workspace/' + workspace.id + '?share=true';
const [publicStatus, setPublicStatus] = useState<boolean | null>(
workspace.isPublish ?? false const { login, updateWorkspaceMeta, user, currentWorkspace } =
); useTemporaryHelper();
const { confirm } = useConfirm();
const togglePublic = (flag: boolean) => { const togglePublic = (flag: boolean) => {
const isPublic = setWorkspacePublish(workspace.id, flag); updateWorkspaceMeta(currentWorkspace.id, { isPublish: flag });
setPublicStatus(isPublic);
}; };
const copyUrl = () => { const copyUrl = () => {
navigator.clipboard.writeText(shareUrl); navigator.clipboard.writeText(shareUrl);
toast('Copied url to clipboard'); 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: user ? 'Enable' : 'Sign in and Enable',
cancelText: 'Skip',
}).then(confirm => {
if (user) {
updateWorkspaceMeta(currentWorkspace.id, { isPublish: true });
} else {
confirm && login();
updateWorkspaceMeta(currentWorkspace.id, { isPublish: true });
}
});
};
return ( return (
<div> <>
<StyledPublishContent> {user ? (
{publicStatus ? ( <div>
<StyledPublishContent>
{currentWorkspace?.isPublish ? (
<>
<StyledPublishExplanation>
Publishing to web requires AFFiNE Cloud service .
</StyledPublishExplanation>
<StyledSettingH2 marginTop={48}>
Share with link
</StyledSettingH2>
<StyledPublishCopyContainer>
<Input width={500} value={shareUrl} disabled={true}></Input>
<StyledCopyButtonContainer>
<Button onClick={copyUrl} type="primary" shape="circle">
Copy Link
</Button>
</StyledCopyButtonContainer>
</StyledPublishCopyContainer>
</>
) : (
<StyledPublishExplanation>
After publishing to the web, everyone can view the content of
this workspace through the link.
</StyledPublishExplanation>
)}
</StyledPublishContent>
{!currentWorkspace?.isPublish ? (
<Button
onClick={() => {
togglePublic(true);
}}
type="primary"
shape="circle"
>
Publish to web
</Button>
) : (
<Button
onClick={() => {
togglePublic(false);
}}
type="primary"
shape="circle"
>
Stop publishing
</Button>
)}
</div>
) : (
<StyledPublishContent>
<> <>
<StyledPublishExplanation> <StyledPublishExplanation>
The current workspace has been published to the web, everyone can Publishing to web requires AFFiNE Cloud service.
view the contents of this workspace through the link.
</StyledPublishExplanation> </StyledPublishExplanation>
<StyledSettingH2 marginTop={48}>Share with link</StyledSettingH2>
<StyledPublishCopyContainer> <StyledPublishCopyContainer>
<Input width={500} value={shareUrl} disabled={true}></Input> <Button
<StyledCopyButtonContainer> onClick={() => {
<Button onClick={copyUrl} type="primary" shape="circle"> enableAffineCloud();
Copy Link }}
</Button> type="primary"
</StyledCopyButtonContainer> shape="circle"
>
Enable AFFiNE Cloud
</Button>
</StyledPublishCopyContainer> </StyledPublishCopyContainer>
</> </>
) : ( </StyledPublishContent>
<StyledPublishExplanation>
After publishing to the web, everyone can view the content of this
workspace through the link.
</StyledPublishExplanation>
)}
</StyledPublishContent>
{!publicStatus ? (
<Button
onClick={() => {
togglePublic(true);
}}
type="primary"
shape="circle"
>
Publish to web
</Button>
) : (
<Button
onClick={() => {
togglePublic(false);
}}
type="primary"
shape="circle"
>
Stop publishing
</Button>
)} )}
</div> </>
); );
}; };
const SyncPage = ({ workspace }: { workspace: Workspace }) => { const SyncPage = ({ workspace }: { workspace: Workspace }) => {
@@ -433,7 +477,6 @@ const SyncPage = ({ workspace }: { workspace: Workspace }) => {
}); });
const setType = () => { const setType = () => {
const ACTIVEworkspace = getActiveWorkspace(); const ACTIVEworkspace = getActiveWorkspace();
console.log('ACTIVEworkspace: ', ACTIVEworkspace);
ACTIVEworkspace && setWorkspaceType(ACTIVEworkspace.type); ACTIVEworkspace && setWorkspaceType(ACTIVEworkspace.type);
}; };
return ( return (
@@ -448,27 +491,27 @@ const SyncPage = ({ workspace }: { workspace: Workspace }) => {
</StyledPublishExplanation> </StyledPublishExplanation>
<StyledPublishCopyContainer> <StyledPublishCopyContainer>
<StyledCopyButtonContainer> <Button
<Button onClick={() => {
onClick={() => { updateWorkspaceMeta(workspace.id, {
updateWorkspaceMeta(workspace.id, { type: 'cloud',
type: 'cloud', });
}); setType();
setType(); }}
}} type="primary"
type="primary" shape="circle"
shape="circle" >
> Enable AFFiNE Cloud
Enable AFFiNE Cloud </Button>
</Button>
</StyledCopyButtonContainer>
</StyledPublishCopyContainer> </StyledPublishCopyContainer>
</> </>
) : ( ) : (
<StyledPublishExplanation> <>
<code>{workspace.name}</code> is Cloud Workspace. All data will be <StyledPublishExplanation>
synchronized and saved to the AFFiNE account <code>{workspace.name}</code> is Cloud Workspace. All data will be
<div> synchronized and saved to the AFFiNE
</StyledPublishExplanation>
<StyledPublishCopyContainer>
<Menu <Menu
content={ content={
<> <>
@@ -495,8 +538,8 @@ const SyncPage = ({ workspace }: { workspace: Workspace }) => {
> >
<Button>Download all data to device</Button> <Button>Download all data to device</Button>
</Menu> </Menu>
</div> </StyledPublishCopyContainer>
</StyledPublishExplanation> </>
)} )}
</StyledPublishContent> </StyledPublishContent>
</div> </div>
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'; import { useState } from 'react';
import { getWorkspaces, Workspace, User } from './mock-data/mock'; import { getWorkspaces, Workspace, User } from './mock-data/mock';
export function getActiveWorkspace(): Workspace { export function getActiveWorkspace(): Workspace {
@@ -12,16 +12,19 @@ export const useTemporaryHelper = () => {
const [currentWorkspace, setCurrentWorkspace] = useState<Workspace>( const [currentWorkspace, setCurrentWorkspace] = useState<Workspace>(
JSON.parse(localStorage.getItem('affine-active-workspace') ?? '{}') JSON.parse(localStorage.getItem('affine-active-workspace') ?? '{}')
); );
const [user, setUser] = useState<User | null>(null); const [user, setUser] = useState<User | null>();
return { return {
updateWorkspaceMeta: (workspaceId: string, workspaceData: Workspace) => { updateWorkspaceMeta: (
workspaceId: string,
workspaceData: { name?: string; avatar?: string; isPublish?: boolean }
) => {
const workspacesMeta = getWorkspaces(); const workspacesMeta = getWorkspaces();
const newWorkspacesMeta = workspacesMeta.map((workspace: Workspace) => { const newWorkspacesMeta = workspacesMeta.map((workspace: Workspace) => {
if (workspace.id === workspaceId) { if (workspace.id === workspaceId) {
workspaceData.name && (workspace.name = workspaceData.name); workspaceData.name && (workspace.name = workspaceData.name);
workspaceData.avatar && (workspace.avatar = workspaceData.avatar); workspaceData.avatar && (workspace.avatar = workspaceData.avatar);
return workspaceData; return workspace;
} }
return workspace; return workspace;
}); });
@@ -94,7 +97,7 @@ export const useTemporaryHelper = () => {
avatar: 'string', avatar: 'string',
}; };
localStorage.setItem('affine-user', JSON.stringify(userInfo)); localStorage.setItem('affine-user', JSON.stringify(userInfo));
console.log('login');
setUser(userInfo); setUser(userInfo);
}, },
getUserInfo: () => { getUserInfo: () => {