Use brower preference and persist theme mode

Sascha created

Change summary

webui/src/components/Themer.tsx | 39 +++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 13 deletions(-)

Detailed changes

webui/src/components/Themer.tsx 🔗

@@ -1,12 +1,12 @@
-import React, { createContext, useCallback, useContext, useState } from 'react';
+import React, { createContext, useContext, useState } from 'react';
 
-import { ThemeProvider } from '@material-ui/core';
+import { PaletteType, ThemeProvider, useMediaQuery } from '@material-ui/core';
 import IconButton from '@material-ui/core/IconButton/IconButton';
 import Tooltip from '@material-ui/core/Tooltip/Tooltip';
-import { createMuiTheme, ThemeOptions } from '@material-ui/core/styles';
+import { createMuiTheme } from '@material-ui/core/styles';
 import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons';
 
-const defaultTheme: ThemeOptions = {
+const defaultTheme = {
   palette: {
     type: 'light',
     primary: {
@@ -39,24 +39,37 @@ const LightSwitch = () => {
 type Props = { children: React.ReactNode };
 const Themer = ({ children }: Props) => {
   const [theme, setTheme] = useState(defaultTheme);
+  const preferseDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
+  const browserMode = preferseDarkMode ? 'dark' : 'light';
+  const preferedMode = localStorage.getItem('themeMode');
+  const curMode = preferedMode != null ? preferedMode : browserMode;
 
-  const toggleMode = useCallback(() => {
-    const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark';
-    const adjustedTheme: ThemeOptions = {
+  const adjustedTheme = {
+    ...theme,
+    palette: {
+      ...theme.palette,
+      type: (curMode === 'dark' ? 'dark' : 'light') as PaletteType,
+    },
+  };
+
+  const toggleMode = () => {
+    const preferedMode = curMode === 'dark' ? 'light' : 'dark';
+    localStorage.setItem('themeMode', preferedMode);
+    const adjustedTheme = {
       ...theme,
       palette: {
         ...theme.palette,
-        type: newMode,
+        type: preferedMode as PaletteType,
       },
     };
     setTheme(adjustedTheme);
-  }, [theme, setTheme]);
-
-  const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark';
+  };
 
   return (
-    <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: newMode }}>
-      <ThemeProvider theme={createMuiTheme(theme)}> {children} </ThemeProvider>
+    <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: curMode }}>
+      <ThemeProvider theme={createMuiTheme(adjustedTheme)}>
+        {children}
+      </ThemeProvider>
     </ThemeContext.Provider>
   );
 };