mirror of
https://github.com/lifegpc/bookdownload.git
synced 2026-07-08 01:31:31 +08:00
Add QdSettings
This commit is contained in:
@@ -35,5 +35,8 @@
|
|||||||
"options_ui": {
|
"options_ui": {
|
||||||
"open_in_tab": true,
|
"open_in_tab": true,
|
||||||
"page": "dist/settings.html"
|
"page": "dist/settings.html"
|
||||||
}
|
},
|
||||||
|
"permissions": [
|
||||||
|
"storage"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
12
src/components/AlertWarn.tsx
Normal file
12
src/components/AlertWarn.tsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Modal } from "antd";
|
||||||
|
|
||||||
|
export type AlertWarnProps = {
|
||||||
|
title?: string;
|
||||||
|
content: string;
|
||||||
|
onClose?: () => void;
|
||||||
|
okText?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function AlertWarn({ title = "警告", content, onClose, okText = "好的" }: AlertWarnProps) {
|
||||||
|
return <Modal title={title} open={true} onOk={onClose} onCancel={onClose} okText={okText} cancelButtonProps={{ style: { display: "none" } }}>{content}</Modal>
|
||||||
|
}
|
||||||
3
src/components/SwitchLabel.module.css
Normal file
3
src/components/SwitchLabel.module.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.switch-label > span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
17
src/components/SwitchLabel.tsx
Normal file
17
src/components/SwitchLabel.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { Switch } from "antd";
|
||||||
|
import styles from "./SwitchLabel.module.css";
|
||||||
|
|
||||||
|
export type SwitchLabelProps = {
|
||||||
|
label: string;
|
||||||
|
checked: boolean;
|
||||||
|
onChange: (checked: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SwitchLabel({ label, checked, onChange }: SwitchLabelProps) {
|
||||||
|
return (
|
||||||
|
<div className={styles["switch-label"]}>
|
||||||
|
<span onClick={() => onChange(!checked)}>{label}</span>
|
||||||
|
<Switch checked={checked} onChange={onChange} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -18,6 +18,9 @@ export class QdConfig {
|
|||||||
}
|
}
|
||||||
await saveConfig(QdConfig.STORAGE_KEY, this.config);
|
await saveConfig(QdConfig.STORAGE_KEY, this.config);
|
||||||
}
|
}
|
||||||
|
reset() {
|
||||||
|
this.config = {};
|
||||||
|
}
|
||||||
get AutoSaveChapter(): boolean {
|
get AutoSaveChapter(): boolean {
|
||||||
return this.config?.AutoSaveChapter ?? false;
|
return this.config?.AutoSaveChapter ?? false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default function QdChapterInfo({ bookInfo, chapterInfo }: QdChapterInfoPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
<Space orientation="vertical" size="middle" style={{ width: '100%' }}>
|
||||||
{/* 章节信息 */}
|
{/* 章节信息 */}
|
||||||
<Card title="章节信息" size="small">
|
<Card title="章节信息" size="small">
|
||||||
<Descriptions column={1} size="small">
|
<Descriptions column={1} size="small">
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function PopupBody() {
|
|||||||
load().catch(e => {
|
load().catch(e => {
|
||||||
setError(e instanceof Error ? e.message : 'Unknown error');
|
setError(e instanceof Error ? e.message : 'Unknown error');
|
||||||
});
|
});
|
||||||
});
|
}, []);
|
||||||
if (result) {
|
if (result) {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
if (result.ok && result.body?.type === 'QdChapterInfo') {
|
if (result.ok && result.body?.type === 'QdChapterInfo') {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||||
<title>扩展设置</title>
|
<title>扩展设置</title>
|
||||||
<!--<link rel="stylesheet" href="./settings.css"/>-->
|
<link rel="stylesheet" href="./settings.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -1,18 +1,49 @@
|
|||||||
import { Typography, Switch, FloatButton, Affix, Button } from "antd";
|
import { FloatButton, Affix, Button, Space } from "antd";
|
||||||
import { SaveTwoTone, SaveOutlined } from "@ant-design/icons";
|
import { SaveTwoTone, SaveOutlined, SyncOutlined } from "@ant-design/icons";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
import { QdConfig } from "../config";
|
||||||
const { Title } = Typography;
|
import SwitchLabel from "../components/SwitchLabel";
|
||||||
|
import AlertWarn from "../components/AlertWarn";
|
||||||
|
|
||||||
export default function QdSettings() {
|
export default function QdSettings() {
|
||||||
const [container, setContainer] = useState<HTMLElement | null>(null);
|
const [container, setContainer] = useState<HTMLElement | null>(null);
|
||||||
|
const [config] = useState(new QdConfig());
|
||||||
|
const [autoSaveChapter, setAutoSaveChapter] = useState(false);
|
||||||
|
const [alert, setAlert] = useState<{ title?: string; content: string } | null>(null);
|
||||||
|
function handleConfig() {
|
||||||
|
setAutoSaveChapter(config.AutoSaveChapter);
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
config.init().then(() => {
|
||||||
|
handleConfig();
|
||||||
|
}).catch(e => {
|
||||||
|
setAlert({ content: "加载设置失败:" + (e instanceof Error ? e.message : "未知错误"), title: "错误" });
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
function saveSettings() {
|
||||||
|
config.AutoSaveChapter = autoSaveChapter;
|
||||||
|
config.save().then(() => {
|
||||||
|
setAlert({ content: "设置已保存!", title: "通知" });
|
||||||
|
}).catch(e => {
|
||||||
|
setAlert({ content: e instanceof Error ? e.message : "未知错误", title: "错误" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function resetSettings() {
|
||||||
|
config.reset();
|
||||||
|
handleConfig();
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div ref={setContainer}>
|
<div ref={setContainer}>
|
||||||
<Title level={2}>起点设置</Title>
|
|
||||||
<Affix target={() => container}>
|
<Affix target={() => container}>
|
||||||
<Button type="primary" icon={<SaveOutlined />}>保存设置</Button>
|
<Button type="primary" icon={<SaveOutlined />} onClick={saveSettings}>保存设置</Button>
|
||||||
|
<Button onClick={resetSettings} style={{ marginLeft: 8 }} icon={<SyncOutlined />}>重置设置</Button>
|
||||||
</Affix>
|
</Affix>
|
||||||
<FloatButton icon={<SaveTwoTone />} tooltip="保存设置" />
|
<br />
|
||||||
|
<Space orientation="vertical">
|
||||||
|
<SwitchLabel label="自动保存章节" checked={autoSaveChapter} onChange={setAutoSaveChapter} />
|
||||||
|
</Space>
|
||||||
|
<FloatButton icon={<SaveTwoTone />} tooltip="保存设置" onClick={saveSettings} />
|
||||||
|
{alert && <AlertWarn title={alert.title} content={alert.content} onClose={() => setAlert(null)} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ export function saveAsFile(filename: string, content: string, mimeType: string =
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function saveConfig(key: string, config: any): Promise<void> {
|
export async function saveConfig(key: string, config: any): Promise<void> {
|
||||||
return await chrome.storage.managed.set({ [key]: config });
|
return await chrome.storage.local.set({ [key]: config });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadConfig<T>(key: string, defaultValue: T): Promise<T> {
|
export async function loadConfig<T>(key: string, defaultValue: T): Promise<T> {
|
||||||
const r = await chrome.storage.managed.get<{[key]: T | undefined}>(key);
|
const r = await chrome.storage.local.get<{[key]: T | undefined}>(key);
|
||||||
if (r[key] === undefined) {
|
if (r[key] === undefined) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user