This repository has been archived on 2026-04-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
interaktive-systeme/app/contexts/ThemeContext.tsx
2023-12-17 19:25:06 +01:00

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