1 import { useEffect, useLayoutEffect, useMemo } from 'react';
3 import { useUserSettings } from '@proton/account/userSettings/hooks';
4 import useApi from '@proton/components/hooks/useApi';
5 import { getSilentApi } from '@proton/shared/lib/api/helpers/customConfig';
6 import { updateTheme } from '@proton/shared/lib/api/settings';
8 canGetInboxDesktopInfo,
10 hasInboxDesktopFeature,
11 } from '@proton/shared/lib/desktop/ipcHelpers';
12 import { getIsDrawerApp, postMessageToIframe } from '@proton/shared/lib/drawer/helpers';
13 import { DRAWER_EVENTS } from '@proton/shared/lib/drawer/interfaces';
14 import { isElectronMail } from '@proton/shared/lib/helpers/desktop';
15 import { rootFontSize } from '@proton/shared/lib/helpers/dom';
16 import type { ThemeSetting } from '@proton/shared/lib/themes/themes';
17 import { electronAppTheme as defaultElectronAppTheme, getDefaultThemeSetting } from '@proton/shared/lib/themes/themes';
18 import debounce from '@proton/utils/debounce';
19 import noop from '@proton/utils/noop';
21 import useDrawer from '../../hooks/drawer/useDrawer';
22 import { useTheme } from './ThemeProvider';
24 export const DrawerThemeInjector = () => {
25 const { settings } = useTheme();
27 const { iframeSrcMap } = useDrawer();
29 useLayoutEffect(() => {
30 // If apps are opened in drawer, update their theme too
32 Object.keys(iframeSrcMap).map((app) => {
33 if (getIsDrawerApp(app)) {
34 postMessageToIframe({ type: DRAWER_EVENTS.UPDATE_THEME, payload: { themeSetting: settings } }, app);
43 export const ThemeInjector = () => {
44 const [userSettings] = useUserSettings();
45 const { addListener, settings, setThemeSetting } = useTheme();
47 const silentApi = getSilentApi(api);
49 const legacyThemeType = userSettings.ThemeType;
50 const legacyThemeSettings = useMemo(() => getDefaultThemeSetting(legacyThemeType), [legacyThemeType]);
51 const themeSetting = userSettings.Theme && 'Mode' in userSettings.Theme ? userSettings.Theme : legacyThemeSettings;
53 useLayoutEffect(() => {
54 const theme = (() => {
55 if (!isElectronMail) {
59 if (canGetInboxDesktopInfo) {
60 if (hasInboxDesktopFeature('FullTheme')) {
61 return getInboxDesktopInfo('theme');
62 } else if (hasInboxDesktopFeature('ThemeSelection')) {
63 return { ...defaultElectronAppTheme, ...getInboxDesktopInfo('theme') };
67 return defaultElectronAppTheme;
70 setThemeSetting(theme);
75 }, [settings.FontSize]);
78 const cb = debounce((settings: ThemeSetting) => {
79 if (!hasInboxDesktopFeature('ThemeSelection')) {
80 silentApi(updateTheme(settings)).catch(noop);
84 const removeListener = addListener(cb);