import React, { createContext, useContext, useEffect, useState } from 'react' import { Appearance } from 'react-native' import { useSelector } from 'react-redux' import { ColorDefinitions, getTheme } from '@utils/styles/themes' import { getSettingsTheme } from '@utils/slices/settingsSlice' import { throttle } from 'lodash' type ContextType = { mode: 'light' | 'dark' theme: { [key in ColorDefinitions]: string } setTheme: (theme: 'light' | 'dark') => void } const ManageThemeContext = createContext({ mode: 'light', theme: getTheme('light'), setTheme: () => {} }) export const useTheme = () => useContext(ManageThemeContext) const useColorSchemeDelay = (delay = 500) => { const [colorScheme, setColorScheme] = React.useState( Appearance.getColorScheme() ) const onColorSchemeChange = React.useCallback( throttle( ({ colorScheme }) => { setColorScheme(colorScheme) }, delay, { leading: false } ), [] ) React.useEffect(() => { const listener = Appearance.addChangeListener(onColorSchemeChange) return () => { onColorSchemeChange.cancel() listener.remove() } }, []) return colorScheme } const ThemeManager: React.FC = ({ children }) => { const osTheme = useColorSchemeDelay() const userTheme = useSelector(getSettingsTheme) const currentMode = userTheme === 'auto' ? (osTheme as 'light' | 'dark') : userTheme const [mode, setMode] = useState(currentMode) const setTheme = (theme: 'light' | 'dark') => setMode(theme) useEffect(() => { setMode(currentMode) }, [currentMode]) return ( {children} ) } export default ThemeManager