feat(core): add cloud usage in sidebar avatar menu (#6400)

- Extract logic of getting cloud storage usage information into new hook
- Move `<StorageProgress />`: `component` → `core`
- Set minimum progress `0.5%`
- Add cloud usage progress bar in sidebar user avatar's dropdown

![CleanShot 2024-03-29 at 17.10.04@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/1fe9371a-a870-49a1-b4bb-b923c2fa4fe6.png)
This commit is contained in:
CatsJuice
2024-04-01 07:41:19 +00:00
parent af2158cb0c
commit f4e1e23120
8 changed files with 192 additions and 96 deletions

View File

@@ -1,6 +1,5 @@
export { SettingHeader } from './setting-header';
export { SettingRow } from './setting-row';
export * from './storage-progess';
export * from './workspace-detail-skeleton';
export * from './workspace-list-skeleton';
export { SettingWrapper } from './wrapper';

View File

@@ -85,39 +85,3 @@ globalStyle(`${settingRow} .right-col`, {
paddingLeft: '15px',
flexShrink: 0,
});
export const storageProgressContainer = style({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});
export const storageProgressWrapper = style({
flexGrow: 1,
marginRight: '20px',
});
globalStyle(`${storageProgressWrapper} .storage-progress-desc`, {
fontSize: cssVar('fontXs'),
color: cssVar('textSecondaryColor'),
height: '20px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 2,
});
globalStyle(`${storageProgressWrapper} .storage-progress-bar-wrapper`, {
height: '8px',
borderRadius: '4px',
backgroundColor: cssVar('black10'),
overflow: 'hidden',
});
export const storageProgressBar = style({
height: '100%',
backgroundColor: cssVar('processingColor'),
selectors: {
'&.danger': {
backgroundColor: cssVar('errorColor'),
},
},
});
export const storageButton = style({
padding: '4px 12px',
});

View File

@@ -1,92 +0,0 @@
import { SubscriptionPlan } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import bytes from 'bytes';
import clsx from 'clsx';
import { useMemo } from 'react';
import { Button } from '../../ui/button';
import { Tooltip } from '../../ui/tooltip';
import * as styles from './share.css';
export interface StorageProgressProgress {
max: number;
value: number;
upgradable?: boolean;
onUpgrade: () => void;
plan: SubscriptionPlan;
}
enum ButtonType {
Primary = 'primary',
Default = 'default',
}
export const StorageProgress = ({
max: upperLimit,
value,
upgradable = true,
onUpgrade,
plan,
}: StorageProgressProgress) => {
const t = useAFFiNEI18N();
const percent = useMemo(
() => Math.round((value / upperLimit) * 100),
[upperLimit, value]
);
const used = useMemo(() => bytes.format(value), [value]);
const max = useMemo(() => bytes.format(upperLimit), [upperLimit]);
const buttonType = useMemo(() => {
if (plan === SubscriptionPlan.Free) {
return ButtonType.Primary;
}
return ButtonType.Default;
}, [plan]);
return (
<div className={styles.storageProgressContainer}>
<div className={styles.storageProgressWrapper}>
<div className="storage-progress-desc">
<span>{t['com.affine.storage.used.hint']()}</span>
<span>
{used}/{max}
{` (${plan} ${t['com.affine.storage.plan']()})`}
</span>
</div>
<div className="storage-progress-bar-wrapper">
<div
className={clsx(styles.storageProgressBar, {
danger: percent > 80,
})}
style={{ width: `${percent > 100 ? '100' : percent}%` }}
></div>
</div>
</div>
{upgradable ? (
<Tooltip
options={{ hidden: percent < 100 }}
content={
plan === 'Free'
? t['com.affine.storage.maximum-tips']()
: t['com.affine.storage.maximum-tips.pro']()
}
>
<span tabIndex={0}>
<Button
type={buttonType}
onClick={onUpgrade}
className={styles.storageButton}
>
{plan === 'Free'
? t['com.affine.storage.upgrade']()
: t['com.affine.storage.change-plan']()}
</Button>
</span>
</Tooltip>
) : null}
</div>
);
};