Skip to content

Commit

Permalink
feat: add auto dark mode (#259)
Browse files Browse the repository at this point in the history
Add detection for theme preferences given by the browser.

This works by replacing the "dark mode" setting with a new selector that defaults to "auto" (losing old settings, sorry).

You can try this out by opening the dev console and using the dedicated button (Inspector > sun/moon -shaped in Firefox, Elements > paint brush -shaped in Chromium).

I tried to match the project style but I'm not too good at frontend, I hope this is OK!
  • Loading branch information
oleobal authored May 15, 2023
1 parent 896182b commit b2a7b1d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 20 deletions.
27 changes: 26 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,35 @@ export default function App() {
const [errorsDialog, setErrorsDialog] = React.useState(false);
const dispatch = useDispatch();
const etebase = useCredentials();
const darkMode = useSelector((state: store.StoreState) => state.settings.darkMode);
const darkModeUserSelection = useSelector((state: store.StoreState) => state.settings.darkModeUserSelection);
const fetchCount = useSelector((state: store.StoreState) => state.fetchCount);
const errors = useSelector((state: store.StoreState) => state.errors);

function shouldBeDark(userSelection: string, browserPreference: boolean): boolean {
if (userSelection === "auto") {
return browserPreference;
} else if (userSelection === "dark") {
return true;
}
return false;
}

const [darkModeBrowserPreference, setDarkModeBrowserPreference] = React.useState(Boolean(window.matchMedia?.("(prefers-color-scheme: dark)").matches));
const handleBrowserDarkModePreferenceChange = React.useCallback((e) => {
setDarkModeBrowserPreference(e.matches);
}, []);
React.useEffect(() => {
window.matchMedia?.("(prefers-color-scheme: dark)").addEventListener("change", handleBrowserDarkModePreferenceChange);
return () => {
window.matchMedia?.("(prefers-color-scheme: dark)").removeEventListener("change", handleBrowserDarkModePreferenceChange);
};
}, [handleBrowserDarkModePreferenceChange]);

const [darkMode, setDarkMode] = React.useState(() => shouldBeDark(darkModeUserSelection, darkModeBrowserPreference));
React.useEffect(() => {
setDarkMode(shouldBeDark(darkModeUserSelection, darkModeBrowserPreference));
}, [darkModeUserSelection, darkModeBrowserPreference]);

async function refresh() {
const syncManager = SyncManager.getManager(etebase!);
const sync = syncManager.sync();
Expand Down
28 changes: 11 additions & 17 deletions src/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ 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 { StoreState } from "../store";
Expand Down Expand Up @@ -173,8 +170,6 @@ 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<any>) {
const name = event.target.name;
const value = event.target.value;
Expand Down Expand Up @@ -228,18 +223,17 @@ export default React.memo(function Settings() {
</Select>
</FormControl>
<h2>Dark mode</h2>
<FormGroup>
<FormControlLabel
control={
<Switch
color="primary"
checked={darkMode}
onChange={() => dispatch(setSettings({ ...settings, darkMode: !darkMode }))}
/>
}
label="Dark mode"
/>
</FormGroup>
<FormControl style={{ width: "15em" }}>
<Select
name="darkModeUserSelection"
value={settings.darkModeUserSelection}
onChange={handleChange}
>
<MenuItem value="auto">Auto</MenuItem>
<MenuItem value="dark">Dark</MenuItem>
<MenuItem value="light">Light</MenuItem>
</Select>
</FormControl>
</Container>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions src/store/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export const messagesReducer = handleActions(
// FIXME Move all the below (potentially the fetchCount ones too) to their own file
export interface SettingsType {
locale: string;
darkMode?: boolean;
darkModeUserSelection: string;
taskSettings: {
filterBy: string | null;
sortBy: string;
Expand All @@ -255,7 +255,7 @@ export const settingsReducer = handleActions(
},
{
locale: "en-gb",
darkMode: false,
darkModeUserSelection: "auto",
taskSettings: {
filterBy: null,
sortBy: "smart",
Expand Down

0 comments on commit b2a7b1d

Please sign in to comment.