Add darkmode switch button

This commit is contained in:
2023-06-25 21:58:24 +08:00
parent ddd3548e2b
commit 0a78c23d85
6 changed files with 48 additions and 19 deletions

View File

@@ -1,14 +0,0 @@
import { Component } from "preact";
import Icon from "preact-material-components/Icon";
type Props = {
show: boolean;
icon: string;
};
export default class MyIcon extends Component<Props> {
render() {
if (!this.props.show) return;
return <Icon>{this.props.icon}</Icon>;
}
}

View File

@@ -1,6 +1,6 @@
import { Head } from "$fresh/runtime.ts";
import { Component, ContextType } from "preact";
import { useEffect, useState } from "preact/hooks";
import { StateUpdater, useEffect, useState } from "preact/hooks";
import Icon from "preact-material-components/Icon";
import List from "preact-material-components/List";
import TopAppBar from "preact-material-components/TopAppBar";
@@ -11,7 +11,8 @@ import t, { i18n_map, I18NMap } from "../server/i18n.ts";
import TaskManager from "./TaskManager.tsx";
import { initState, set_state } from "../server/state.ts";
import NewTask from "../components/NewTask.tsx";
import MyIcon from "../components/MyIcon.tsx";
import { parse_bool } from "../server/parse.ts";
import Switch from "preact-material-components/Switch";
export type ContainerProps = {
i18n: I18NMap;
@@ -24,9 +25,24 @@ export default class Container extends Component<ContainerProps> {
i18n_map.value = this.props.i18n;
const [display, set_display] = useState(false);
const [state, set_state1] = useState("#/");
const [darkmode, set_darkmode] = useState(false);
const [darkmode, set_darkmode1] = useState(false);
const set_darkmode: StateUpdater<boolean> = (u) => {
const v = typeof u === "function" ? u(darkmode) : u;
set_darkmode1(v);
localStorage.setItem("darkmode", JSON.stringify(v));
if (v) {
document.body.classList.add("dark-scheme");
} else {
document.body.classList.remove("dark-scheme");
}
};
useEffect(() => {
initState(set_state1);
const dm = parse_bool(localStorage.getItem("darkmode"), false);
set_darkmode1(dm);
if (dm) {
document.body.classList.add("dark-scheme");
}
}, []);
return (
<div>
@@ -47,6 +63,14 @@ export default class Container extends Component<ContainerProps> {
</TopAppBar.Title>
</TopAppBar.Section>
<TopAppBar.Section align-end>
<Switch
class="darkmode"
checked={darkmode}
onClick={() => {
set_darkmode(!darkmode);
}}
/>
<Icon>{darkmode ? "dark_mode" : "light_mode"}</Icon>
<TopAppBar.Icon>more_vert</TopAppBar.Icon>
</TopAppBar.Section>
</TopAppBar.Row>

13
server/parse.ts Normal file
View File

@@ -0,0 +1,13 @@
export function parse_bool<T extends boolean | null>(
value: string | null,
def: T,
): boolean | T {
if (value === null) return def;
const v = value.toLowerCase();
const n = parseInt(v);
if (isNaN(n)) {
return v === "true";
} else {
return n !== 0;
}
}

View File

@@ -201,3 +201,7 @@ body {
.dark-scheme .mdc-notched-outline__idle{
color: white!important;
}
.mdc-top-app-bar__section--align-end > * {
margin: 0 5px;
}

View File

@@ -4,5 +4,6 @@
"reload": "Reload",
"save": "Save",
"yes": "Yes",
"no": "No"
"no": "No",
"darkmode": "Dark mode"
}

View File

@@ -4,5 +4,6 @@
"reload": "重新加载",
"save": "保存",
"yes": "是",
"no": "否"
"no": "否",
"darkmode": "夜间模式"
}