fix theme system

This commit is contained in:
2025-11-17 19:55:53 +07:00
parent 862c4e42a4
commit f3cf10e5e6

View File

@@ -14,7 +14,10 @@ import {
useState, useState,
ReactNode, ReactNode,
} from "react"; } from "react";
import { useColorScheme as useSystemColorScheme } from "react-native"; import {
useColorScheme as useSystemColorScheme,
Appearance,
} from "react-native";
type ThemeMode = "light" | "dark" | "system"; type ThemeMode = "light" | "dark" | "system";
type ColorScheme = "light" | "dark"; type ColorScheme = "light" | "dark";
@@ -32,23 +35,64 @@ const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
const THEME_STORAGE_KEY = "theme_mode"; const THEME_STORAGE_KEY = "theme_mode";
export function ThemeProvider({ children }: { children: ReactNode }) { export function ThemeProvider({ children }: { children: ReactNode }) {
// Dùng useColorScheme từ react-native để detect theme thiết bị // State để force re-render khi system theme thay đổi
const deviceColorScheme = useSystemColorScheme(); // "light" | "dark" | null | undefined const [systemTheme, setSystemTheme] = useState<ColorScheme>(() => {
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) // State lưu user's choice (light/dark/system)
const [themeMode, setThemeModeState] = useState<ThemeMode>("system"); const [themeMode, setThemeModeState] = useState<ThemeMode>("system");
const [isLoaded, setIsLoaded] = useState(false); 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 // Xác định colorScheme cuối cùng
const colorScheme: ColorScheme = const colorScheme: ColorScheme =
themeMode === "system" themeMode === "system" ? systemTheme : themeMode;
? deviceColorScheme === "dark"
? "dark"
: "light"
: themeMode;
const colors = Colors[colorScheme]; const colors = Colors[colorScheme];
// Log để debug
useEffect(() => {
console.log(
"[Theme] Current state - Mode:",
themeMode,
"| Scheme:",
colorScheme,
"| System:",
systemTheme
);
}, [themeMode, colorScheme, systemTheme]);
useEffect(() => { useEffect(() => {
const loadThemeMode = async () => { const loadThemeMode = async () => {
try { try {
@@ -85,17 +129,15 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
// Chờ theme load xong trước khi render // Chờ theme load xong trước khi render
if (!isLoaded) { if (!isLoaded) {
// Render với default theme (system) khi đang load // Render với default theme (system) khi đang load
const defaultScheme: ColorScheme =
deviceColorScheme === "dark" ? "dark" : "light";
return ( return (
<ThemeContext.Provider <ThemeContext.Provider
value={{ value={{
themeMode: "system", themeMode: "system",
colorScheme: defaultScheme, colorScheme: systemTheme,
colors: Colors[defaultScheme], colors: Colors[systemTheme],
setThemeMode: async () => {}, setThemeMode: async () => {},
getColor: (colorName: ColorName) => getColor: (colorName: ColorName) =>
Colors[defaultScheme][colorName] || Colors[defaultScheme].text, Colors[systemTheme][colorName] || Colors[systemTheme].text,
}} }}
> >
{children} {children}