fix theme system
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user