mirror of
https://github.com/lifegpc/bookdownload.git
synced 2026-07-08 01:31:31 +08:00
Add settings page
This commit is contained in:
30
src/config.ts
Normal file
30
src/config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { loadConfig, saveConfig } from "./utils";
|
||||
|
||||
type QdConfigData = {
|
||||
AutoSaveChapter?: boolean;
|
||||
}
|
||||
|
||||
export class QdConfig {
|
||||
static STORAGE_KEY = 'qd_config';
|
||||
config?: QdConfigData;
|
||||
constructor() {
|
||||
}
|
||||
async init() {
|
||||
this.config = await loadConfig<QdConfigData>(QdConfig.STORAGE_KEY, {});
|
||||
}
|
||||
async save() {
|
||||
if (!this.config) {
|
||||
throw new Error('Config not initialized');
|
||||
}
|
||||
await saveConfig(QdConfig.STORAGE_KEY, this.config);
|
||||
}
|
||||
get AutoSaveChapter(): boolean {
|
||||
return this.config?.AutoSaveChapter ?? false;
|
||||
}
|
||||
set AutoSaveChapter(value: boolean) {
|
||||
if (!this.config) {
|
||||
throw new Error('Config not initialized');
|
||||
}
|
||||
this.config.AutoSaveChapter = value;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { Descriptions, Card, Typography, Tag, Space, Button } from 'antd';
|
||||
import type { BookInfo, ChapterInfo } from '../qdtypes';
|
||||
import { get_chapter_content, saveAsFile } from '../utils';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { Title, Text, Paragraph } = Typography;
|
||||
|
||||
interface QdChapterInfoProps {
|
||||
bookInfo: BookInfo;
|
||||
@@ -127,7 +127,7 @@ export default function QdChapterInfo({ bookInfo, chapterInfo }: QdChapterInfoPr
|
||||
{/* 章节内容 */}
|
||||
<Card title="章节内容" size="small">
|
||||
{chapters.map((paragraph, index) => (
|
||||
<p key={index}>{paragraph}</p>
|
||||
<Paragraph key={index}>{paragraph}</Paragraph>
|
||||
))}
|
||||
</Card>
|
||||
</Space>
|
||||
|
||||
13
src/popup.html
Normal file
13
src/popup.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<title>扩展弹出页</title>
|
||||
<link rel="stylesheet" href="./popup.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="./popup.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
13
src/settings.html
Normal file
13
src/settings.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<title>扩展设置</title>
|
||||
<!--<link rel="stylesheet" href="./settings.css"/>-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="./settings.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
23
src/settings.tsx
Normal file
23
src/settings.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { Typography, Tabs } from "antd";
|
||||
import type { TabsProps } from 'antd';
|
||||
import QdSettings from "./settings/QdSettings";
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
'key': '1',
|
||||
'label': `起点设置`,
|
||||
'children': <QdSettings />,
|
||||
}
|
||||
];
|
||||
|
||||
function Settings() {
|
||||
return (<>
|
||||
<Title >扩展设置</Title>
|
||||
<Tabs defaultActiveKey="1" items={items} />
|
||||
</>);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(<Settings />);
|
||||
18
src/settings/QdSettings.tsx
Normal file
18
src/settings/QdSettings.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Typography, Switch, FloatButton, Affix, Button } from "antd";
|
||||
import { SaveTwoTone, SaveOutlined } from "@ant-design/icons";
|
||||
import { useState } from "react";
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
export default function QdSettings() {
|
||||
const [container, setContainer] = useState<HTMLElement | null>(null);
|
||||
return (
|
||||
<div ref={setContainer}>
|
||||
<Title level={2}>起点设置</Title>
|
||||
<Affix target={() => container}>
|
||||
<Button type="primary" icon={<SaveOutlined />}>保存设置</Button>
|
||||
</Affix>
|
||||
<FloatButton icon={<SaveTwoTone />} tooltip="保存设置" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
src/utils.ts
14
src/utils.ts
@@ -1,4 +1,4 @@
|
||||
import { UrlParams, SendMessage, Message } from "./types";
|
||||
import type { UrlParams, SendMessage, Message } from "./types";
|
||||
|
||||
export const QD_CHAPTER_URLPATH_REGEX = /^\/chapter\/(\d+)\/(\d+)\/?$/;
|
||||
|
||||
@@ -58,3 +58,15 @@ export function saveAsFile(filename: string, content: string, mimeType: string =
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
export async function saveConfig(key: string, config: any): Promise<void> {
|
||||
return await chrome.storage.managed.set({ [key]: config });
|
||||
}
|
||||
|
||||
export async function loadConfig<T>(key: string, defaultValue: T): Promise<T> {
|
||||
const r = await chrome.storage.managed.get<{[key]: T | undefined}>(key);
|
||||
if (r[key] === undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
return r[key];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user