feat(infra): remove obsolete pattern (#11177)

React suspense is a deprecated mode, remove the useEnsureLiveData method
This commit is contained in:
EYHN
2025-03-25 13:20:17 +00:00
parent ad4e1ed7de
commit d7567edcb8
5 changed files with 29 additions and 62 deletions
+1 -1
View File
@@ -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
@@ -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>
}