Deskripsi: - fitur ganti mode tema - penerapan tema pada semua fitur NO Issues
67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react';
|
|
import { useColorScheme } from 'react-native';
|
|
import { Colors } from '@/constants/Colors';
|
|
|
|
type Theme = 'light' | 'dark' | 'system';
|
|
type StartTheme = 'light' | 'dark';
|
|
|
|
interface ThemeContextType {
|
|
theme: Theme;
|
|
activeTheme: StartTheme;
|
|
setTheme: (theme: Theme) => void;
|
|
colors: typeof Colors.light;
|
|
}
|
|
|
|
const ThemeContext = createContext<ThemeContextType>({
|
|
theme: 'system',
|
|
activeTheme: 'light',
|
|
setTheme: () => { },
|
|
colors: Colors.light,
|
|
});
|
|
|
|
export const useTheme = () => useContext(ThemeContext);
|
|
|
|
export default function ThemeProvider({ children }: { children: ReactNode }) {
|
|
const systemColorScheme = useColorScheme();
|
|
const [theme, setThemeState] = useState<Theme>('system');
|
|
const [isReady, setIsReady] = useState(false);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
try {
|
|
const storedTheme = await AsyncStorage.getItem('@theme');
|
|
if (storedTheme) {
|
|
setThemeState(storedTheme as Theme);
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to load theme', e);
|
|
} finally {
|
|
setIsReady(true);
|
|
}
|
|
})();
|
|
}, []);
|
|
|
|
const setTheme = async (newTheme: Theme) => {
|
|
setThemeState(newTheme);
|
|
try {
|
|
await AsyncStorage.setItem('@theme', newTheme);
|
|
} catch (e) {
|
|
console.error('Failed to save theme', e);
|
|
}
|
|
};
|
|
|
|
if (!isReady) {
|
|
return null;
|
|
}
|
|
|
|
const activeTheme = theme === 'system' ? (systemColorScheme || 'light') : theme;
|
|
const colors = Colors[activeTheme];
|
|
|
|
return (
|
|
<ThemeContext.Provider value={{ theme, activeTheme, setTheme, colors }}>
|
|
{children}
|
|
</ThemeContext.Provider>
|
|
);
|
|
}
|