Files
mobile-darmasaba/providers/ThemeProvider.tsx
amaliadwiy d3802ca26c upd: redesign
Deskripsi:
- fitur ganti mode tema
- penerapan tema pada semua fitur

NO Issues
2026-02-09 17:49:25 +08:00

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>
);
}