diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ThemeContext.tsx | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/src/lib/ThemeContext.tsx b/src/lib/ThemeContext.tsx index fe25dde54..483c50c42 100644 --- a/src/lib/ThemeContext.tsx +++ b/src/lib/ThemeContext.tsx @@ -1,8 +1,9 @@ +import {isWeb} from 'platform/detection' import React, {ReactNode, createContext, useContext} from 'react' import { AppState, TextStyle, - useColorScheme, + useColorScheme as useColorScheme_BUGGY, ViewStyle, ColorSchemeName, } from 'react-native' @@ -92,33 +93,44 @@ export const ThemeContext = createContext<Theme>(defaultTheme) export const useTheme = () => useContext(ThemeContext) -export const ThemeProvider: React.FC<ThemeProviderProps> = ({ - theme, - children, -}) => { - const colorSchemeFromRN = useColorScheme() - const [nativeColorScheme, setNativeColorScheme] = - React.useState<ColorSchemeName>(colorSchemeFromRN) +function getTheme(theme: ColorSchemeName) { + return theme === 'dark' ? darkTheme : defaultTheme +} + +/** + * With RN iOS, we can only "trust" the color scheme reported while the app is + * active. This is a workaround until the bug is fixed upstream. + * + * @see https://github.com/bluesky-social/social-app/pull/1417#issuecomment-1719868504 + * @see https://github.com/facebook/react-native/pull/39439 + */ +function useColorScheme_FIXED() { + const colorScheme = useColorScheme_BUGGY() + const [currentColorScheme, setCurrentColorScheme] = + React.useState<ColorSchemeName>(colorScheme) React.useEffect(() => { + // we don't need to be updating state on web + if (isWeb) return const subscription = AppState.addEventListener('change', state => { const isActive = state === 'active' - if (!isActive) return - - setNativeColorScheme(colorSchemeFromRN) + setCurrentColorScheme(colorScheme) }) return () => subscription.remove() - }, [colorSchemeFromRN]) + }, [colorScheme]) + + return isWeb ? colorScheme : currentColorScheme +} - const value = - theme === 'system' - ? nativeColorScheme === 'dark' - ? darkTheme - : defaultTheme - : theme === 'dark' - ? darkTheme - : defaultTheme +export const ThemeProvider: React.FC<ThemeProviderProps> = ({ + theme, + children, +}) => { + const colorScheme = useColorScheme_FIXED() + const themeValue = getTheme(theme === 'system' ? colorScheme : theme) - return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider> + return ( + <ThemeContext.Provider value={themeValue}>{children}</ThemeContext.Provider> + ) } |