about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2023-09-15 11:06:06 -0500
committerGitHub <noreply@github.com>2023-09-15 11:06:06 -0500
commit84b7edd9db4bb08f03b5c882da5542fc29a72232 (patch)
treee94fbc4db01d25247e42683f2a74292ab09143d2 /src
parent50f811666aa8999bd7c6cf0c823437f23ddce4c6 (diff)
parent0e8d564555d23bb2161fd8c96c3eef5bb7f04889 (diff)
downloadvoidsky-84b7edd9db4bb08f03b5c882da5542fc29a72232.tar.zst
Merge pull request #1451 from bluesky-social/eric/theme-switching-web
fix theme switching on web without refresh
Diffstat (limited to 'src')
-rw-r--r--src/lib/ThemeContext.tsx54
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>
+  )
 }