import * as React from 'react'; import { AccessibilityInfo, Appearance, ColorSchemeName, NativeEventSubscription, } from 'react-native'; import MaterialCommunityIcon from '../components/MaterialCommunityIcon'; import PortalHost from '../components/Portal/PortalHost'; import DarkTheme from '../styles/DarkTheme'; import DefaultTheme from '../styles/DefaultTheme'; import { Provider as SettingsProvider, Settings } from './settings'; import { ThemeProvider } from './theming'; import { addEventListener } from '../utils/addEventListener'; type Props = { children: React.ReactNode; theme?: ReactNativePaper.Theme; settings?: Settings; }; const Provider = ({ ...props }: Props) => { const colorSchemeName = (!props.theme && Appearance?.getColorScheme()) || 'light'; const [reduceMotionEnabled, setReduceMotionEnabled] = React.useState(false); const [colorScheme, setColorScheme] = React.useState(colorSchemeName); const handleAppearanceChange = ( preferences: Appearance.AppearancePreferences ) => { const { colorScheme } = preferences; setColorScheme(colorScheme); }; React.useEffect(() => { let subscription: NativeEventSubscription | undefined; if (!props.theme) { subscription = addEventListener( AccessibilityInfo, 'reduceMotionChanged', setReduceMotionEnabled ) as NativeEventSubscription | undefined; } return () => { if (!props.theme) { subscription?.remove(); } }; }, [props.theme]); React.useEffect(() => { let appearanceSubscription: NativeEventSubscription | undefined; if (!props.theme) { appearanceSubscription = Appearance?.addChangeListener( handleAppearanceChange ) as NativeEventSubscription | undefined; } return () => { if (!props.theme) { if (appearanceSubscription) { appearanceSubscription.remove(); } else { Appearance?.removeChangeListener(handleAppearanceChange); } } }; }, [props.theme]); const getTheme = () => { const { theme: providedTheme } = props; if (providedTheme) { return providedTheme; } else { const theme = ( colorScheme === 'dark' ? DarkTheme : DefaultTheme ) as ReactNativePaper.Theme; return { ...theme, animation: { ...theme.animation, scale: reduceMotionEnabled ? 0 : 1, }, }; } }; const { children, settings } = props; return ( {children} ); }; export default Provider;