fix(core): remove quota modal (#12586)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Removed Features**
  - Removed all quota-reached modal dialogs, including both cloud and local storage quota notifications.
  - Users will no longer see modal alerts when storage limits are reached in workspaces.
- **User Interface**
  - Quota-reached modals and related styles have been removed from workspace layouts on both desktop and mobile.
- **Other Changes**
  - Quota notification logic and related settings have been eliminated from the application.
  - Maximum blob size enforcement and related callbacks have been removed from blob management.
  - Localization entries related to file upload size limits and quota tips have been removed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
EYHN
2025-05-28 08:04:22 +00:00
parent 274319dd6c
commit b847de4980
10 changed files with 3 additions and 274 deletions

View File

@@ -1,27 +0,0 @@
import { cssVar } from '@toeverything/theme';
import { cssVarV2 } from '@toeverything/theme/v2';
import { style } from '@vanilla-extract/css';
export const ulStyle = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
gap: '8px',
marginTop: '12px',
});
export const liStyle = style({
display: 'flex',
flexDirection: 'row',
alignItems: 'start',
fontSize: cssVar('fontBase'),
});
export const prefixDot = style({
background: cssVarV2('icon/activated'),
width: '5px',
height: '5px',
borderRadius: '50%',
marginRight: '12px',
marginTop: '10px',
});

View File

