diff --git a/config.ts b/config.ts index bbb57d1..c95bfba 100644 --- a/config.ts +++ b/config.ts @@ -1,5 +1,19 @@ +import { exists } from "std/fs/exists.ts"; import { JsonValue, parse } from "std/jsonc/mod.ts"; +export type ConfigType = { + cookies: boolean; + db_path?: string; + ua?: string; + ex: boolean; + base: string; + max_task_count: number; + mpv: boolean; + max_retry_count: number; + max_download_img_count: number; + download_original_img: boolean; +}; + export class Config { _data; constructor(data: JsonValue) { @@ -71,9 +85,24 @@ export class Config { get download_original_img() { return this._return_bool("download_original_img") || false; } + to_json(): ConfigType { + return { + cookies: typeof this.cookies === "string", + db_path: this.db_path, + ua: this.ua, + ex: this.ex, + base: this.base, + max_task_count: this.max_task_count, + mpv: this.mpv, + max_retry_count: this.max_retry_count, + max_download_img_count: this.max_download_img_count, + download_original_img: this.download_original_img, + }; + } } export async function load_settings(path: string) { + if (!await exists(path)) return new Config({}); const s = (new TextDecoder()).decode(await Deno.readFile(path)); return new Config(parse(s)); } diff --git a/deno.lock b/deno.lock index 6b6e1f0..f69b588 100644 --- a/deno.lock +++ b/deno.lock @@ -194,6 +194,8 @@ "https://deno.land/x/zipjs@v2.7.14/lib/z-worker-inline.js": "df83d91413a2e79f76924f39f26f59e6efbe8f5487d3a91b7e92b6d64236927c", "https://deno.land/x/zipjs@v2.7.14/lib/zip-fs.js": "a733360302f5fbec9cc01543cb9fcfe7bae3f35a50d0006626ce42fe8183b63f", "https://esm.sh/*preact-render-to-string@5.2.6": "88ec8d8706b6a3f1e0fdad3862a2690dcd9b350d87bdc8e7bd0e27fbc0f7d29e", + "https://esm.sh/preact-material-components@1.6.1/Button": "bc60923d511c6e2e33a7064339b3e643a9c15e3ef232ab063ef570af2ef83dc8", + "https://esm.sh/preact-material-components@1.6.1/Checkbox": "bf34f5cd8c6d015916d854d91aab2caf115463e97be9a461f8dd3370ea11a49c", "https://esm.sh/preact-material-components@1.6.1/Icon": "e15153f88485e448a8d5ee9d1399205717b41d9cb72bd5824c3b42e1dc463cf6", "https://esm.sh/preact-material-components@1.6.1/List": "5eefaedd7a0f66843c1a1de658f4058b6fc1bbdcd0af1ec627c0f9412f4510c5", "https://esm.sh/preact-material-components@1.6.1/TopAppBar": "e418485020aecb866d9cc44216cd52c5ac1ff120bd1ad422b318428c274b3474", @@ -235,28 +237,43 @@ "https://esm.sh/v122/bind-decorator@1.0.11/deno/bind-decorator.mjs": "21a126bdebaca6e38120139d903c3485c4f57e15487646666e79c1b5c15d0e44", "https://esm.sh/v122/preact-material-components@1.6.1/Base/MaterialComponent.d.ts": "af619a28f2d2f76113e29e952308a2ce46577438f7ed40531458b880ff9a141f", "https://esm.sh/v122/preact-material-components@1.6.1/Base/types.d.ts": "4ec93636595145b9c5cdd628111f28e66148821c23c8ef6273f84bb84a6b8eb8", + "https://esm.sh/v122/preact-material-components@1.6.1/Button/index.d.ts": "3744521d359e3ccf04f115ac731e3304ff8d5901b7d7bcb617de5d88833fdb5c", + "https://esm.sh/v122/preact-material-components@1.6.1/Icon/index.d.ts": "b2c27c8b912f07f20025951d9d05b2e4fb07c773d43db567b930e59b1c444f1c", "https://esm.sh/v122/preact-material-components@1.6.1/List/index.d.ts": "b4159279b6622abbf057385c2b155875dc7e80bdd4403def72d1c0cf58324c73", "https://esm.sh/v122/preact-material-components@1.6.1/TopAppBar/index.d.ts": "d921bd9336541339b0fff19e0769cea149b798bc172d261a7b7a1595f6b90266", "https://esm.sh/v122/preact-material-components@1.6.1/deno/Base/MaterialComponent.js": "7dca052dee2ab5010232055eac4a3159c8455e9b2857870525f7002cb50160bd", + "https://esm.sh/v122/preact-material-components@1.6.1/deno/Button.js": "d60a9ea2eff985808ee0f491579b88dd30e6ce8bf0cb95ac2e7e9c2da9b0c0f3", "https://esm.sh/v122/preact-material-components@1.6.1/deno/Icon.js": "44e17e354a08a2421fffcca3493efa60cc92e2357d410ed387e40f5d34da0ee2", "https://esm.sh/v122/preact-material-components@1.6.1/deno/List.js": "6e908d2bac752351683097bcc22ea26d8e46009c60bc3cee2312728af2f60776", "https://esm.sh/v122/preact-material-components@1.6.1/deno/TopAppBar.js": "ab7ec4fa168d7867961b9fd818e10d138ffb075c20ea4b11f6d231318d897145", + "https://esm.sh/v122/preact-material-components@1.6.1/deno/themeUtils/generateThemeClass.js": "5ec3dd1474bfb68d60ae2c06c90a3faab4e1f79597807d1e72ff5608b05f0a44", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/classCallCheck.js": "678d4a1fc837f06947628e73a957e1f017fe30c77e8500008ec9a5977563c4f9", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/createClass.js": "4205e44f1238343af0a0e0ebc92cfb043382600f54c3e53aa4e6801c9bec7a44", + "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/get.js": "2021a8fa9d0d4880ece83c1d93266ac1d7414430f4f4671691a336ef3aa25dbe", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/getPrototypeOf.js": "41e694838de6926a04a013646f2b3915afa24a57a9301f3e226eadc78fa32e76", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/inherits.js": "09429b866edd8b9dd67dab992f9ad8865c19e15ffecde5ff632e4929755e2807", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/interopRequireDefault.js": "273ebefd452416883e9e517a620b46197b732a9ee384dfcb2ef33f731b7293d4", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/possibleConstructorReturn.js": "c48587b6a4194dac1f823e4706c67a286187cec9f29d35aac06df940443baa51", "https://esm.sh/v124/@babel/runtime@7.21.5/deno/helpers/typeof.js": "ea8e5723c88f83ac7cfbb5728d38e20449f7387093b2825e6c8c81fdc50a7f32", + "https://esm.sh/v124/@material/animation@0.39.0/deno/index.js": "e3a5feaecaada6d930cdee2e4c48eab2d7a44e0c37074614993463d2d74002a3", "https://esm.sh/v124/@material/base@0.39.0/deno/component.js": "aca74f4f0a80339f5bbba649c24b374ded56762679ea161a3db9563de595cec2", "https://esm.sh/v124/@material/base@0.39.0/deno/foundation.js": "4edd0737b3601305ffe599556e98e4861542210744da83af19194c8c4f50c0e0", + "https://esm.sh/v124/@material/checkbox@0.39.3/deno/checkbox.mjs": "8f90b149efea9633436d5b5aff73686494f7872a5d51de56036ec9c8c2178892", + "https://esm.sh/v124/@material/ripple@0.39.3/deno/adapter.js": "29b56c7005653c22ce0d167db65b802e14903e2ba67164824d0be6364309117f", + "https://esm.sh/v124/@material/ripple@0.39.3/deno/constants.js": "f8a80510d9c102aacc87c0fdcdd665118685d53f18948f7eabe275b2c85512a8", + "https://esm.sh/v124/@material/ripple@0.39.3/deno/foundation.js": "f3032b8f3ef0477cf7767362af38f7242df17efdaeb768289074ca4f8c66410e", + "https://esm.sh/v124/@material/ripple@0.39.3/deno/index.js": "c26a075e8ac462902a1014d7b5dd0c0147428b3673a959d28f595b0c3db17368", "https://esm.sh/v124/@material/ripple@0.39.3/deno/ripple.mjs": "df299ee5ebdca82a60414bd942f39bd08eddb47071b7e8e1bcb2ae87f73f2c94", + "https://esm.sh/v124/@material/ripple@0.39.3/deno/util.js": "4df787664fc517d4545bb7d502f85de3b34cfa613e34edd6b4630ea21e673cf2", + "https://esm.sh/v124/@material/selection-control@0.39.3/deno/index.js": "de08ffa76efb31c7fe817ea4a6da471cfe19060f49a21c6cbe6aa9533dc95aa1", "https://esm.sh/v124/bind-decorator@1.0.11/deno/bind-decorator.mjs": "21a126bdebaca6e38120139d903c3485c4f57e15487646666e79c1b5c15d0e44", "https://esm.sh/v124/csstype@3.1.2/index.d.ts": "4c68749a564a6facdf675416d75789ee5a557afda8960e0803cf6711fa569288", "https://esm.sh/v124/preact-material-components@1.6.1/Base/MaterialComponent.d.ts": "2ea7a1ffbff6c43619f3f85d69a9e9a3c62575f409fc93ad651f6906adba47d0", "https://esm.sh/v124/preact-material-components@1.6.1/Base/types.d.ts": "4ec93636595145b9c5cdd628111f28e66148821c23c8ef6273f84bb84a6b8eb8", + "https://esm.sh/v124/preact-material-components@1.6.1/Checkbox/index.d.ts": "034ffead571baad3e10bf34ca33de3ff4829ecb42b9a466766edca59851c10bf", "https://esm.sh/v124/preact-material-components@1.6.1/Icon/index.d.ts": "b2c27c8b912f07f20025951d9d05b2e4fb07c773d43db567b930e59b1c444f1c", "https://esm.sh/v124/preact-material-components@1.6.1/deno/Base/MaterialComponent.js": "a1ec4698c20561f82924708a3d728cdd4ba2c8b3cd895fe3b060c17911528c5c", + "https://esm.sh/v124/preact-material-components@1.6.1/deno/Checkbox.js": "33efdefd473e9df5d0f5a0e56eb0df00bdd6e60a689755e2d0375aaac4108b76", "https://esm.sh/v124/preact-material-components@1.6.1/deno/Icon.js": "9d5ff5fb97a2a4005cf7bb2091e716ca77f920363c68c84108f1dc5e77bb7b7d", "https://esm.sh/v124/preact-render-to-string@5.2.6/X-ZS8q/deno/preact-render-to-string.mjs": "672116885c5e5072207c527a0ec663f5bc52774a0868ec487985109520382a55", "https://esm.sh/v124/preact-render-to-string@5.2.6/X-ZS8q/src/index.d.ts": "b1d73703252c8570fdf2952475805f5808ba3511fefbd93a3e7bd8406de7dcd0", diff --git a/fetch_static_files.ts b/fetch_static_files.ts index a87084d..64f9a9b 100644 --- a/fetch_static_files.ts +++ b/fetch_static_files.ts @@ -3,9 +3,7 @@ import { sure_dir } from "./utils.ts"; const map = JSON.parse(await Deno.readTextFile("./import_map.json")).imports; const LIST: string[] = [ - "preact-material-components/TopAppBar/style.css", - "preact-material-components/List/style.css", - "preact-material-components/Icon/style.css", + "preact-material-components/style.css", ]; function get_url(i: string) { diff --git a/fresh.gen.ts b/fresh.gen.ts index a3aeae2..0589eef 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -3,15 +3,17 @@ // This file is automatically updated during development when running `dev.ts`. import config from "./deno.json" assert { type: "json" }; -import * as $0 from "./routes/api/task/list.ts"; -import * as $1 from "./routes/index.tsx"; +import * as $0 from "./routes/api/config.ts"; +import * as $1 from "./routes/api/task/list.ts"; +import * as $2 from "./routes/index.tsx"; import * as $$0 from "./islands/Container.tsx"; import * as $$1 from "./islands/Settings.tsx"; const manifest = { routes: { - "./routes/api/task/list.ts": $0, - "./routes/index.tsx": $1, + "./routes/api/config.ts": $0, + "./routes/api/task/list.ts": $1, + "./routes/index.tsx": $2, }, islands: { "./islands/Container.tsx": $$0, diff --git a/islands/Container.tsx b/islands/Container.tsx index f4742e5..4fc493a 100644 --- a/islands/Container.tsx +++ b/islands/Container.tsx @@ -23,9 +23,7 @@ export default class Container extends Component { - - - + @@ -42,10 +40,7 @@ export default class Container extends Component { - + set_display(false)}> close diff --git a/islands/Settings.tsx b/islands/Settings.tsx index 2e14246..ce0f921 100644 --- a/islands/Settings.tsx +++ b/islands/Settings.tsx @@ -1,5 +1,10 @@ import { Component, ContextType } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import Button from "preact-material-components/Button"; +import Checkbox from "preact-material-components/Checkbox"; +import { tw } from "twind"; import { GlobalCtx } from "../components/GlobalContext.tsx"; +import { ConfigType } from "../config.ts"; export type SettingsProps = { show: boolean; @@ -10,6 +15,34 @@ export default class Settings extends Component { declare context: ContextType; render() { if (!this.props.show) return; - return
Settings
; + const [settings, set_settings] = useState(); + const [error, set_error] = useState(); + const fetchSettings = async () => { + const re = await fetch("/api/config"); + set_settings(await re.json()); + }; + const loadData = () => { + fetchSettings().catch((e) => { + set_error("Failed to fetch settings."); + console.error(e); + }); + }; + useEffect(loadData, []); + let data; + if (error) { + data =
{error}
; + } else if (settings) { + data = ( +
+ + +
+ +
+ ); + } else { + data =
Loading...
; + } + return
{data}
; } } diff --git a/routes/api/config.ts b/routes/api/config.ts new file mode 100644 index 0000000..25d39ed --- /dev/null +++ b/routes/api/config.ts @@ -0,0 +1,13 @@ +import { Handlers } from "$fresh/server.ts"; +import { load_settings } from "../../config.ts"; +import { get_cfg_path } from "../../server.ts"; + +export const handler: Handlers = { + async GET(_req, _ctx) { + const path = get_cfg_path(); + const cfg = await load_settings(path); + return new Response(JSON.stringify(cfg.to_json()), { + headers: { "Content-Type": "application/json" }, + }); + }, +}; diff --git a/server-run.ts b/server-run.ts index a4d158d..c94e152 100644 --- a/server-run.ts +++ b/server-run.ts @@ -1,4 +1,3 @@ -import { load_settings } from "./config.ts"; import { startServer } from "./server.ts"; -await startServer(await load_settings("./config.json")); +await startServer("./config.json"); diff --git a/server.ts b/server.ts index 656eda8..1432da4 100644 --- a/server.ts +++ b/server.ts @@ -1,18 +1,26 @@ import { start } from "$fresh/server.ts"; -import { Config } from "./config.ts"; +import { load_settings } from "./config.ts"; import manifest from "./fresh.gen.ts"; import { TaskManager } from "./task_manager.ts"; import twindPlugin from "$fresh/plugins/twind.ts"; import twindConfig from "./twind.config.ts"; let task_manager: TaskManager | undefined = undefined; +let cfg_path: string | undefined = undefined; export function get_task_manager() { if (!task_manager) throw Error("task manager undefined."); return task_manager; } -export function startServer(cfg: Config) { +export function get_cfg_path() { + if (!cfg_path) throw Error("cfg_path undefined."); + return cfg_path; +} + +export async function startServer(path: string) { + cfg_path = path; + const cfg = await load_settings(path); task_manager = new TaskManager(cfg); return start(manifest, { signal: task_manager.aborts, diff --git a/static/common.css b/static/common.css index 252f469..8a5ad08 100644 --- a/static/common.css +++ b/static/common.css @@ -3,10 +3,21 @@ position: fixed; background-color: white; box-sizing: border-box; - display: none; + display: block; + left: -64px; + transition: all 0.5s ease; + height: 100vh; +} + +.nav-menu.open { + left: 0px; } .main { position: fixed; top: 64px; } + +.settings label { + line-height: 40px; +}