diff --git a/package.json b/package.json
index 794478f..a49039d 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
},
"private": true,
"dependencies": {
+ "@flare/js-utils": "^1.0.3",
"@flare/tuitio-client-react": "^1.0.1",
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
diff --git a/src/features/machines/components/MachinesContainer.js b/src/features/machines/components/MachinesContainer.js
index 5708861..20cf0d6 100644
--- a/src/features/machines/components/MachinesContainer.js
+++ b/src/features/machines/components/MachinesContainer.js
@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useCallback } from "react";
import {
ApplicationStateContext,
ApplicationDispatchContext
-} from "../../../state/ApplicationContexts";
+} from "../../../state/contexts";
import useApi from "../../../api";
import MachinesList from "./MachinesList";
import PageTitle from "../../../components/common/PageTitle";
diff --git a/src/features/settings/components/SettingsContainer.js b/src/features/settings/components/SettingsContainer.js
index 8eebf7e..bace773 100644
--- a/src/features/settings/components/SettingsContainer.js
+++ b/src/features/settings/components/SettingsContainer.js
@@ -1,8 +1,14 @@
import React from "react";
import LanguageContainer from "./language/LanguageContainer";
+import ThemeSettings from "./ThemeSettings";
const SettingsContainer = () => {
- return ;
+ return (
+ <>
+
+
+ >
+ );
};
export default SettingsContainer;
diff --git a/src/features/settings/components/ThemeSettings.js b/src/features/settings/components/ThemeSettings.js
new file mode 100644
index 0000000..cf522d3
--- /dev/null
+++ b/src/features/settings/components/ThemeSettings.js
@@ -0,0 +1,23 @@
+import React from "react";
+import { useApplicationTheme } from "../../../providers/ThemeProvider";
+import { Switch } from "@material-ui/core";
+
+const ThemeSettings = () => {
+ const { isDark, onDarkModeChanged } = useApplicationTheme();
+
+ const handleChange = event => {
+ const { checked } = event.target;
+ onDarkModeChanged(checked);
+ };
+
+ return (
+
+ );
+};
+
+export default ThemeSettings;
diff --git a/src/index.js b/src/index.js
index 6fdef0e..2dc491a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,6 @@
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
-import { ThemeProvider } from "@material-ui/styles";
-import Themes from "./themes";
+import ThemeProvider from "./providers/ThemeProvider";
import CssBaseline from "@material-ui/core/CssBaseline";
import App from "./components/App";
import { TuitioProvider } from "@flare/tuitio-client-react";
@@ -12,7 +11,7 @@ import "./utils/i18n";
ReactDOM.render(
-
+
Loading...}>
diff --git a/src/providers/ApplicationStateProvider.js b/src/providers/ApplicationStateProvider.js
index 9c27ec0..071541f 100644
--- a/src/providers/ApplicationStateProvider.js
+++ b/src/providers/ApplicationStateProvider.js
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import {
ApplicationStateContext,
ApplicationDispatchContext
-} from "../state/ApplicationContexts";
+} from "../state/contexts";
import {
reducer,
dispatchActions as reducerDispatchActions
diff --git a/src/providers/ThemeProvider.js b/src/providers/ThemeProvider.js
new file mode 100644
index 0000000..bcbef66
--- /dev/null
+++ b/src/providers/ThemeProvider.js
@@ -0,0 +1,82 @@
+import React, { useReducer, useMemo, useContext } from "react";
+import PropTypes from "prop-types";
+import { ThemeProvider as MuiThemeProvider } from "@material-ui/styles";
+import { localStorage } from "@flare/js-utils";
+import { getThemes } from "../themes";
+
+const ApplicationThemeContext = React.createContext();
+const LOCAL_STORAGE_COLOR_SCHEME_KEY = "network-resurrector-color-scheme";
+
+const COLOR_SCHEME = {
+ LIGHT: "light",
+ DARK: "dark"
+};
+
+const colorScheme = localStorage.getItem(LOCAL_STORAGE_COLOR_SCHEME_KEY);
+const prefersDarkMode = window.matchMedia(
+ "(prefers-color-scheme: dark)"
+).matches;
+
+const initialState = {
+ scheme:
+ colorScheme ?? (prefersDarkMode ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT)
+};
+
+const reducer = (state = initialState, action) => {
+ switch (action.type) {
+ case "onColorSchemeChanged": {
+ return {
+ ...state,
+ scheme: action.scheme
+ };
+ }
+ default: {
+ return state;
+ }
+ }
+};
+
+const dispatchActions = dispatch => ({
+ onColorSchemeChanged: scheme => {
+ dispatch({ type: "onColorSchemeChanged", scheme });
+ localStorage.setItem(LOCAL_STORAGE_COLOR_SCHEME_KEY, scheme);
+ }
+});
+
+const useApplicationTheme = () => {
+ const { state, actions } = useContext(ApplicationThemeContext);
+ const { onColorSchemeChanged } = actions;
+
+ const { scheme } = state;
+ const onDarkModeChanged = active =>
+ onColorSchemeChanged(active ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT);
+
+ return { isDark: scheme === COLOR_SCHEME.DARK, onDarkModeChanged };
+};
+
+const ThemeProvider = ({ children }) => {
+ const [state, dispatch] = useReducer(reducer, initialState);
+ const actions = useMemo(() => dispatchActions(dispatch), [dispatch]);
+ const themes = useMemo(
+ () => getThemes(state.scheme === COLOR_SCHEME.DARK),
+ [state.scheme]
+ );
+
+ return (
+
+ {children}
+
+ );
+};
+
+ThemeProvider.propTypes = {
+ children: PropTypes.node.isRequired
+};
+
+export { ThemeProvider, ApplicationThemeContext, useApplicationTheme };
+export default ThemeProvider;
diff --git a/src/state/ApplicationContexts.js b/src/state/contexts.js
similarity index 100%
rename from src/state/ApplicationContexts.js
rename to src/state/contexts.js
diff --git a/src/themes/index.js b/src/themes/index.js
index a0830ec..07216c2 100644
--- a/src/themes/index.js
+++ b/src/themes/index.js
@@ -1,12 +1,7 @@
import defaultTheme from "./default";
import { createTheme } from "@material-ui/core/styles";
-const prefersDarkMode = false;
-
const overrides = {
- palette: {
- type: prefersDarkMode ? "dark" : "light"
- },
typography: {
h1: {
fontSize: "3rem"
@@ -29,12 +24,16 @@ const overrides = {
}
};
-const themes = {
- default: createTheme({
- ...defaultTheme,
- ...overrides,
- palette: { ...defaultTheme.palette, ...overrides.palette }
- })
+const getThemes = darkMode => {
+ const type = darkMode ? "dark" : "light";
+
+ return {
+ default: createTheme({
+ ...defaultTheme,
+ ...overrides,
+ palette: { ...defaultTheme.palette, type }
+ })
+ };
};
-export default themes;
+export { getThemes };