import React, { type FC, type PropsWithChildren, createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { FALLBACK_CULTURE } from 'lib/globalize'; import { currentSettings as userSettings } from 'scripts/settings/userSettings'; import Events, { type Event } from 'utils/events'; import { useApi } from './useApi'; interface UserSettings { customCss?: string disableCustomCss: boolean theme?: string dashboardTheme?: string dateTimeLocale?: string language?: string } // NOTE: This is an incomplete list of only the settings that are currently being used const UserSettingField = { // Custom CSS CustomCss: 'customCss', DisableCustomCss: 'disableCustomCss', // Theme settings Theme: 'appTheme', DashboardTheme: 'dashboardTheme', // Locale settings DateTimeLocale: 'datetimelocale', Language: 'language' }; const UserSettingsContext = createContext({ disableCustomCss: false }); export const useUserSettings = () => useContext(UserSettingsContext); export const UserSettingsProvider: FC> = ({ children }) => { const [ customCss, setCustomCss ] = useState(); const [ disableCustomCss, setDisableCustomCss ] = useState(false); const [ theme, setTheme ] = useState(); const [ dashboardTheme, setDashboardTheme ] = useState(); const [ dateTimeLocale, setDateTimeLocale ] = useState(); const [ language, setLanguage ] = useState(FALLBACK_CULTURE); const { user } = useApi(); const context = useMemo(() => ({ customCss, disableCustomCss, theme, dashboardTheme, dateTimeLocale, locale: language }), [ customCss, disableCustomCss, theme, dashboardTheme, dateTimeLocale, language ]); // Update the values of the user settings const updateUserSettings = useCallback(() => { setCustomCss(userSettings.customCss()); setDisableCustomCss(userSettings.disableCustomCss()); setTheme(userSettings.theme()); setDashboardTheme(userSettings.dashboardTheme()); setDateTimeLocale(userSettings.dateTimeLocale()); setLanguage(userSettings.language()); }, []); const onUserSettingsChange = useCallback((_e: Event, name?: string) => { if (name && Object.values(UserSettingField).includes(name)) { updateUserSettings(); } }, [ updateUserSettings ]); // Handle user settings changes useEffect(() => { Events.on(userSettings, 'change', onUserSettingsChange); return () => { Events.off(userSettings, 'change', onUserSettingsChange); }; }, [ onUserSettingsChange ]); // Update the settings if the user changes useEffect(() => { updateUserSettings(); }, [ updateUserSettings, user ]); return ( {children} ); };