mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 11:15:53 +08:00
Add system default as dark theme preference option
This commit is contained in:
parent
e7cfbc6bf7
commit
b3beef97df
@ -131,7 +131,7 @@ const useStyles = (theme: Theme) =>
|
|||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
snackbar: state.snackbar,
|
snackbar: state.snackbar,
|
||||||
isDarkTheme: state.settings.isDarkTheme,
|
themePreference: state.settings.themePreference,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ function SlideUpTransition(props: TransitionProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function App(props: ConnectedProps<typeof connector>) {
|
function App(props: ConnectedProps<typeof connector>) {
|
||||||
const theme = makeTheme(props.isDarkTheme);
|
const theme = makeTheme(props.themePreference);
|
||||||
const classes = useStyles(theme)();
|
const classes = useStyles(theme)();
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const toggleDrawer = () => setOpen(!open);
|
const toggleDrawer = () => setOpen(!open);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import { ThemePreference } from "../reducers/settingsReducer";
|
||||||
|
|
||||||
// List of settings related action types.
|
// List of settings related action types.
|
||||||
export const POLL_INTERVAL_CHANGE = 'POLL_INTERVAL_CHANGE';
|
export const POLL_INTERVAL_CHANGE = "POLL_INTERVAL_CHANGE";
|
||||||
export const TOGGLE_DARK_THEME = 'TOGGLE_DARK_THEME';
|
export const THEME_PREFERENCE_CHANGE = "THEME_PREFERENCE_CHANGE";
|
||||||
|
|
||||||
interface PollIntervalChangeAction {
|
interface PollIntervalChangeAction {
|
||||||
type: typeof POLL_INTERVAL_CHANGE;
|
type: typeof POLL_INTERVAL_CHANGE;
|
||||||
@ -8,11 +10,14 @@ interface PollIntervalChangeAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ToggleDarkThemeAction {
|
interface ToggleDarkThemeAction {
|
||||||
type: typeof TOGGLE_DARK_THEME;
|
type: typeof THEME_PREFERENCE_CHANGE;
|
||||||
|
value: ThemePreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Union of all settings related action types.
|
// Union of all settings related action types.
|
||||||
export type SettingsActionTypes = PollIntervalChangeAction | ToggleDarkThemeAction;
|
export type SettingsActionTypes =
|
||||||
|
| PollIntervalChangeAction
|
||||||
|
| ToggleDarkThemeAction;
|
||||||
|
|
||||||
export function pollIntervalChange(value: number) {
|
export function pollIntervalChange(value: number) {
|
||||||
return {
|
return {
|
||||||
@ -21,9 +26,9 @@ export function pollIntervalChange(value: number) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toggleDarkTheme() {
|
export function selectTheme(value: ThemePreference) {
|
||||||
return {
|
return {
|
||||||
type: TOGGLE_DARK_THEME
|
type: THEME_PREFERENCE_CHANGE,
|
||||||
|
value,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import {
|
import {
|
||||||
POLL_INTERVAL_CHANGE,
|
POLL_INTERVAL_CHANGE,
|
||||||
SettingsActionTypes,
|
SettingsActionTypes,
|
||||||
TOGGLE_DARK_THEME,
|
THEME_PREFERENCE_CHANGE,
|
||||||
} from "../actions/settingsActions";
|
} from "../actions/settingsActions";
|
||||||
|
|
||||||
|
export enum ThemePreference {
|
||||||
|
SystemDefault,
|
||||||
|
Always,
|
||||||
|
Never,
|
||||||
|
}
|
||||||
interface SettingsState {
|
interface SettingsState {
|
||||||
pollInterval: number;
|
pollInterval: number;
|
||||||
isDarkTheme: boolean;
|
themePreference: ThemePreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SettingsState = {
|
const initialState: SettingsState = {
|
||||||
pollInterval: 8,
|
pollInterval: 8,
|
||||||
isDarkTheme: true,
|
themePreference: ThemePreference.SystemDefault,
|
||||||
};
|
};
|
||||||
|
|
||||||
function settingsReducer(
|
function settingsReducer(
|
||||||
@ -21,10 +26,10 @@ function settingsReducer(
|
|||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case POLL_INTERVAL_CHANGE:
|
case POLL_INTERVAL_CHANGE:
|
||||||
return { ...state, pollInterval: action.value };
|
return { ...state, pollInterval: action.value };
|
||||||
case TOGGLE_DARK_THEME:
|
case THEME_PREFERENCE_CHANGE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isDarkTheme: !state.isDarkTheme,
|
themePreference: action.value,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import { createMuiTheme, Theme } from "@material-ui/core/styles";
|
import { createMuiTheme, Theme } from "@material-ui/core/styles";
|
||||||
|
import { ThemePreference } from "./reducers/settingsReducer";
|
||||||
|
import useMediaQuery from "@material-ui/core/useMediaQuery";
|
||||||
|
|
||||||
export function makeTheme(isDarkTheme: boolean): Theme {
|
export function makeTheme(themePreference: ThemePreference): Theme {
|
||||||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
let prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
|
||||||
|
if (themePreference === ThemePreference.Always) {
|
||||||
|
prefersDarkMode = true;
|
||||||
|
} else if (themePreference === ThemePreference.Never) {
|
||||||
|
prefersDarkMode = false;
|
||||||
|
}
|
||||||
return createMuiTheme({
|
return createMuiTheme({
|
||||||
// Got color palette from https://htmlcolors.com/palette/31/stripe
|
// Got color palette from https://htmlcolors.com/palette/31/stripe
|
||||||
palette: {
|
palette: {
|
||||||
@ -13,7 +22,7 @@ export function makeTheme(isDarkTheme: boolean): Theme {
|
|||||||
background: {
|
background: {
|
||||||
default: "#f5f7f9",
|
default: "#f5f7f9",
|
||||||
},
|
},
|
||||||
type: isDarkTheme ? "dark" : "light",
|
type: prefersDarkMode ? "dark" : "light",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect, ConnectedProps } from "react-redux";
|
import { connect, ConnectedProps } from "react-redux";
|
||||||
import Container from "@material-ui/core/Container";
|
import Container from "@material-ui/core/Container";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles, useTheme, Theme } from "@material-ui/core/styles";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Card from "@material-ui/core/Card";
|
import Card from "@material-ui/core/Card";
|
||||||
@ -31,7 +31,7 @@ function mapStateToProps(state: AppState) {
|
|||||||
redisAddress: state.redis.address,
|
redisAddress: state.redis.address,
|
||||||
redisInfoRaw: state.redis.rawData,
|
redisInfoRaw: state.redis.rawData,
|
||||||
pollInterval: state.settings.pollInterval,
|
pollInterval: state.settings.pollInterval,
|
||||||
isDarkTheme: state.settings.isDarkTheme,
|
themePreference: state.settings.themePreference,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,14 +40,9 @@ type Props = ConnectedProps<typeof connector>;
|
|||||||
|
|
||||||
function RedisInfoView(props: Props) {
|
function RedisInfoView(props: Props) {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const {
|
const { pollInterval, getRedisInfoAsync, redisInfo, redisInfoRaw } = props;
|
||||||
pollInterval,
|
const theme = useTheme<Theme>();
|
||||||
getRedisInfoAsync,
|
const isDarkTheme = theme.palette.type === "dark";
|
||||||
redisInfo,
|
|
||||||
redisInfoRaw,
|
|
||||||
isDarkTheme,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
usePolling(getRedisInfoAsync, pollInterval);
|
usePolling(getRedisInfoAsync, pollInterval);
|
||||||
|
|
||||||
// Metrics to show
|
// Metrics to show
|
||||||
|
@ -5,15 +5,14 @@ import { makeStyles } from "@material-ui/core/styles";
|
|||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Paper from "@material-ui/core/Paper";
|
import Paper from "@material-ui/core/Paper";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Switch from "@material-ui/core/Switch";
|
|
||||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
|
||||||
import FormGroup from "@material-ui/core/FormGroup";
|
|
||||||
import Slider from "@material-ui/core/Slider";
|
import Slider from "@material-ui/core/Slider";
|
||||||
import {
|
import { pollIntervalChange, selectTheme } from "../actions/settingsActions";
|
||||||
pollIntervalChange,
|
|
||||||
toggleDarkTheme,
|
|
||||||
} from "../actions/settingsActions";
|
|
||||||
import { AppState } from "../store";
|
import { AppState } from "../store";
|
||||||
|
import FormControl from "@material-ui/core/FormControl/FormControl";
|
||||||
|
import InputLabel from "@material-ui/core/InputLabel";
|
||||||
|
import Select from "@material-ui/core/Select";
|
||||||
|
import MenuItem from "@material-ui/core/MenuItem";
|
||||||
|
import { ThemePreference } from "../reducers/settingsReducer";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
container: {
|
container: {
|
||||||
@ -26,16 +25,23 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
},
|
},
|
||||||
|
formControl: {
|
||||||
|
margin: theme.spacing(1),
|
||||||
|
minWidth: 120,
|
||||||
|
},
|
||||||
|
selectEmpty: {
|
||||||
|
marginTop: theme.spacing(2),
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
pollInterval: state.settings.pollInterval,
|
pollInterval: state.settings.pollInterval,
|
||||||
isDarkTheme: state.settings.isDarkTheme,
|
themePreference: state.settings.themePreference,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = { pollIntervalChange, toggleDarkTheme };
|
const mapDispatchToProps = { pollIntervalChange, selectTheme };
|
||||||
|
|
||||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||||
|
|
||||||
@ -53,8 +59,8 @@ function SettingsView(props: PropsFromRedux) {
|
|||||||
props.pollIntervalChange(val as number);
|
props.pollIntervalChange(val as number);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleThemeChange = (event: React.ChangeEvent<HTMLElement>) => {
|
const handleThemeChange = (event: React.ChangeEvent<{ value: unknown }>) => {
|
||||||
props.toggleDarkTheme();
|
props.selectTheme(event.target.value as ThemePreference);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Container maxWidth="lg" className={classes.container}>
|
<Container maxWidth="lg" className={classes.container}>
|
||||||
@ -87,23 +93,22 @@ function SettingsView(props: PropsFromRedux) {
|
|||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={5}>
|
<FormControl variant="outlined" className={classes.formControl}>
|
||||||
<Paper>
|
<InputLabel id="theme-label">Dark theme</InputLabel>
|
||||||
<Typography color="textPrimary">theme switch</Typography>
|
<Select
|
||||||
<FormGroup row>
|
labelId="theme-label"
|
||||||
<FormControlLabel
|
id="theme-selected"
|
||||||
control={
|
value={props.themePreference}
|
||||||
<Switch
|
|
||||||
checked={props.isDarkTheme}
|
|
||||||
onChange={handleThemeChange}
|
onChange={handleThemeChange}
|
||||||
name="DarkTheme"
|
label="theme preference"
|
||||||
/>
|
>
|
||||||
}
|
<MenuItem value={ThemePreference.SystemDefault}>
|
||||||
label="🌛"
|
System Default
|
||||||
/>
|
</MenuItem>
|
||||||
</FormGroup>
|
<MenuItem value={ThemePreference.Always}>Always</MenuItem>
|
||||||
</Paper>
|
<MenuItem value={ThemePreference.Never}>Never</MenuItem>
|
||||||
</Grid>
|
</Select>
|
||||||
|
</FormControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user