@@ -1,123 +0,0 @@
import { ConfirmModal } from '@affine/component/ui/modal';
import { openQuotaModalAtom } from '@affine/core/components/atoms';
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { type I18nString, useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import { useLiveData, useService } from '@toeverything/infra';
import { useAtom } from 'jotai';
import { useCallback, useEffect, useMemo } from 'react';
import { useAsyncCallback } from '../../hooks/affine-async-hooks';
import * as styles from './cloud-quota-modal.css';
export const CloudQuotaModal = () => {
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const [open, setOpen] = useAtom(openQuotaModalAtom);
const workspaceQuotaService = useService(WorkspaceQuotaService);
useEffect(() => {
workspaceQuotaService.quota.revalidate();
}, [workspaceQuotaService]);
const workspaceQuota = useLiveData(workspaceQuotaService.quota.quota$);
const permissionService = useService(WorkspacePermissionService);
const isOwner = useLiveData(permissionService.permission.isOwner$);
useEffect(() => {
// revalidate permission
permissionService.permission.revalidate();
}, [permissionService]);
const workspaceDialogService = useService(WorkspaceDialogService);
const handleUpgradeConfirm = useCallback(() => {
workspaceDialogService.open('setting', {
activeTab: 'plans',
scrollAnchor: 'cloudPricingPlan',
});
track.$.paywall.storage.viewPlans();
setOpen(false);
}, [workspaceDialogService, setOpen]);
const description = useMemo(() => {
if (!workspaceQuota) {
return null;
}
if (isOwner) {
return (
<OwnerDescription quota={workspaceQuota.humanReadable.blobLimit} />
);
}
return t['com.affine.payment.blob-limit.description.member']({
quota: workspaceQuota.humanReadable.blobLimit,
});
}, [isOwner, workspaceQuota, t]);
const onAbortLargeBlob = useAsyncCallback(
async (byteSize: number) => {
// wait for quota revalidation
await workspaceQuotaService.quota.waitForRevalidation();
if (
byteSize > (workspaceQuotaService.quota.quota$.value?.blobLimit ?? 0)
) {
setOpen(true);
}
},
[setOpen, workspaceQuotaService]
);
useEffect(() => {
if (!workspaceQuota) {
return;
}
currentWorkspace.engine.blob.setMaxBlobSize(workspaceQuota.blobLimit);
const disposable =
currentWorkspace.engine.blob.onReachedMaxBlobSize(onAbortLargeBlob);
return () => {
disposable();
};
}, [currentWorkspace.engine.blob, onAbortLargeBlob, workspaceQuota]);
return (
<ConfirmModal
open={open}
title={t['com.affine.payment.blob-limit.title']()}
onOpenChange={setOpen}
description={description}
onConfirm={handleUpgradeConfirm}
confirmText={t['com.affine.payment.upgrade']()}
confirmButtonOptions={{
variant: 'primary',
}}
/>
);
};
const tips: I18nString[] = [
'com.affine.payment.blob-limit.description.owner.tips-1',
'com.affine.payment.blob-limit.description.owner.tips-2',
'com.affine.payment.blob-limit.description.owner.tips-3',
];
const OwnerDescription = ({ quota }: { quota: string }) => {
const t = useI18n();
return (
<div>
{t['com.affine.payment.blob-limit.description.owner']({
quota: quota,
})}
<ul className={styles.ulStyle}>
{tips.map((tip, index) => (
<li className={styles.liStyle} key={index}>
<div className={styles.prefixDot} />
{t.t(tip)}
</li>
))}
</ul>
</div>
);
};

View File

@@ -1,2 +0,0 @@
export * from './cloud-quota-modal';
export * from './local-quota-modal';

View File

@@ -1,45 +0,0 @@
import { ConfirmModal } from '@affine/component/ui/modal';
import { openQuotaModalAtom } from '@affine/core/components/atoms';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import { useAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
export const LocalQuotaModal = () => {
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const [open, setOpen] = useAtom(openQuotaModalAtom);
const onConfirm = useCallback(() => {
setOpen(false);
}, [setOpen]);
useEffect(() => {
const disposable = currentWorkspace.engine.blob.onReachedMaxBlobSize(() => {
setOpen(true);
});
return () => {
disposable();
};
}, [currentWorkspace.engine.blob, setOpen]);
return (
<ConfirmModal
open={open}
title={t['com.affine.payment.blob-limit.title']()}
description={t['com.affine.payment.blob-limit.description.local']({
quota: '100MB',
})}
onOpenChange={setOpen}
cancelButtonOptions={{
hidden: true,
}}
onConfirm={onConfirm}
confirmText={t['Got it']()}
confirmButtonOptions={{
variant: 'primary',
}}
/>
);
};

View File

@@ -1,10 +1,5 @@
import { uniReactRoot } from '@affine/component';
// import { WorkspaceAIOnboarding } from '@affine/core/components/affine/ai-onboarding';
import { AiLoginRequiredModal } from '@affine/core/components/affine/auth/ai-login-required';
import {
CloudQuotaModal,
LocalQuotaModal,
} from '@affine/core/components/affine/quota-reached-modal';
import { useResponsiveSidebar } from '@affine/core/components/hooks/use-responsive-siedebar';
import { SWRConfigProvider } from '@affine/core/components/providers/swr-config-provider';
import { WorkspaceSideEffects } from '@affine/core/components/providers/workspace-side-effects';
@@ -29,13 +24,8 @@ export const WorkspaceLayout = function WorkspaceLayout({
{/* ---- some side-effect components ---- */}
{currentWorkspace?.flavour !== 'local' ? (
<>
<CloudQuotaModal />
<QuotaCheck workspaceMeta={currentWorkspace.meta} />
</>
) : (
<LocalQuotaModal />
)}
<QuotaCheck workspaceMeta={currentWorkspace.meta} />
) : null}
<AiLoginRequiredModal />
<WorkspaceSideEffects />
<PeekViewManagerModal />

View File

@@ -1,10 +1,6 @@
import { uniReactRoot } from '@affine/component';
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
import { AiLoginRequiredModal } from '@affine/core/components/affine/auth/ai-login-required';
import {
CloudQuotaModal,
LocalQuotaModal,
} from '@affine/core/components/affine/quota-reached-modal';
import { SWRConfigProvider } from '@affine/core/components/providers/swr-config-provider';
import { WorkspaceSideEffects } from '@affine/core/components/providers/workspace-side-effects';
import {
@@ -146,11 +142,6 @@ export const WorkspaceLayout = ({
{/* ---- some side-effect components ---- */}
<PeekViewManagerModal />
{workspace?.flavour !== 'local' ? (
<CloudQuotaModal />
) : (
<LocalQuotaModal />
)}
<AiLoginRequiredModal />
<uniReactRoot.Root />
<WorkspaceSideEffects />