Skip to content

Commit

Permalink
Merge pull request #1451 from bluesky-social/eric/theme-switching-web
Browse files Browse the repository at this point in the history
fix theme switching on web without refresh
  • Loading branch information
estrattonbailey authored Sep 15, 2023
2 parents 50f8116 + 0e8d564 commit 84b7edd
Showing 1 changed file with 33 additions and 21 deletions.
54 changes: 33 additions & 21 deletions src/lib/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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>
)
}

0 comments on commit 84b7edd

Please sign in to comment.