diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json
index dcd37e6b1f..bf1d58bc68 100644
--- a/packages/frontend/component/package.json
+++ b/packages/frontend/component/package.json
@@ -40,6 +40,7 @@
"@toeverything/infra": "workspace:*",
"@toeverything/theme": "^0.7.20",
"@vanilla-extract/dynamic": "^2.0.3",
+ "bytes": "^3.1.2",
"check-password-strength": "^2.0.7",
"clsx": "^2.0.0",
"dayjs": "^1.11.10",
@@ -71,6 +72,7 @@
"@storybook/jest": "^0.2.3",
"@storybook/testing-library": "^0.2.2",
"@testing-library/react": "^14.0.0",
+ "@types/bytes": "^3.1.3",
"@types/react": "^18.2.28",
"@types/react-datepicker": "^4.19.0",
"@types/react-dnd": "^3.0.2",
diff --git a/packages/frontend/component/src/components/setting-components/share.css.ts b/packages/frontend/component/src/components/setting-components/share.css.ts
index c5fffdc144..be26abbf75 100644
--- a/packages/frontend/component/src/components/setting-components/share.css.ts
+++ b/packages/frontend/component/src/components/setting-components/share.css.ts
@@ -115,31 +115,19 @@ globalStyle(`${storageProgressWrapper} .storage-progress-desc`, {
globalStyle(`${storageProgressWrapper} .storage-progress-bar-wrapper`, {
height: '8px',
borderRadius: '4px',
- backgroundColor: 'var(--affine-pure-black-10)',
+ backgroundColor: 'var(--affine-black-10)',
overflow: 'hidden',
});
export const storageProgressBar = style({
height: '100%',
backgroundColor: 'var(--affine-processing-color)',
selectors: {
- '&.warning': {
- // Wait for design
- backgroundColor: '#FF7C09',
- },
'&.danger': {
backgroundColor: 'var(--affine-error-color)',
},
},
});
-export const storageExtendHint = style({
- borderRadius: '4px',
- padding: '4px 8px',
- backgroundColor: 'var(--affine-background-secondary-color)',
- color: 'var(--affine-text-secondary-color)',
- fontSize: 'var(--affine-font-xs)',
- lineHeight: '20px',
- marginTop: 8,
-});
-globalStyle(`${storageExtendHint} a`, {
- color: 'var(--affine-link-color)',
+
+export const storageButton = style({
+ padding: '4px 12px',
});
diff --git a/packages/frontend/component/src/components/setting-components/storage-progess.tsx b/packages/frontend/component/src/components/setting-components/storage-progess.tsx
index 5968bf29cd..33dd170182 100644
--- a/packages/frontend/component/src/components/setting-components/storage-progess.tsx
+++ b/packages/frontend/component/src/components/setting-components/storage-progess.tsx
@@ -1,6 +1,7 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button } from '@toeverything/components/button';
import { Tooltip } from '@toeverything/components/tooltip';
+import bytes from 'bytes';
import clsx from 'clsx';
import { useMemo } from 'react';
@@ -10,20 +11,14 @@ export interface StorageProgressProgress {
max: number;
value: number;
onUpgrade: () => void;
+ plan: string;
}
-const transformBytesToMB = (bytes: number) => {
- return (bytes / 1024 / 1024).toFixed(2);
-};
-
-const transformBytesToGB = (bytes: number) => {
- return (bytes / 1024 / 1024 / 1024).toFixed(2);
-};
-
export const StorageProgress = ({
max: upperLimit,
value,
onUpgrade,
+ plan,
}: StorageProgressProgress) => {
const t = useAFFiNEI18N();
const percent = useMemo(
@@ -31,51 +26,53 @@ export const StorageProgress = ({
[upperLimit, value]
);
- const used = useMemo(() => transformBytesToMB(value), [value]);
- const max = useMemo(() => transformBytesToGB(upperLimit), [upperLimit]);
+ const used = useMemo(() => bytes.format(value), [value]);
+ const max = useMemo(() => bytes.format(upperLimit), [upperLimit]);
+
+ const buttonType = useMemo(() => {
+ if (plan === 'Free') {
+ return 'primary';
+ }
+ return 'default';
+ }, [plan]);
return (
- <>
-
-
-
- {t['com.affine.storage.used.hint']()}
-
- {used}MB/{max}GB
-
-
-
-
-
80,
- danger: percent > 99,
- })}
- style={{ width: `${percent}%` }}
- >
-
-
-
-
-
-
+
+
+
+ {t['com.affine.storage.used.hint']()}
+
+ {used}/{max}
+ {` (${plan} Plan)`}
-
-
- {percent > 80 ? (
-
- ) : null}
- >
+
+
+
80,
+ })}
+ style={{ width: `${percent > 100 ? '100' : percent}%` }}
+ >
+
+
+
+
+
+
+
+
+
);
};
diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json
index 2438b74f82..a7d00eaa06 100644
--- a/packages/frontend/core/package.json
+++ b/packages/frontend/core/package.json
@@ -43,6 +43,7 @@
"@react-hookz/web": "^23.1.0",
"@toeverything/components": "^0.0.45",
"async-call-rpc": "^6.3.1",
+ "bytes": "^3.1.2",
"css-spring": "^4.1.0",
"cssnano": "^6.0.1",
"graphql": "^16.8.1",
@@ -75,6 +76,7 @@
"@sentry/webpack-plugin": "^2.8.0",
"@svgr/webpack": "^8.1.0",
"@swc/core": "^1.3.93",
+ "@types/bytes": "^3.1.3",
"@types/lodash-es": "^4.17.9",
"@types/webpack-env": "^1.18.2",
"copy-webpack-plugin": "^11.0.0",
diff --git a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx
index b58fe74b57..8a5541b1a0 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx
@@ -7,6 +7,7 @@ import {
import {
allBlobSizesQuery,
removeAvatarMutation,
+ SubscriptionPlan,
uploadAvatarMutation,
} from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -14,17 +15,24 @@ import { useMutation, useQuery } from '@affine/workspace/affine/gql';
import { ArrowRightSmallIcon, CameraIcon } from '@blocksuite/icons';
import { Avatar } from '@toeverything/components/avatar';
import { Button } from '@toeverything/components/button';
+import bytes from 'bytes';
import { useSetAtom } from 'jotai';
import {
type FC,
type MouseEvent,
Suspense,
useCallback,
+ useMemo,
useState,
} from 'react';
-import { authAtom, openSignOutModalAtom } from '../../../../atoms';
+import {
+ authAtom,
+ openSettingModalAtom,
+ openSignOutModalAtom,
+} from '../../../../atoms';
import { useCurrentUser } from '../../../../hooks/affine/use-current-user';
+import { useUserSubscription } from '../../../../hooks/use-subscription';
import { Upload } from '../../../pure/file-upload';
import * as style from './style.css';
@@ -124,6 +132,7 @@ export const AvatarAndName = () => {