Merge branch 'feat/rbf-wording' into 'main'
[ProtonMail-WebClient.git] / packages / drive-store / store / _settings / useUserSettings.tsx
blob0f0aa52e7cc1e826618a500039ca066b1600c41b
1 import type { ReactNode } from 'react';
2 import { createContext, useCallback, useContext, useMemo, useState } from 'react';
4 import { useApi } from '@proton/components';
5 import { queryUpdateUserSettings } from '@proton/shared/lib/api/drive/user';
6 import { DEFAULT_USER_SETTINGS } from '@proton/shared/lib/drive/constants';
7 import type { UserModel } from '@proton/shared/lib/interfaces';
8 import type {
9     LayoutSetting,
10     RevisionRetentionDaysSetting,
11     UserSettings,
12     UserSettingsResponse,
13 } from '@proton/shared/lib/interfaces/drive/userSettings';
14 import useFlag from '@proton/unleash/useFlag';
16 import type { UserSortParams } from './sorting';
17 import { getSetting, parseSetting } from './sorting';
19 const UserSettingsContext = createContext<{
20     sort: UserSortParams;
21     layout: LayoutSetting;
22     revisionRetentionDays: RevisionRetentionDaysSetting;
23     b2bPhotosEnabled: boolean;
24     changeSort: (sortParams: UserSortParams) => Promise<void>;
25     changeLayout: (Layout: LayoutSetting) => Promise<void>;
26     changeB2BPhotosEnabled: (B2BPhotosEnabled: boolean) => Promise<void>;
27 } | null>(null);
29 export function UserSettingsProvider({
30     initialUser,
31     initialDriveUserSettings,
32     children,
33 }: {
34     children: ReactNode;
35     initialUser: UserModel;
36     initialDriveUserSettings: UserSettingsResponse;
37 }) {
38     const api = useApi();
39     const driveB2BPhotosUpload = useFlag('DriveB2BPhotosUpload');
41     const [userSettings, setUserSettings] = useState<UserSettings>(() => {
42         const { UserSettings, Defaults } = initialDriveUserSettings;
43         const { hasPaidDrive } = initialUser;
44         return Object.entries(UserSettings).reduce((settings, [key, value]) => {
45             // In case of user downgrade from paid to free, we want to set the default free user value
46             if (key === 'RevisionRetentionDays' && !hasPaidDrive) {
47                 return {
48                     ...settings,
49                     RevisionRetentionDays: Defaults.RevisionRetentionDays,
50                 };
51             }
52             return {
53                 ...settings,
54                 [key]:
55                     value ??
56                     (Defaults[key as keyof UserSettingsResponse['Defaults']] ||
57                         DEFAULT_USER_SETTINGS[key as keyof UserSettingsResponse['UserSettings']]),
58             };
59         }, {} as UserSettings);
60     });
62     const sort = useMemo(() => parseSetting(userSettings.Sort), [userSettings.Sort]);
64     const changeSort = useCallback(async (sortParams: UserSortParams) => {
65         const sortSetting = getSetting(sortParams);
66         if (!sortSetting) {
67             return;
68         }
69         setUserSettings((settings) => ({ ...settings, Sort: sortSetting }));
70         await api(
71             queryUpdateUserSettings({
72                 Sort: sortSetting,
73             })
74         );
75     }, []);
77     const changeLayout = useCallback(async (Layout: LayoutSetting) => {
78         setUserSettings((settings) => ({ ...settings, Layout }));
79         await api(
80             queryUpdateUserSettings({
81                 Layout,
82             })
83         );
84     }, []);
86     const changeB2BPhotosEnabled = useCallback(async (B2BPhotosEnabled: boolean) => {
87         setUserSettings((settings) => ({ ...settings, B2BPhotosEnabled }));
88         await api(
89             queryUpdateUserSettings({
90                 B2BPhotosEnabled,
91             })
92         );
93     }, []);
95     const value = {
96         sort,
97         layout: userSettings.Layout,
98         revisionRetentionDays: userSettings.RevisionRetentionDays,
99         b2bPhotosEnabled: !driveB2BPhotosUpload || (driveB2BPhotosUpload && userSettings.B2BPhotosEnabled),
100         changeSort,
101         changeLayout,
102         changeB2BPhotosEnabled,
103     };
105     return <UserSettingsContext.Provider value={value}>{children}</UserSettingsContext.Provider>;
108 export default function useUserSettings() {
109     const state = useContext(UserSettingsContext);
110     if (!state) {
111         throw new Error('Trying to use uninitialized UserSettingsProvider');
112     }
113     return state;