fix theme cross-tab write loop (#2774)
* don't write on onUpdate, memoize * refac useColorModeThemezio/stable
parent
dc6603a1b9
commit
573cf31d86
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {useColorScheme} from 'react-native'
|
import {ColorSchemeName, useColorScheme} from 'react-native'
|
||||||
|
|
||||||
import {useThemePrefs} from 'state/shell'
|
import {useThemePrefs} from 'state/shell'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
|
@ -10,21 +10,31 @@ export function useColorModeTheme(): ThemeName {
|
||||||
const colorScheme = useColorScheme()
|
const colorScheme = useColorScheme()
|
||||||
const {colorMode, darkTheme} = useThemePrefs()
|
const {colorMode, darkTheme} = useThemePrefs()
|
||||||
|
|
||||||
return React.useMemo(() => {
|
React.useLayoutEffect(() => {
|
||||||
if (
|
const theme = getThemeName(colorScheme, colorMode, darkTheme)
|
||||||
(colorMode === 'system' && colorScheme === 'light') ||
|
updateDocument(theme)
|
||||||
colorMode === 'light'
|
updateSystemBackground(theme)
|
||||||
) {
|
}, [colorMode, colorScheme, darkTheme])
|
||||||
updateDocument('light')
|
|
||||||
updateSystemBackground('light')
|
return React.useMemo(
|
||||||
return 'light'
|
() => getThemeName(colorScheme, colorMode, darkTheme),
|
||||||
} else {
|
[colorScheme, colorMode, darkTheme],
|
||||||
const themeName = darkTheme ?? 'dim'
|
)
|
||||||
updateDocument(themeName)
|
}
|
||||||
updateSystemBackground(themeName)
|
|
||||||
return themeName
|
function getThemeName(
|
||||||
}
|
colorScheme: ColorSchemeName,
|
||||||
}, [colorMode, darkTheme, colorScheme])
|
colorMode: 'system' | 'light' | 'dark',
|
||||||
|
darkTheme?: ThemeName,
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
(colorMode === 'system' && colorScheme === 'light') ||
|
||||||
|
colorMode === 'light'
|
||||||
|
) {
|
||||||
|
return 'light'
|
||||||
|
} else {
|
||||||
|
return darkTheme ?? 'dim'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDocument(theme: ThemeName) {
|
function updateDocument(theme: ThemeName) {
|
||||||
|
|
|
@ -20,36 +20,38 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
const [colorMode, setColorMode] = React.useState(persisted.get('colorMode'))
|
const [colorMode, setColorMode] = React.useState(persisted.get('colorMode'))
|
||||||
const [darkTheme, setDarkTheme] = React.useState(persisted.get('darkTheme'))
|
const [darkTheme, setDarkTheme] = React.useState(persisted.get('darkTheme'))
|
||||||
|
|
||||||
const setColorModeWrapped = React.useCallback(
|
const stateContextValue = React.useMemo(
|
||||||
(_colorMode: persisted.Schema['colorMode']) => {
|
() => ({
|
||||||
setColorMode(_colorMode)
|
colorMode,
|
||||||
persisted.write('colorMode', _colorMode)
|
darkTheme,
|
||||||
},
|
}),
|
||||||
[setColorMode],
|
[colorMode, darkTheme],
|
||||||
)
|
)
|
||||||
|
|
||||||
const setDarkThemeWrapped = React.useCallback(
|
const setContextValue = React.useMemo(
|
||||||
(_darkTheme: persisted.Schema['darkTheme']) => {
|
() => ({
|
||||||
setDarkTheme(_darkTheme)
|
setColorMode: (_colorMode: persisted.Schema['colorMode']) => {
|
||||||
persisted.write('darkTheme', _darkTheme)
|
setColorMode(_colorMode)
|
||||||
},
|
persisted.write('colorMode', _colorMode)
|
||||||
[setDarkTheme],
|
},
|
||||||
|
setDarkTheme: (_darkTheme: persisted.Schema['darkTheme']) => {
|
||||||
|
setDarkTheme(_darkTheme)
|
||||||
|
persisted.write('darkTheme', _darkTheme)
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
return persisted.onUpdate(() => {
|
return persisted.onUpdate(() => {
|
||||||
setColorModeWrapped(persisted.get('colorMode'))
|
setColorMode(persisted.get('colorMode'))
|
||||||
setDarkThemeWrapped(persisted.get('darkTheme'))
|
setDarkTheme(persisted.get('darkTheme'))
|
||||||
})
|
})
|
||||||
}, [setColorModeWrapped, setDarkThemeWrapped])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<stateContext.Provider value={{colorMode, darkTheme}}>
|
<stateContext.Provider value={stateContextValue}>
|
||||||
<setContext.Provider
|
<setContext.Provider value={setContextValue}>
|
||||||
value={{
|
|
||||||
setDarkTheme: setDarkThemeWrapped,
|
|
||||||
setColorMode: setColorModeWrapped,
|
|
||||||
}}>
|
|
||||||
{children}
|
{children}
|
||||||
</setContext.Provider>
|
</setContext.Provider>
|
||||||
</stateContext.Provider>
|
</stateContext.Provider>
|
||||||
|
|
Loading…
Reference in New Issue