mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-11 23:26:30 +08:00
feat(infra): remove obsolete pattern (#11177)
React suspense is a deprecated mode, remove the useEnsureLiveData method
This commit is contained in:
@@ -10,4 +10,4 @@ export {
|
||||
onStart,
|
||||
smartRetry,
|
||||
} from './ops';
|
||||
export { useEnsureLiveData, useLiveData } from './react';
|
||||
export { useLiveData } from './react';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { use } from 'foxact/use';
|
||||
import { useSyncExternalStore } from 'react';
|
||||
|
||||
import type { LiveData } from './livedata';
|
||||
@@ -36,33 +35,3 @@ export function useLiveData<Input extends LiveData<any> | null | undefined>(
|
||||
: nullGetSnapshot
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribe LiveData and return the value. If the value is nullish, will suspends until the value is not nullish.
|
||||
*/
|
||||
export function useEnsureLiveData<T>(liveData$: LiveData<T>): NonNullable<T> {
|
||||
const data = useLiveData(liveData$);
|
||||
|
||||
if (data === null || data === undefined) {
|
||||
return use(
|
||||
new Promise<NonNullable<T>>((resolve, reject) => {
|
||||
const subscription = liveData$.subscribe({
|
||||
next(value) {
|
||||
if (value !== null && value !== undefined) {
|
||||
resolve(value as NonNullable<T>);
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
},
|
||||
error(err) {
|
||||
reject(err);
|
||||
},
|
||||
complete() {
|
||||
reject(new Error('Unexpected completion'));
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return data as NonNullable<T>;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,7 @@ import { SubscriptionPlan } from '@affine/graphql';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
import { ArrowRightSmallIcon, CameraIcon } from '@blocksuite/icons/rc';
|
||||
import {
|
||||
useEnsureLiveData,
|
||||
useLiveData,
|
||||
useService,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { useLiveData, useService, useServices } from '@toeverything/infra';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { AuthService, ServerService } from '../../../../modules/cloud';
|
||||
@@ -31,7 +26,7 @@ import * as styles from './style.css';
|
||||
export const UserAvatar = () => {
|
||||
const t = useI18n();
|
||||
const session = useService(AuthService).session;
|
||||
const account = useEnsureLiveData(session.account$);
|
||||
const account = useLiveData(session.account$);
|
||||
|
||||
const handleUpdateUserAvatar = useAsyncCallback(
|
||||
async (file: File) => {
|
||||
@@ -63,10 +58,10 @@ export const UserAvatar = () => {
|
||||
>
|
||||
<Avatar
|
||||
size={56}
|
||||
name={account.label}
|
||||
url={account.avatar}
|
||||
name={account?.label}
|
||||
url={account?.avatar}
|
||||
hoverIcon={<CameraIcon />}
|
||||
onRemove={account.avatar ? handleRemoveUserAvatar : undefined}
|
||||
onRemove={account?.avatar ? handleRemoveUserAvatar : undefined}
|
||||
avatarTooltipOptions={{ content: t['Click to replace photo']() }}
|
||||
removeTooltipOptions={{ content: t['Remove photo']() }}
|
||||
data-testid="user-setting-avatar"
|
||||
@@ -81,10 +76,10 @@ export const UserAvatar = () => {
|
||||
export const AvatarAndName = () => {
|
||||
const t = useI18n();
|
||||
const session = useService(AuthService).session;
|
||||
const account = useEnsureLiveData(session.account$);
|
||||
const [input, setInput] = useState<string>(account.label);
|
||||
const account = useLiveData(session.account$);
|
||||
const [input, setInput] = useState<string>(account?.label ?? '');
|
||||
|
||||
const allowUpdate = !!input && input !== account.label;
|
||||
const allowUpdate = !!input && input !== account?.label;
|
||||
const handleUpdateUserName = useAsyncCallback(async () => {
|
||||
if (account === null) {
|
||||
return;
|
||||
@@ -188,10 +183,13 @@ export const AccountSetting = ({
|
||||
useEffect(() => {
|
||||
session.revalidate();
|
||||
}, [session]);
|
||||
const account = useEnsureLiveData(session.account$);
|
||||
const account = useLiveData(session.account$);
|
||||
const openSignOutModal = useSignOut();
|
||||
|
||||
const onChangeEmail = useCallback(() => {
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
globalDialogService.open('verify-email', {
|
||||
server: serverService.server.baseUrl,
|
||||
changeEmail: !!account.info?.emailVerified,
|
||||
@@ -204,6 +202,10 @@ export const AccountSetting = ({
|
||||
});
|
||||
}, [globalDialogService, serverService.server.baseUrl]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingHeader
|
||||
|
||||
+6
-6
@@ -10,11 +10,7 @@ import { UserFriendlyError } from '@affine/error';
|
||||
import { Permission, WorkspaceMemberStatus } from '@affine/graphql';
|
||||
import { type I18nString, useI18n } from '@affine/i18n';
|
||||
import { MoreVerticalIcon } from '@blocksuite/icons/rc';
|
||||
import {
|
||||
useEnsureLiveData,
|
||||
useLiveData,
|
||||
useService,
|
||||
} from '@toeverything/infra';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import clsx from 'clsx';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
@@ -44,7 +40,7 @@ export const MemberList = ({
|
||||
}, [membersService]);
|
||||
|
||||
const session = useService(AuthService).session;
|
||||
const account = useEnsureLiveData(session.account$);
|
||||
const account = useLiveData(session.account$);
|
||||
|
||||
const handlePageChange = useCallback(
|
||||
(_: number, pageNum: number) => {
|
||||
@@ -54,6 +50,10 @@ export const MemberList = ({
|
||||
[membersService]
|
||||
);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{pageMembers === undefined ? (
|
||||
|
||||
@@ -3,11 +3,7 @@ import { useSignOut } from '@affine/core/components/hooks/affine/use-sign-out';
|
||||
import { AuthService } from '@affine/core/modules/cloud';
|
||||
import { GlobalDialogService } from '@affine/core/modules/dialogs';
|
||||
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
|
||||
import {
|
||||
useEnsureLiveData,
|
||||
useLiveData,
|
||||
useService,
|
||||
} from '@toeverything/infra';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { UserPlanTag } from '../../../components';
|
||||
@@ -52,7 +48,7 @@ const BaseLayout = ({
|
||||
|
||||
const AuthorizedUserProfile = () => {
|
||||
const session = useService(AuthService).session;
|
||||
const account = useEnsureLiveData(session.account$);
|
||||
const account = useLiveData(session.account$);
|
||||
const confirmSignOut = useSignOut();
|
||||
|
||||
return (
|
||||
@@ -61,14 +57,14 @@ const AuthorizedUserProfile = () => {
|
||||
<Avatar
|
||||
size={48}
|
||||
rounded={4}
|
||||
url={account.avatar}
|
||||
name={account.label}
|
||||
url={account?.avatar}
|
||||
name={account?.label}
|
||||
/>
|
||||
}
|
||||
caption={<span className={styles.emailInfo}>{account.email}</span>}
|
||||
caption={<span className={styles.emailInfo}>{account?.email}</span>}
|
||||
title={
|
||||
<div className={styles.nameWithTag}>
|
||||
<span className={styles.name}>{account.label}</span>
|
||||
<span className={styles.name}>{account?.label}</span>
|
||||
<UserPlanTag />
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user