diff --git a/src/App.tsx b/src/App.tsx index 4c1d5c2..654ea03 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -40,18 +40,6 @@ import { credentialsSelector } from './login'; import { History } from 'history'; -const muiTheme = createMuiTheme({ - palette: { - primary: amber, - secondary: { - light: lightBlue.A200, - main: lightBlue.A400, - dark: lightBlue.A700, - contrastText: '#fff', - }, - }, -}); - export const routeResolver = new RouteResolver({ home: '', pim: { @@ -179,6 +167,7 @@ class App extends React.PureComponent { credentials: store.CredentialsData; entries: store.EntriesData; fetchCount: number; + darkMode: boolean; errors: ImmutableList; }; @@ -197,6 +186,19 @@ class App extends React.PureComponent { const errors = this.props.errors; const fetching = this.props.fetchCount > 0; + const muiTheme = createMuiTheme({ + palette: { + type: this.props.darkMode ? 'dark' : undefined, + primary: amber, + secondary: { + light: lightBlue.A200, + main: lightBlue.A400, + dark: lightBlue.A700, + contrastText: '#fff', + }, + }, + }); + const styles = { main: { backgroundColor: muiTheme.palette.background.default, @@ -283,6 +285,7 @@ const mapStateToProps = (state: store.StoreState) => { credentials: credentialsSelector(state), entries: state.cache.entries, fetchCount: state.fetchCount, + darkMode: !!state.settings.darkMode, errors: state.errors, }; }; diff --git a/src/Settings/index.tsx b/src/Settings/index.tsx index af38472..c33a779 100644 --- a/src/Settings/index.tsx +++ b/src/Settings/index.tsx @@ -2,14 +2,17 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { useSelector } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; import Select from '@material-ui/core/Select'; import MenuItem from '@material-ui/core/MenuItem'; import FormControl from '@material-ui/core/FormControl'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormGroup from '@material-ui/core/FormGroup'; +import Switch from '@material-ui/core/Switch'; import InputLabel from '@material-ui/core/InputLabel'; -import { store, StoreState } from '../store'; +import { StoreState } from '../store'; import { setSettings } from '../store/actions'; import Container from '../widgets/Container'; @@ -36,13 +39,16 @@ function SecurityFingerprint() { } export default React.memo(function Settings() { + const dispatch = useDispatch(); const settings = useSelector((state: StoreState) => state.settings); + const darkMode = !!settings.darkMode; + function handleChange(event: React.ChangeEvent) { const name = event.target.name; const value = event.target.value; - store.dispatch(setSettings({ ...settings, [name]: value })); + dispatch(setSettings({ ...settings, [name]: value })); } return ( @@ -65,6 +71,20 @@ export default React.memo(function Settings() { English (United States) +

Experimental

+

Dark mode

+ + dispatch(setSettings({ ...settings, darkMode: !darkMode }))} + /> + } + label="Dark mode" + /> + ); diff --git a/src/store/reducers.ts b/src/store/reducers.ts index 3915146..295ad99 100644 --- a/src/store/reducers.ts +++ b/src/store/reducers.ts @@ -272,6 +272,7 @@ export const errorsReducer = handleActions( // FIXME Move all the below (potentially the fetchCount ones too) to their own file export interface SettingsType { locale: string; + darkMode?: boolean; taskSettings: { filterBy: string | null; sortBy: string; @@ -286,6 +287,7 @@ export const settingsReducer = handleActions( }, { locale: 'en-gb', + darkMode: false, taskSettings: { filterBy: null, sortBy: 'smart',