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
@@ -0,0 +1,56 @@
import { allBlobSizesQuery, SubscriptionPlan } from '@affine/graphql';
import { cssVar } from '@toeverything/theme';
import bytes from 'bytes';
import { useMemo } from 'react';
import { useQuery } from '../use-query';
import { useUserQuota } from '../use-quota';
import { useUserSubscription } from '../use-subscription';
/**
* Hook to get currentUser's cloud storage usage information.
*/
export const useCloudStorageUsage = () => {
const { data } = useQuery({
query: allBlobSizesQuery,
});
const quota = useUserQuota();
const [subscription] = useUserSubscription();
const plan = subscription?.plan ?? SubscriptionPlan.Free;
const maxLimit = useMemo(() => {
if (quota) {
return quota.storageQuota;
}
return bytes.parse(plan === SubscriptionPlan.Free ? '10GB' : '100GB');
}, [plan, quota]);
const used = data?.collectAllBlobSizes?.size ?? 0;
const percent = Math.min(
100,
Math.max(0.5, Number(((used / maxLimit) * 100).toFixed(4)))
);
const color = percent > 80 ? cssVar('errorColor') : cssVar('processingColor');
const usedText = bytes.format(used);
const maxLimitText = bytes.format(maxLimit);
return {
/** Current subscription plan of logged in user */
plan,
/** Used storage in bytes */
used,
/** Formatted used storage */
usedText,
/** CSS variable name for progress bar color */
color,
/** Percentage of storage used */
percent,
/** Maximum storage limit in bytes */
maxLimit,
/** Formatted maximum storage limit */
maxLimitText,
};
};