import { DarkTheme as NavigationDarkTheme, DefaultTheme as NavigationDefaultTheme, NavigationContainer, } from "@react-navigation/native"; import React, { useEffect, useMemo, useState } from "react"; import { useColorScheme } from "react-native"; import { MD3DarkTheme as PaperDarkTheme, MD3LightTheme as PaperDefaultTheme, ProgressBar, Provider as PaperProvider, Snackbar, } from "react-native-paper"; import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons"; import AppStack from "./AppStack"; import { AppDataSource } from "./data-source"; import { settingsRepo } from "./db"; import { emitter } from "./emitter"; import { TickEvent } from "./TimerPage"; import { TOAST } from "./toast"; import { ThemeContext } from "./use-theme"; export const CombinedDefaultTheme = { ...NavigationDefaultTheme, ...PaperDefaultTheme, colors: { ...NavigationDefaultTheme.colors, ...PaperDefaultTheme.colors, }, }; export const CombinedDarkTheme = { ...NavigationDarkTheme, ...PaperDarkTheme, colors: { ...NavigationDarkTheme.colors, ...PaperDarkTheme.colors, }, }; const App = () => { const phoneTheme = useColorScheme(); const [initialized, setInitialized] = useState(false); const [snackbar, setSnackbar] = useState(""); const [appTheme, setAppTheme] = useState("system"); const [progress, setProgress] = useState(0); const [lightColor, setLightColor] = useState( CombinedDefaultTheme.colors.primary ); const [darkColor, setDarkColor] = useState( CombinedDarkTheme.colors.primary ); useEffect(() => { (async () => { if (!AppDataSource.isInitialized) await AppDataSource.initialize(); const settings = await settingsRepo.findOne({ where: {} }); setAppTheme(settings.theme); if (settings.lightColor) setLightColor(settings.lightColor); if (settings.darkColor) setDarkColor(settings.darkColor); setInitialized(true); })(); const descriptions = [ emitter.addListener(TOAST, ({ value }: { value: string }) => { setSnackbar(value); }), emitter.addListener("tick", (event: TickEvent) => { setProgress((Number(event.minutes) * 60 + Number(event.seconds)) / 210); }), ]; return () => descriptions.forEach((description) => description.remove()); }, []); const paperTheme = useMemo(() => { const darkTheme = lightColor ? { ...CombinedDarkTheme, colors: { ...CombinedDarkTheme.colors, primary: darkColor }, } : CombinedDarkTheme; const lightTheme = lightColor ? { ...CombinedDefaultTheme, colors: { ...CombinedDefaultTheme.colors, primary: lightColor }, } : CombinedDefaultTheme; let value = phoneTheme === "dark" ? darkTheme : lightTheme; if (appTheme === "dark") value = darkTheme; else if (appTheme === "light") value = lightTheme; return value; }, [phoneTheme, appTheme, lightColor, darkColor]); return ( }} > {initialized && ( )} setSnackbar("")} visible={!!snackbar} action={{ label: "Close", onPress: () => setSnackbar(""), textColor: paperTheme.colors.background, }} > {snackbar} {progress > 0 && } ); }; export default App;