1 import { type ReactNode } from 'react';
2 import { useEffect, useReducer, useState } from 'react';
4 import useAuthentication from '@proton/components/hooks/useAuthentication';
5 import useConfig from '@proton/components/hooks/useConfig';
6 import useNotifications from '@proton/components/hooks/useNotifications';
7 import type { ApiListenerCallback, ApiWithListener } from '@proton/shared/lib/api/createApi';
8 import { handleInvalidSession } from '@proton/shared/lib/authentication/logout';
9 import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
11 import ApiModals from './ApiModals';
12 import ApiContext from './apiContext';
13 import ApiServerTimeContext from './apiServerTimeContext';
14 import ApiStatusContext, { defaultApiStatus } from './apiStatusContext';
16 const reducer = (oldState: typeof defaultApiStatus, diff: Partial<typeof defaultApiStatus>) => {
21 if (isDeepEqual(oldState, newState)) {
27 const ApiProvider = ({ api, children }: { api: ApiWithListener; children: ReactNode }) => {
28 const { APP_NAME } = useConfig();
29 const { createNotification } = useNotifications();
30 const authentication = useAuthentication();
31 const [apiStatus, setApiStatus] = useReducer(reducer, defaultApiStatus);
32 const [apiServerTime, setApiServerTime] = useState<Date | undefined>(undefined);
35 setApiStatus(defaultApiStatus);
37 const handleEvent: ApiListenerCallback = (event) => {
38 if (event.type === 'notification') {
39 createNotification(event.payload);
43 if (event.type === 'server-time') {
44 setApiServerTime(event.payload);
48 if (event.type === 'status') {
49 setApiStatus(event.payload);
53 if (event.type === 'logout') {
54 handleInvalidSession({ appName: APP_NAME, authentication });
60 api.addEventListener(handleEvent);
62 api.removeEventListener(handleEvent);
67 <ApiContext.Provider value={api}>
68 <ApiStatusContext.Provider value={apiStatus}>
69 <ApiServerTimeContext.Provider value={apiServerTime}>
71 <ApiModals api={api} />
72 </ApiServerTimeContext.Provider>
73 </ApiStatusContext.Provider>
74 </ApiContext.Provider>
78 export default ApiProvider;