feat!: affine cloud support (#3813)
Co-authored-by: Hongtao Lye <codert.sn@gmail.com> Co-authored-by: liuyi <forehalo@gmail.com> Co-authored-by: LongYinan <lynweklm@gmail.com> Co-authored-by: X1a0t <405028157@qq.com> Co-authored-by: JimmFly <yangjinfei001@gmail.com> Co-authored-by: Peng Xiao <pengxiao@outlook.com> Co-authored-by: xiaodong zuo <53252747+zuoxiaodong0815@users.noreply.github.com> Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> Co-authored-by: Qi <474021214@qq.com> Co-authored-by: danielchim <kahungchim@gmail.com>
This commit is contained in:
53
apps/core/src/components/cloud/login-card.tsx
Normal file
53
apps/core/src/components/cloud/login-card.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { UserAvatar } from '@affine/component/user-avatar';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloudWorkspaceIcon } from '@blocksuite/icons';
|
||||
import { signIn } from 'next-auth/react';
|
||||
|
||||
import { useCurrenLoginStatus } from '../../hooks/affine/use-curren-login-status';
|
||||
import { useCurrentUser } from '../../hooks/affine/use-current-user';
|
||||
import { StyledSignInButton } from '../pure/footer/styles';
|
||||
|
||||
export const LoginCard = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
const loginStatus = useCurrenLoginStatus();
|
||||
if (loginStatus === 'authenticated') {
|
||||
return <UserCard />;
|
||||
}
|
||||
return (
|
||||
<StyledSignInButton
|
||||
data-testid="sign-in-button"
|
||||
onClick={async () => {
|
||||
// jump to login page
|
||||
signIn().catch(console.error);
|
||||
}}
|
||||
>
|
||||
<div className="circle">
|
||||
<CloudWorkspaceIcon />
|
||||
</div>{' '}
|
||||
{t['Sign in']()}
|
||||
</StyledSignInButton>
|
||||
);
|
||||
};
|
||||
|
||||
const UserCard = () => {
|
||||
const user = useCurrentUser();
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<UserAvatar
|
||||
size={28}
|
||||
name={user.name}
|
||||
url={user.image}
|
||||
className="avatar"
|
||||
/>
|
||||
<div style={{ marginLeft: '15px' }}>
|
||||
<div>{user.name}</div>
|
||||
<div>{user.email}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
58
apps/core/src/components/cloud/provider.tsx
Normal file
58
apps/core/src/components/cloud/provider.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import { pushNotificationAtom } from '@affine/component/notification-center';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import { SWRConfig } from 'swr';
|
||||
|
||||
const cloudConfig: SWRConfiguration = {
|
||||
suspense: true,
|
||||
use: [
|
||||
useSWRNext => (key, fetcher, config) => {
|
||||
const pushNotification = useSetAtom(pushNotificationAtom);
|
||||
const fetcherWrapper = useCallback(
|
||||
async (...args: any[]) => {
|
||||
assertExists(fetcher);
|
||||
const d = fetcher(...args);
|
||||
if (d instanceof Promise) {
|
||||
return d.catch(e => {
|
||||
if (
|
||||
e instanceof GraphQLError ||
|
||||
(Array.isArray(e) && e[0] instanceof GraphQLError)
|
||||
) {
|
||||
const graphQLError = e instanceof GraphQLError ? e : e[0];
|
||||
pushNotification({
|
||||
title: 'GraphQL Error',
|
||||
message: graphQLError.toString(),
|
||||
key: Date.now().toString(),
|
||||
type: 'error',
|
||||
});
|
||||
} else {
|
||||
pushNotification({
|
||||
title: 'Error',
|
||||
message: e.toString(),
|
||||
key: Date.now().toString(),
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
return d;
|
||||
},
|
||||
[fetcher, pushNotification]
|
||||
);
|
||||
return useSWRNext(key, fetcher ? fetcherWrapper : fetcher, config);
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const Provider = (props: PropsWithChildren): ReactElement => {
|
||||
if (!runtimeConfig.enableCloud) {
|
||||
return <>{props.children}</>;
|
||||
}
|
||||
|
||||
return <SWRConfig value={cloudConfig}>{props.children}</SWRConfig>;
|
||||
};
|
||||
Reference in New Issue
Block a user