mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
Merge pull request #829 from toeverything/fix/downhill-bugs
Fix/downhill bugs
This commit is contained in:
@@ -57,6 +57,8 @@ export const CreateWorkspaceModal = ({ open, onClose }: ModalProps) => {
|
||||
<Input
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder={t('Set a Workspace name')}
|
||||
maxLength={15}
|
||||
minLength={0}
|
||||
onChange={value => {
|
||||
setWorkspaceName(value);
|
||||
}}
|
||||
|
||||
@@ -63,7 +63,7 @@ export const EnableWorkspaceModal = ({
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t('Skip')}
|
||||
{t('Not now')}
|
||||
</StyleButton>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
@@ -1,15 +1,41 @@
|
||||
import { CloudUnsyncedIcon, CloudInsyncIcon } from '@blocksuite/icons';
|
||||
import { CloudUnsyncedIcon } from '@blocksuite/icons';
|
||||
import { useModal } from '@/providers/GlobalModalProvider';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
import { IconButton } from '@/ui/button';
|
||||
|
||||
// Temporary solution to use this component, since the @blocksuite/icons has not been published yet
|
||||
const DefaultSyncIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 13.6493C3 16.6044 5.41766 19 8.4 19L16.5 19C18.9853 19 21 16.9839 21 14.4969C21 12.6503 19.8893 10.9449 18.3 10.25C18.1317 7.32251 15.684 5 12.6893 5C10.3514 5 8.34694 6.48637 7.5 8.5C4.8 8.9375 3 11.2001 3 13.6493Z"
|
||||
stroke="#888A9E"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M11.4571 9L9 16H10.4392L12.0021 11.1586L13.5657 16H15L12.5425 9H11.4571Z"
|
||||
fill="#888A9E"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
export const SyncUser = () => {
|
||||
const { triggerLoginModal } = useModal();
|
||||
const appState = useAppState();
|
||||
|
||||
return appState.user ? (
|
||||
<IconButton iconSize="middle" disabled>
|
||||
<CloudInsyncIcon />
|
||||
<DefaultSyncIcon />
|
||||
</IconButton>
|
||||
) : (
|
||||
<IconButton
|
||||
|
||||
28
packages/app/src/components/login-modal/GoogleIcon.tsx
Normal file
28
packages/app/src/components/login-modal/GoogleIcon.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
export const GoogleIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M22.3055 10.0415H21.5V10H12.5V14H18.1515C17.327 16.3285 15.1115 18 12.5 18C9.1865 18 6.5 15.3135 6.5 12C6.5 8.6865 9.1865 6 12.5 6C14.0295 6 15.421 6.577 16.4805 7.5195L19.309 4.691C17.523 3.0265 15.134 2 12.5 2C6.9775 2 2.5 6.4775 2.5 12C2.5 17.5225 6.9775 22 12.5 22C18.0225 22 22.5 17.5225 22.5 12C22.5 11.3295 22.431 10.675 22.3055 10.0415Z"
|
||||
fill="#FFC107"
|
||||
/>
|
||||
<path
|
||||
d="M3.65234 7.3455L6.93784 9.755C7.82684 7.554 9.97984 6 12.4993 6C14.0288 6 15.4203 6.577 16.4798 7.5195L19.3083 4.691C17.5223 3.0265 15.1333 2 12.4993 2C8.65834 2 5.32734 4.1685 3.65234 7.3455Z"
|
||||
fill="#FF3D00"
|
||||
/>
|
||||
<path
|
||||
d="M12.5002 22.0003C15.0832 22.0003 17.4302 21.0118 19.2047 19.4043L16.1097 16.7853C15.0719 17.5745 13.8039 18.0014 12.5002 18.0003C9.89916 18.0003 7.69066 16.3418 6.85866 14.0273L3.59766 16.5398C5.25266 19.7783 8.61366 22.0003 12.5002 22.0003Z"
|
||||
fill="#4CAF50"
|
||||
/>
|
||||
<path
|
||||
d="M22.3055 10.0415H21.5V10H12.5V14H18.1515C17.7571 15.1082 17.0467 16.0766 16.108 16.7855L16.1095 16.7845L19.2045 19.4035C18.9855 19.6025 22.5 17 22.5 12C22.5 11.3295 22.431 10.675 22.3055 10.0415Z"
|
||||
fill="#1976D2"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
import { CloudUnsyncedIcon } from '@blocksuite/icons';
|
||||
import { styled } from '@/styles';
|
||||
import GoogleSvg from './google.svg';
|
||||
|
||||
export const GoogleIcon = () => {
|
||||
return (
|
||||
<GoogleIconWrapper>
|
||||
<picture>
|
||||
<img src={GoogleSvg.src} alt="Google" />
|
||||
</picture>
|
||||
</GoogleIconWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const GoogleIconWrapper = styled('div')(({ theme }) => ({
|
||||
background: theme.colors.pageBackground,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}));
|
||||
|
||||
export const StayLogOutIcon = () => {
|
||||
return (
|
||||
<StayLogOutWrapper>
|
||||
<CloudUnsyncedIcon />
|
||||
</StayLogOutWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const StayLogOutWrapper = styled('div')(({ theme }) => {
|
||||
return {
|
||||
width: '48px',
|
||||
height: '48px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontSize: '24px',
|
||||
background: theme.colors.hoverBackground,
|
||||
};
|
||||
});
|
||||
@@ -1,99 +0,0 @@
|
||||
import { styled } from '@/styles';
|
||||
import { Button } from '@/ui/button';
|
||||
import { GoogleIcon, StayLogOutIcon } from './Icons';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
export const GoogleLoginButton = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<StyledGoogleButton>
|
||||
<ButtonWrapper>
|
||||
<IconWrapper>
|
||||
<GoogleIcon />
|
||||
</IconWrapper>
|
||||
<TextWrapper>{t('Continue with Google')}</TextWrapper>
|
||||
</ButtonWrapper>
|
||||
</StyledGoogleButton>
|
||||
);
|
||||
};
|
||||
|
||||
export const StayLogOutButton = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<StyledStayLogOutButton>
|
||||
<ButtonWrapper>
|
||||
<IconWrapper>
|
||||
<StayLogOutIcon />
|
||||
</IconWrapper>
|
||||
<TextWrapper>
|
||||
<Title>{t('Stay logged out')}</Title>
|
||||
<Description>{t('All changes are saved locally')}</Description>
|
||||
</TextWrapper>
|
||||
</ButtonWrapper>
|
||||
</StyledStayLogOutButton>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledGoogleButton = styled('div')(({ theme }) => {
|
||||
return {
|
||||
width: '284px',
|
||||
height: '40px',
|
||||
marginTop: '30px',
|
||||
fontSize: '16px',
|
||||
cursor: 'pointer',
|
||||
borderRadius: '40px',
|
||||
border: `1px solid ${theme.colors.iconColor}`,
|
||||
overflow: 'hidden',
|
||||
':hover': {
|
||||
border: `1px solid ${theme.colors.primaryColor}`,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const StyledStayLogOutButton = styled(Button)(() => {
|
||||
return {
|
||||
width: '361px',
|
||||
height: '56px',
|
||||
padding: '4px',
|
||||
':hover': {
|
||||
borderColor: '#6880FF',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const ButtonWrapper = styled('div')({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
const IconWrapper = styled('div')({
|
||||
flex: '0 48px',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
marginRight: '12px',
|
||||
marginTop: '8px',
|
||||
});
|
||||
|
||||
const TextWrapper = styled('div')({
|
||||
flex: 1,
|
||||
textAlign: 'left',
|
||||
height: '40px',
|
||||
lineHeight: '40px',
|
||||
});
|
||||
|
||||
const Title = styled('h1')(() => {
|
||||
return {
|
||||
fontSize: '18px',
|
||||
lineHeight: '26px',
|
||||
fontWeight: 500,
|
||||
};
|
||||
});
|
||||
|
||||
const Description = styled('p')(() => {
|
||||
return {
|
||||
fontSize: '16px',
|
||||
lineHeight: '22px',
|
||||
fontWeight: 400,
|
||||
};
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.3055 10.0415H21.5V10H12.5V14H18.1515C17.327 16.3285 15.1115 18 12.5 18C9.1865 18 6.5 15.3135 6.5 12C6.5 8.6865 9.1865 6 12.5 6C14.0295 6 15.421 6.577 16.4805 7.5195L19.309 4.691C17.523 3.0265 15.134 2 12.5 2C6.9775 2 2.5 6.4775 2.5 12C2.5 17.5225 6.9775 22 12.5 22C18.0225 22 22.5 17.5225 22.5 12C22.5 11.3295 22.431 10.675 22.3055 10.0415Z" fill="#FFC107"/>
|
||||
<path d="M3.65234 7.3455L6.93784 9.755C7.82684 7.554 9.97984 6 12.4993 6C14.0288 6 15.4203 6.577 16.4798 7.5195L19.3083 4.691C17.5223 3.0265 15.1333 2 12.4993 2C8.65834 2 5.32734 4.1685 3.65234 7.3455Z" fill="#FF3D00"/>
|
||||
<path d="M12.5002 22.0003C15.0832 22.0003 17.4302 21.0118 19.2047 19.4043L16.1097 16.7853C15.0719 17.5745 13.8039 18.0014 12.5002 18.0003C9.89916 18.0003 7.69066 16.3418 6.85866 14.0273L3.59766 16.5398C5.25266 19.7783 8.61366 22.0003 12.5002 22.0003Z" fill="#4CAF50"/>
|
||||
<path d="M22.3055 10.0415H21.5V10H12.5V14H18.1515C17.7571 15.1082 17.0467 16.0766 16.108 16.7855L16.1095 16.7845L19.2045 19.4035C18.9855 19.6025 22.5 17 22.5 12C22.5 11.3295 22.431 10.675 22.3055 10.0415Z" fill="#1976D2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,8 +1,9 @@
|
||||
import { styled } from '@/styles';
|
||||
import { positionAbsolute, styled } from '@/styles';
|
||||
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
|
||||
import { GoogleLoginButton } from './LoginOptionButton';
|
||||
import { Button } from '@/ui/button';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { GoogleIcon } from './GoogleIcon';
|
||||
interface LoginModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
@@ -13,34 +14,41 @@ export const LoginModal = ({ open, onClose }: LoginModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Modal open={open} onClose={onClose} data-testid="login-modal">
|
||||
<ModalWrapper width={560} height={292}>
|
||||
<Header>
|
||||
<ModalCloseButton
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
</Header>
|
||||
<ModalWrapper width={560} height={292} style={{ paddingTop: '44px' }}>
|
||||
<ModalCloseButton
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
<Content>
|
||||
<ContentTitle>{t('Sign in')}</ContentTitle>
|
||||
<SignDes>{t('Set up an AFFiNE account to sync data')}</SignDes>
|
||||
<span
|
||||
<StyledLoginButton
|
||||
shape="round"
|
||||
onClick={async () => {
|
||||
await login();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
<GoogleLoginButton />
|
||||
</span>
|
||||
<GoogleIcon />
|
||||
{t('Continue with Google')}
|
||||
</StyledLoginButton>
|
||||
</Content>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const Header = styled('div')({
|
||||
position: 'relative',
|
||||
height: '44px',
|
||||
const StyledLoginButton = styled(Button)(() => {
|
||||
return {
|
||||
width: '284px',
|
||||
marginTop: '30px',
|
||||
position: 'relative',
|
||||
svg: {
|
||||
...positionAbsolute({ left: '18px', top: '0', bottom: '0' }),
|
||||
margin: 'auto',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const Content = styled('div')({
|
||||
|
||||
@@ -3,9 +3,9 @@ import { FlexWrapper } from '@/ui/layout';
|
||||
import { WorkspaceAvatar } from '@/components/workspace-avatar';
|
||||
import { IconButton } from '@/ui/button';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
import { StyledFooter, StyleUserInfo, StyleSignIn } from './styles';
|
||||
import { StyledFooter, StyleUserInfo, StyledSignInButton } from './styles';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
|
||||
import { Tooltip } from '@/ui/tooltip';
|
||||
export const Footer = ({
|
||||
onLogin,
|
||||
onLogout,
|
||||
@@ -31,27 +31,33 @@ export const Footer = ({
|
||||
<p>{user.email}</p>
|
||||
</StyleUserInfo>
|
||||
</FlexWrapper>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
onLogout();
|
||||
}}
|
||||
>
|
||||
<LogOutIcon />
|
||||
</IconButton>
|
||||
<Tooltip content={t('Sign out')} disablePortal={true}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
onLogout();
|
||||
}}
|
||||
>
|
||||
<LogOutIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
)}
|
||||
|
||||
{!user && (
|
||||
<StyleSignIn
|
||||
<StyledSignInButton
|
||||
noBorder
|
||||
bold
|
||||
icon={
|
||||
<div className="circle">
|
||||
<CloudInsyncIcon fontSize={16} />
|
||||
</div>
|
||||
}
|
||||
onClick={async () => {
|
||||
onLogin();
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
<CloudInsyncIcon fontSize={16} />
|
||||
</span>
|
||||
{t('Sign in')}
|
||||
</StyleSignIn>
|
||||
</StyledSignInButton>
|
||||
)}
|
||||
</StyledFooter>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { displayFlex, styled } from '@/styles';
|
||||
import { displayFlex, displayInlineFlex, styled, textEllipsis } from '@/styles';
|
||||
import { Button } from '@/ui/button';
|
||||
|
||||
export const StyledSplitLine = styled.div(({ theme }) => {
|
||||
return {
|
||||
@@ -29,6 +30,8 @@ export const StyleWorkspaceTitle = styled.div(({ theme }) => {
|
||||
fontWeight: 600,
|
||||
lineHeight: '24px',
|
||||
marginBottom: '10px',
|
||||
maxWidth: '200px',
|
||||
...textEllipsis(1),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -80,28 +83,6 @@ export const StyleUserInfo = styled.div(({ theme }) => {
|
||||
};
|
||||
});
|
||||
|
||||
export const StyleSignIn = styled.div(({ theme }) => {
|
||||
return {
|
||||
cursor: 'pointer',
|
||||
fontSize: '16px',
|
||||
fontWeight: 700,
|
||||
color: theme.colors.iconColor,
|
||||
span: {
|
||||
display: 'inline-block',
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
borderRadius: '40px',
|
||||
backgroundColor: theme.colors.innerHoverBackground,
|
||||
textAlign: 'center',
|
||||
lineHeight: '44px',
|
||||
marginRight: '16px',
|
||||
svg: {
|
||||
fill: theme.colors.primaryColor,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledModalHeaderLeft = styled.div(() => {
|
||||
return { ...displayFlex('flex-start', 'center') };
|
||||
});
|
||||
@@ -160,3 +141,19 @@ export const StyledModalHeader = styled('div')(({ theme }) => {
|
||||
...displayFlex('space-between', 'center'),
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSignInButton = styled(Button)(({ theme }) => {
|
||||
return {
|
||||
fontWeight: 700,
|
||||
paddingLeft: 0,
|
||||
'.circle': {
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
borderRadius: '20px',
|
||||
backgroundColor: theme.colors.innerHoverBackground,
|
||||
flexShrink: 0,
|
||||
marginRight: '16px',
|
||||
...displayInlineFlex('center', 'center'),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -85,8 +85,8 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||
height={32}
|
||||
value={workspaceName}
|
||||
placeholder={t('Workspace Name')}
|
||||
maxLength={14}
|
||||
minLength={1}
|
||||
maxLength={15}
|
||||
minLength={0}
|
||||
disabled={!isOwner}
|
||||
onChange={handleChangeWorkSpaceName}
|
||||
></StyledInput>
|
||||
|
||||
@@ -145,6 +145,7 @@ export const StyledButton = styled('button', {
|
||||
shouldForwardProp: prop => {
|
||||
return ![
|
||||
'hoverBackground',
|
||||
'shape',
|
||||
'hoverColor',
|
||||
'hoverStyle',
|
||||
'type',
|
||||
@@ -203,6 +204,9 @@ export const StyledButton = styled('button', {
|
||||
'.affine-button-icon': {
|
||||
color: theme.colors.iconColor,
|
||||
},
|
||||
'.affine-button-icon__fixed': {
|
||||
color: theme.colors.iconColor,
|
||||
},
|
||||
'>span': {
|
||||
marginLeft: '5px',
|
||||
width: '100%',
|
||||
|
||||
@@ -38,8 +38,9 @@ export const Input = (props: inputProps) => {
|
||||
if (
|
||||
(maxLength && e.target.value.length > maxLength) ||
|
||||
(minLength && e.target.value.length < minLength)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setValue(e.target.value);
|
||||
onChange && onChange(e.target.value);
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
"Enable AFFiNE Cloud Description": "If enabled, the data in this workspace will be backed up and synchronised via AFFiNE Cloud.",
|
||||
"Enable": "Enable",
|
||||
"Sign in and Enable": "Sign in and Enable",
|
||||
"Skip": "Skip",
|
||||
"Not now": "Not now",
|
||||
"Publishing": "Publishing to web requires AFFiNE Cloud service.",
|
||||
"Share with link": "Share with link",
|
||||
"Copy Link": "Copy Link",
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
"Enable AFFiNE Cloud Description": "如启用,此工作区中的数据将通过AFFiNE Cloud进行备份和同步。",
|
||||
"Enable": "启动",
|
||||
"Sign in and Enable": "登录并启用",
|
||||
"Skip": "跳过",
|
||||
"Not now": "下次再说",
|
||||
"Publishing": "发布到web需要AFFiNE云服务。",
|
||||
"Share with link": "通过链接分享",
|
||||
"Copy Link": "复制链接",
|
||||
|
||||
Reference in New Issue
Block a user