mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-02 01:49:51 +08:00
fix(core): multiple settings dialog should not appear when click user plan button repeatedly (#8924)
This commit is contained in:
@@ -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> / </span>
|
<span> / </span>
|
||||||
<span>{maxFormatted}</span>
|
<span>{maxFormatted}</span>
|
||||||
</div>
|
</div>
|
||||||
<UserPlanButton />
|
<UserPlanButton onClick={handleClick} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.cloudUsageBar}>
|
<div className={styles.cloudUsageBar}>
|
||||||
|
|||||||
+9
@@ -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 />
|
||||||
|
|||||||
+4
-1
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user