97 lines
2.7 KiB
TypeScript
97 lines
2.7 KiB
TypeScript
import {useContext, createContext, useState, useEffect} from "react"
|
|
import AsyncStorage from "@react-native-async-storage/async-storage"
|
|
import { useColorScheme } from "react-native";
|
|
import themeColors from "../../constants/colors";
|
|
|
|
|
|
interface ThemeProps {
|
|
isSystemTheme?: boolean
|
|
theme: "light" | "dark";
|
|
colors: typeof themeColors.light & typeof themeColors.dark;
|
|
applySystemTheme?: () => void;
|
|
applyTheme?: (theme: "light" | "dark") => void;
|
|
}
|
|
|
|
const THEME_KEY = "THEME"
|
|
const SYSTEM_THEME_KEY = "SYSTEM_THEME"
|
|
|
|
const ThemeContext = createContext<ThemeProps>({theme: "light", colors: themeColors.light})
|
|
|
|
export const useTheme = () => {
|
|
return useContext(ThemeContext)
|
|
}
|
|
|
|
export const ThemeProvider = ({children} : any) => {
|
|
const currentSystemTheme = useColorScheme()
|
|
const [isSystemTheme, setIsSystemTheme] = useState<boolean>(true);
|
|
const [theme, setTheme] = useState<"light" | "dark">("light");
|
|
const [colors, setColors] = useState<typeof themeColors.light & typeof themeColors.dark>(themeColors.light)
|
|
|
|
useEffect(() => {
|
|
console.log("effect called")
|
|
const loadTheme = async () => {
|
|
try {
|
|
const is_system_theme = await AsyncStorage.getItem(SYSTEM_THEME_KEY)
|
|
const saved_theme = await AsyncStorage.getItem(THEME_KEY);
|
|
|
|
if(is_system_theme !== "false"){//We will use !== false bacause system theme should be used if unspecified
|
|
applySystemTheme();
|
|
return;
|
|
}
|
|
|
|
if(saved_theme === "light" || saved_theme === "dark"){
|
|
applyTheme(saved_theme);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
loadTheme();
|
|
}, [currentSystemTheme])
|
|
|
|
|
|
const applySystemTheme = () => {
|
|
const storeSystemTheme = async () => {
|
|
console.log("applySystemTheme")
|
|
await AsyncStorage.setItem(SYSTEM_THEME_KEY, "true")
|
|
}
|
|
|
|
storeSystemTheme();
|
|
setIsSystemTheme(true)
|
|
applyThemeInternal(currentSystemTheme ?? "light")
|
|
}
|
|
|
|
const applyThemeInternal = (theme: "light" | "dark") => {
|
|
const storeTheme = async (theme: "light" | "dark") => {
|
|
await AsyncStorage.setItem(THEME_KEY, theme)
|
|
}
|
|
|
|
setTheme(theme);
|
|
storeTheme(theme);
|
|
setColors(themeColors[theme])
|
|
}
|
|
|
|
const applyTheme = (theme: "light" | "dark") => {
|
|
const unsetSytemTheme = async () => {
|
|
AsyncStorage.setItem(SYSTEM_THEME_KEY, "false");
|
|
}
|
|
unsetSytemTheme()
|
|
setIsSystemTheme(false);
|
|
applyThemeInternal(theme);
|
|
}
|
|
|
|
const value = {
|
|
isSystemTheme: isSystemTheme,
|
|
applyTheme: applyTheme,
|
|
applySystemTheme: applySystemTheme,
|
|
theme: theme,
|
|
colors: colors,
|
|
}
|
|
|
|
return (
|
|
<ThemeContext.Provider value={value}>
|
|
{children}
|
|
</ThemeContext.Provider>
|
|
)
|
|
}
|