From f3cf10e5e64adeda20667aae78f6dad49926618f Mon Sep 17 00:00:00 2001 From: MinhNN Date: Mon, 17 Nov 2025 19:55:53 +0700 Subject: [PATCH] fix theme system --- hooks/use-theme-context.tsx | 68 ++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/hooks/use-theme-context.tsx b/hooks/use-theme-context.tsx index 2b65ee5..0077a0a 100644 --- a/hooks/use-theme-context.tsx +++ b/hooks/use-theme-context.tsx @@ -14,7 +14,10 @@ import { useState, ReactNode, } from "react"; -import { useColorScheme as useSystemColorScheme } from "react-native"; +import { + useColorScheme as useSystemColorScheme, + Appearance, +} from "react-native"; type ThemeMode = "light" | "dark" | "system"; type ColorScheme = "light" | "dark"; @@ -32,23 +35,64 @@ const ThemeContext = createContext(undefined); const THEME_STORAGE_KEY = "theme_mode"; export function ThemeProvider({ children }: { children: ReactNode }) { - // Dùng useColorScheme từ react-native để detect theme thiết bị - const deviceColorScheme = useSystemColorScheme(); // "light" | "dark" | null | undefined + // State để force re-render khi system theme thay đổi + const [systemTheme, setSystemTheme] = useState(() => { + const current = Appearance.getColorScheme(); + console.log("[Theme] Initial system theme:", current); + return current === "dark" ? "dark" : "light"; + }); // State lưu user's choice (light/dark/system) const [themeMode, setThemeModeState] = useState("system"); const [isLoaded, setIsLoaded] = useState(false); + // Listen vào system theme changes - đăng ký ngay từ đầu + useEffect(() => { + console.log("[Theme] Registering appearance listener"); + + const subscription = Appearance.addChangeListener(({ colorScheme }) => { + const newScheme = colorScheme === "dark" ? "dark" : "light"; + console.log( + "[Theme] System theme changed to:", + newScheme, + "at", + new Date().toLocaleTimeString() + ); + setSystemTheme(newScheme); + }); + + // Double check current theme khi mount + const currentScheme = Appearance.getColorScheme(); + const current = currentScheme === "dark" ? "dark" : "light"; + if (current !== systemTheme) { + console.log("[Theme] Syncing system theme on mount:", current); + setSystemTheme(current); + } + + return () => { + console.log("[Theme] Removing appearance listener"); + subscription.remove(); + }; + }, []); + // Xác định colorScheme cuối cùng const colorScheme: ColorScheme = - themeMode === "system" - ? deviceColorScheme === "dark" - ? "dark" - : "light" - : themeMode; + themeMode === "system" ? systemTheme : themeMode; const colors = Colors[colorScheme]; + // Log để debug + useEffect(() => { + console.log( + "[Theme] Current state - Mode:", + themeMode, + "| Scheme:", + colorScheme, + "| System:", + systemTheme + ); + }, [themeMode, colorScheme, systemTheme]); + useEffect(() => { const loadThemeMode = async () => { try { @@ -85,17 +129,15 @@ export function ThemeProvider({ children }: { children: ReactNode }) { // Chờ theme load xong trước khi render if (!isLoaded) { // Render với default theme (system) khi đang load - const defaultScheme: ColorScheme = - deviceColorScheme === "dark" ? "dark" : "light"; return ( {}, getColor: (colorName: ColorName) => - Colors[defaultScheme][colorName] || Colors[defaultScheme].text, + Colors[systemTheme][colorName] || Colors[systemTheme].text, }} > {children}