fix(core): multiple settings dialog should not appear when click user plan button repeatedly (#8924)

This commit is contained in:
JimmFly
2024-11-26 05:49:12 +00:00
parent 31c806ef7e
commit e12d5f8750
5 changed files with 48 additions and 18 deletions
@@ -1,10 +1,8 @@
import { Tooltip } from '@affine/component/ui/tooltip'; import { Tooltip } from '@affine/component/ui/tooltip';
import { useCatchEventCallback } from '@affine/core/components/hooks/use-catch-event-hook';
import { GlobalDialogService } from '@affine/core/modules/dialogs';
import { SubscriptionPlan } from '@affine/graphql'; import { SubscriptionPlan } from '@affine/graphql';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { useLiveData, useService, useServices } from '@toeverything/infra'; import { useLiveData, useServices } from '@toeverything/infra';
import { useEffect } from 'react'; import { type SyntheticEvent, useEffect } from 'react';
import { import {
ServerConfigService, ServerConfigService,
@@ -12,7 +10,11 @@ import {
} from '../../../modules/cloud'; } from '../../../modules/cloud';
import * as styles from './style.css'; import * as styles from './style.css';
export const UserPlanButton = () => { export const UserPlanButton = ({
onClick,
}: {
onClick: (e: SyntheticEvent<Element, Event>) => void;
}) => {
const { serverConfigService, subscriptionService } = useServices({ const { serverConfigService, subscriptionService } = useServices({
ServerConfigService, ServerConfigService,
SubscriptionService, SubscriptionService,
@@ -34,14 +36,6 @@ export const UserPlanButton = () => {
subscriptionService.subscription.revalidate(); subscriptionService.subscription.revalidate();
}, [subscriptionService]); }, [subscriptionService]);
const globalDialogService = useService(GlobalDialogService);
const handleClick = useCatchEventCallback(() => {
globalDialogService.open('setting', {
activeTab: 'plans',
scrollAnchor: 'cloudPricingPlan',
});
}, [globalDialogService]);
const t = useI18n(); const t = useI18n();
if (!hasPayment) { if (!hasPayment) {
@@ -61,7 +55,7 @@ export const UserPlanButton = () => {
<div <div
data-is-believer={isBeliever ? 'true' : undefined} data-is-believer={isBeliever ? 'true' : undefined}
className={styles.userPlanButton} className={styles.userPlanButton}
onClick={handleClick} onClick={onClick}
data-event-props="$.settingsPanel.profileAndBadge.viewPlans" data-event-props="$.settingsPanel.profileAndBadge.viewPlans"
> >
{planLabel} {planLabel}
@@ -30,6 +30,7 @@ import {
} from '../../modules/cloud'; } from '../../modules/cloud';
import { UserPlanButton } from '../affine/auth/user-plan-button'; import { UserPlanButton } from '../affine/auth/user-plan-button';
import { useSignOut } from '../hooks/affine/use-sign-out'; import { useSignOut } from '../hooks/affine/use-sign-out';
import { useCatchEventCallback } from '../hooks/use-catch-event-hook';
import * as styles from './index.css'; import * as styles from './index.css';
import { UnknownUserIcon } from './unknow-user'; import { UnknownUserIcon } from './unknow-user';
@@ -113,6 +114,14 @@ const CloudUsage = () => {
const quota = useService(UserQuotaService).quota; const quota = useService(UserQuotaService).quota;
const quotaError = useLiveData(quota.error$); const quotaError = useLiveData(quota.error$);
const globalDialogService = useService(GlobalDialogService);
const handleClick = useCatchEventCallback(() => {
globalDialogService.open('setting', {
activeTab: 'plans',
scrollAnchor: 'cloudPricingPlan',
});
}, [globalDialogService]);
useEffect(() => { useEffect(() => {
// revalidate quota to get the latest status // revalidate quota to get the latest status
quota.revalidate(); quota.revalidate();
@@ -150,7 +159,7 @@ const CloudUsage = () => {
<span>&nbsp;/&nbsp;</span> <span>&nbsp;/&nbsp;</span>
<span>{maxFormatted}</span> <span>{maxFormatted}</span>
</div> </div>
<UserPlanButton /> <UserPlanButton onClick={handleClick} />
</div> </div>
<div className={styles.cloudUsageBar}> <div className={styles.cloudUsageBar}>
@@ -16,6 +16,7 @@ import {
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useCatchEventCallback } from '../../hooks/use-catch-event-hook';
import { AddWorkspace } from './add-workspace'; import { AddWorkspace } from './add-workspace';
import * as styles from './index.css'; import * as styles from './index.css';
import { UserAccountItem } from './user-account'; import { UserAccountItem } from './user-account';
@@ -129,12 +130,20 @@ const UserWithWorkspaceListInner = ({
const workspaceManager = useService(WorkspacesService); const workspaceManager = useService(WorkspacesService);
const workspaces = useLiveData(workspaceManager.list.workspaces$); const workspaces = useLiveData(workspaceManager.list.workspaces$);
const onOpenPricingPlan = useCatchEventCallback(() => {
globalDialogService.open('setting', {
activeTab: 'plans',
scrollAnchor: 'cloudPricingPlan',
});
}, [globalDialogService]);
return ( return (
<div className={styles.workspaceListWrapper}> <div className={styles.workspaceListWrapper}>
{isAuthenticated ? ( {isAuthenticated ? (
<UserAccountItem <UserAccountItem
email={session.session.account.email ?? 'Unknown User'} email={session.session.account.email ?? 'Unknown User'}
onEventEnd={onEventEnd} onEventEnd={onEventEnd}
onClick={onOpenPricingPlan}
/> />
) : ( ) : (
<SignInItem /> <SignInItem />
@@ -1,11 +1,14 @@
import { UserPlanButton } from '@affine/core/components/affine/auth/user-plan-button'; import { UserPlanButton } from '@affine/core/components/affine/auth/user-plan-button';
import type { SyntheticEvent } from 'react';
import * as styles from './index.css'; import * as styles from './index.css';
export const UserAccountItem = ({ export const UserAccountItem = ({
email, email,
onClick,
}: { }: {
email: string; email: string;
onClick: (e: SyntheticEvent<Element, Event>) => void;
onEventEnd?: () => void; onEventEnd?: () => void;
}) => { }) => {
return ( return (
@@ -13,7 +16,7 @@ export const UserAccountItem = ({
<div className={styles.leftContainer}> <div className={styles.leftContainer}>
<div className={styles.userEmail}>{email}</div> <div className={styles.userEmail}>{email}</div>
</div> </div>
<UserPlanButton /> <UserPlanButton onClick={onClick} />
</div> </div>
); );
}; };
@@ -7,6 +7,7 @@ import { Tooltip } from '@affine/component/ui/tooltip';
import { WorkspaceAvatar } from '@affine/component/workspace-avatar'; import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
import { UserPlanButton } from '@affine/core/components/affine/auth/user-plan-button'; import { UserPlanButton } from '@affine/core/components/affine/auth/user-plan-button';
import { authAtom } from '@affine/core/components/atoms'; import { authAtom } from '@affine/core/components/atoms';
import { useCatchEventCallback } from '@affine/core/components/hooks/use-catch-event-hook';
import { useWorkspaceInfo } from '@affine/core/components/hooks/use-workspace-info'; import { useWorkspaceInfo } from '@affine/core/components/hooks/use-workspace-info';
import { AuthService } from '@affine/core/modules/cloud'; import { AuthService } from '@affine/core/modules/cloud';
import { UserFeatureService } from '@affine/core/modules/cloud/services/user-feature'; import { UserFeatureService } from '@affine/core/modules/cloud/services/user-feature';
@@ -38,11 +39,24 @@ import * as style from './style.css';
export type UserInfoProps = { export type UserInfoProps = {
onAccountSettingClick: () => void; onAccountSettingClick: () => void;
onTabChange: (
key: SettingTab,
workspaceMetadata: WorkspaceMetadata | null
) => void;
active?: boolean; active?: boolean;
}; };
export const UserInfo = ({ onAccountSettingClick, active }: UserInfoProps) => { export const UserInfo = ({
onAccountSettingClick,
onTabChange,
active,
}: UserInfoProps) => {
const account = useLiveData(useService(AuthService).session.account$); const account = useLiveData(useService(AuthService).session.account$);
const onClick = useCatchEventCallback(() => {
onTabChange('plans', null);
}, [onTabChange]);
if (!account) { if (!account) {
// TODO(@eyhn): loading ui // TODO(@eyhn): loading ui
return; return;
@@ -68,7 +82,7 @@ export const UserInfo = ({ onAccountSettingClick, active }: UserInfoProps) => {
<div className="name" title={account.label}> <div className="name" title={account.label}>
{account.label} {account.label}
</div> </div>
<UserPlanButton /> <UserPlanButton onClick={onClick} />
</div> </div>
<div className="email" title={account.email}> <div className="email" title={account.email}>
@@ -193,6 +207,7 @@ export const SettingSidebar = ({
<UserInfo <UserInfo
onAccountSettingClick={onAccountSettingClick} onAccountSettingClick={onAccountSettingClick}
active={activeTab === 'account'} active={activeTab === 'account'}
onTabChange={onTabChange}
/> />
</Suspense> </Suspense>
) : null} ) : null}