Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / components / hooks / drawer / useOpenDrawerOnLoad.ts
blob6b9f71be9bc1725fd870b75e13a2a559499d676f
1 import { useEffect } from 'react';
3 import { useUser } from '@proton/account/user/hooks';
4 import useDrawer from '@proton/components/hooks/drawer/useDrawer';
5 import useApiStatus from '@proton/components/hooks/useApiStatus';
6 import useAuthentication from '@proton/components/hooks/useAuthentication';
7 import useConfig from '@proton/components/hooks/useConfig';
8 import useOnline from '@proton/components/hooks/useOnline';
9 import { getAppHref } from '@proton/shared/lib/apps/helper';
10 import { getLocalIDFromPathname } from '@proton/shared/lib/authentication/pathnameHelper';
11 import type { APP_NAMES } from '@proton/shared/lib/constants';
12 import { APPS_CONFIGURATION } from '@proton/shared/lib/constants';
13 import {
14     addParentAppToUrl,
15     getDisplayDrawerApp,
16     getIsDrawerApp,
17     getIsIframedDrawerApp,
18     getLocalStorageUserDrawerKey,
19 } from '@proton/shared/lib/drawer/helpers';
20 import type { DrawerLocalStorageValue } from '@proton/shared/lib/drawer/interfaces';
21 import { getItem } from '@proton/shared/lib/helpers/storage';
23 const useOpenDrawerOnLoad = () => {
24     const [user] = useUser();
25     const { APP_NAME } = useConfig();
26     const { offline } = useApiStatus();
27     const onlineStatus = useOnline();
28     const authentication = useAuthentication();
29     const { setIframeSrcMap, setIframeURLMap, setAppInView } = useDrawer();
31     const isAppReachable = !offline && onlineStatus;
33     useEffect(() => {
34         const itemFromStorage = getItem(getLocalStorageUserDrawerKey(user.ID));
35         if (itemFromStorage) {
36             // Surround JSON.parse by try/catch in case the value cannot be parsed
37             try {
38                 const { app, path } = JSON.parse(itemFromStorage) as DrawerLocalStorageValue;
40                 const url = APPS_CONFIGURATION[app as APP_NAMES]
41                     ? getAppHref(path || '', app as APP_NAMES, authentication.getLocalID())
42                     : undefined;
44                 if (app && isAppReachable) {
45                     const isValidApp = getIsDrawerApp(app);
46                     const canDisplayDrawerApp = getDisplayDrawerApp(APP_NAME, app);
48                     if (!isValidApp || !canDisplayDrawerApp) {
49                         return;
50                     }
52                     if (getIsIframedDrawerApp(app)) {
53                         if (path && url) {
54                             setIframeSrcMap((map) => ({
55                                 ...map,
56                                 [app]: url,
57                             }));
59                             setIframeURLMap((map) => ({
60                                 ...map,
61                                 [app]: url,
62                             }));
63                         } else {
64                             /**
65                              * Normally, this case should never happen.
66                              * In case there is an iframed app reference stored in the localStorage without url,
67                              * we will try to open the drawer app on parent app load, without any url.
68                              *
69                              * However, if we try to open an iframed app without url,
70                              * it will result as a blank space in the drawer on which the user has no control.
71                              * To avoid that, we will use en the default child app url.
72                              */
73                             // If no url is set, load the iframe on the default child app url
74                             const localID = getLocalIDFromPathname(window.location.pathname);
75                             const appHref = getAppHref('/', app, localID);
76                             const defaultUrl = addParentAppToUrl(appHref, APP_NAME);
78                             setIframeSrcMap((map) => ({
79                                 ...map,
80                                 [app]: defaultUrl,
81                             }));
83                             setIframeURLMap((map) => ({
84                                 ...map,
85                                 [app]: defaultUrl,
86                             }));
87                         }
88                     }
89                     setAppInView(app);
90                 }
91             } catch (e: any) {
92                 console.error(e);
93             }
94         }
95     }, []);
98 export default useOpenDrawerOnLoad;