Update settings page

This commit is contained in:
2023-05-26 18:56:49 +08:00
parent b257cd9fb9
commit 54c5ffa10c
3 changed files with 103 additions and 3 deletions

View File

@@ -0,0 +1,46 @@
import { Component, ContextType } from "preact";
import { SettingsCtx } from "./SettingsContext.tsx";
import { ConfigType } from "../config.ts";
import Checkbox from "preact-material-components/Checkbox";
export type SettingsCheckboxProps = {
checked: boolean;
name: keyof ConfigType;
description: string;
};
export default class SettingsCheckbox
extends Component<SettingsCheckboxProps, unknown> {
static contextType = SettingsCtx;
declare context: ContextType<typeof SettingsCtx>;
render() {
const id = `s-${this.props.name}`;
return (
<div>
<Checkbox
id={id}
checked={this.props.checked}
onInput={(ev: Event) => {
if (ev.target && this.context) {
const e = ev.target as HTMLInputElement;
this.context.set_settings((v) => {
if (v) {
const t: Record<string, unknown> = v;
t[this.props.name] = e.checked;
if (this.context) {
this.context.set_changed((v) => {
v.add(this.props.name);
return v;
});
}
return t as ConfigType;
}
});
}
}}
/>
<label for={id}>{this.props.description}</label>
</div>
);
}
}

View File

@@ -0,0 +1,33 @@
import { Component, ComponentChild, createContext } from "preact";
import { StateUpdater } from "preact/hooks";
import { ConfigType } from "../config.ts";
export const SettingsCtx = createContext<State | null>(null);
type State = {
set_settings: StateUpdater<ConfigType | undefined>;
set_changed: StateUpdater<Set<string>>;
};
type Props = {
children: ComponentChild;
set_settings: StateUpdater<ConfigType | undefined>;
set_changed: StateUpdater<Set<string>>;
};
export default class SettingsContext extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
set_settings: props.set_settings,
set_changed: props.set_changed,
};
}
render() {
return (
<SettingsCtx.Provider value={this.props}>
{this.props.children}
</SettingsCtx.Provider>
);
}
}

View File

@@ -5,6 +5,8 @@ import Checkbox from "preact-material-components/Checkbox";
import { tw } from "twind";
import { GlobalCtx } from "../components/GlobalContext.tsx";
import { ConfigType } from "../config.ts";
import SettingsCheckbox from "../components/SettingsCheckbox.tsx";
import SettingsContext from "../components/SettingsContext.tsx";
export type SettingsProps = {
show: boolean;
@@ -17,9 +19,11 @@ export default class Settings extends Component<SettingsProps> {
if (!this.props.show) return;
const [settings, set_settings] = useState<ConfigType | undefined>();
const [error, set_error] = useState<string | undefined>();
const [changed, set_changed] = useState<Set<string>>(new Set());
const fetchSettings = async () => {
const re = await fetch("/api/config");
set_settings(await re.json());
set_changed(new Set());
};
const loadData = () => {
fetchSettings().catch((e) => {
@@ -34,9 +38,26 @@ export default class Settings extends Component<SettingsProps> {
} else if (settings) {
data = (
<div class="settings">
<Checkbox id="s-ex" checked={settings.ex} />
<label for="s-ex">Use exhentai.org.</label>
<br />
<SettingsContext
set_changed={set_changed}
set_settings={set_settings}
>
<SettingsCheckbox
name="download_original_img"
checked={settings.download_original_img}
description="Download original images."
/>
<SettingsCheckbox
name="ex"
checked={settings.ex}
description="Use exhentai.org."
/>
<SettingsCheckbox
name="mpv"
checked={settings.mpv}
description="Fetch page data from Multi-Page Viewer."
/>
</SettingsContext>
<Button onClick={loadData}>Reload</Button>
</div>
);