1 import { c } from 'ttag';
3 import { PLANS } from '@proton/payments';
5 import type { APP_NAMES } from '../constants';
6 import { APPS } from '../constants';
7 import { getHasMailB2BPlan, hasVisionary } from '../helpers/subscription';
8 import type { Subscription, User, UserModel } from '../interfaces';
10 export const getHasStorageSplit = (user: User) => {
11 return user.MaxBaseSpace !== undefined;
14 export const getUsedSpace = (user: User) => {
15 if (getHasStorageSplit(user)) {
16 return user.UsedBaseSpace + user.UsedDriveSpace;
18 return user.UsedSpace;
21 export const getSpace = (user: User) => {
22 const usedSpace = user.UsedSpace ?? 0;
23 const maxSpace = user.MaxSpace ?? 0;
25 if (!getHasStorageSplit(user)) {
26 const usedDriveSpace = user.ProductUsedSpace?.Drive ?? 0;
27 const usedBaseSpace = usedSpace - usedDriveSpace;
33 maxBaseSpace: maxSpace,
34 maxDriveSpace: maxSpace,
39 const usedDriveSpace = user.UsedDriveSpace ?? 0;
40 const usedBaseSpace = user.UsedBaseSpace ?? 0;
41 const maxDriveSpace = user.MaxDriveSpace ?? maxSpace ?? 0;
42 const maxBaseSpace = user.MaxBaseSpace ?? maxSpace ?? 0;
54 const getData = (used: number, max: number) => {
55 const percentage = (used * 100) / max;
56 const safePercentage = Number.isNaN(percentage) ? 0 : percentage;
57 const flooredPercentage = Math.floor(safePercentage);
59 percentage: safePercentage,
60 displayed: flooredPercentage,
64 export enum SpaceState {
70 export const getSpaceDetails = (usedSpace: number, maxSpace: number) => {
71 const data = getData(usedSpace, maxSpace);
72 const danger = data.percentage >= 100;
73 const warning = data.percentage >= 80 && data.percentage < 100;
75 type: danger ? SpaceState.Danger : warning ? SpaceState.Warning : SpaceState.Good,
80 export const getCompleteSpaceDetails = (space: ReturnType<typeof getSpace>) => {
82 pooled: getSpaceDetails(space.usedSpace, space.maxSpace),
83 base: getSpaceDetails(space.usedBaseSpace, space.maxBaseSpace),
84 drive: getSpaceDetails(space.usedDriveSpace, space.maxDriveSpace),
88 export const getAppSpace = (options: ReturnType<typeof getSpace>, app: APP_NAMES) => {
89 if (!options.splitStorage) {
90 return { usedSpace: options.usedSpace, maxSpace: options.maxSpace };
92 if (app === APPS.PROTONDRIVE) {
93 return { usedSpace: options.usedDriveSpace, maxSpace: options.maxDriveSpace };
95 return { usedSpace: options.usedBaseSpace, maxSpace: options.maxBaseSpace };
98 export const getCanAddStorage = ({ user, subscription }: { user: UserModel; subscription?: Subscription }) => {
102 if (user.isSubUser) {
111 if (hasVisionary(subscription) || getHasMailB2BPlan(subscription)) {
117 export const getAppStorage = (app: string) => {
118 // Translator: Your 'mail storage' or 'drive storage' is full
119 return c('storage_split: info').t`${app} storage`;
122 export const getAppStorageFull = (appStorage: string) => {
123 // Translator: Your 'mail storage' or 'drive storage' is full
124 return c('storage_split: info').t`Your ${appStorage} is full`;
127 export const getAppStorageAlmostFull = (appStorage: string) => {
128 return c('storage_split: info').t`Your ${appStorage} is almost full`;
131 export const getStorageFull = () => {
132 return c('storage_split: info').t`Your storage is full`;
135 export const getPercentageFull = (storage: string, percentage: number) => {
136 // Translator: Drive storage 99% full
137 return c('storage_split: info').t`${storage} ${percentage}% full`;
140 export const getPlanToUpsell = ({
144 storageDetails: ReturnType<typeof getCompleteSpaceDetails>;
147 if (app === APPS.PROTONDRIVE) {
151 // Area of experimentation which plan to upsell to.
153 if (storageDetails.base.type === SpaceState.Danger && storageDetails.drive.type === SpaceState.Danger) {
156 if (storageDetails.base.type === SpaceState.Danger) {
159 if (storageDetails.drive.type === SpaceState.Danger) {