mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Update
This commit is contained in:
@@ -3,6 +3,7 @@ import { GlobalCtx } from "./GlobalContext.tsx";
|
||||
import Fab from "preact-material-components/Fab";
|
||||
import Icon from "preact-material-components/Icon";
|
||||
import { set_state } from "../server/state.ts";
|
||||
import t from "../server/i18n.ts";
|
||||
|
||||
export type NewTaskProps = {
|
||||
show: boolean;
|
||||
@@ -15,15 +16,22 @@ export default class NewTask extends Component<NewTaskProps> {
|
||||
if (!this.props.show) return null;
|
||||
return (
|
||||
<div class="new_task">
|
||||
<Fab class="close" mini={true}>
|
||||
<Icon
|
||||
onClick={() => {
|
||||
set_state((p) => p.slice(0, p.length - 4));
|
||||
}}
|
||||
>
|
||||
close
|
||||
</Icon>
|
||||
</Fab>
|
||||
<div class="container">
|
||||
<div class="top">
|
||||
<div class="title">{t("task.add")}</div>
|
||||
<Fab class="close" mini={true}>
|
||||
<Icon
|
||||
onClick={() => {
|
||||
set_state((p) => p.slice(0, p.length - 4));
|
||||
}}
|
||||
>
|
||||
close
|
||||
</Icon>
|
||||
</Fab>
|
||||
</div>
|
||||
<div class="content"></div>
|
||||
<div class="bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import NewTask from "../components/NewTask.tsx";
|
||||
import { parse_int } from "../server/parse.ts";
|
||||
import { detect_darkmode } from "../server/dark.ts";
|
||||
import { registeServiceWorker } from "../server/sw.ts";
|
||||
import { initCfg } from "../server/cfg.ts";
|
||||
|
||||
export type ContainerProps = {
|
||||
i18n: I18NMap;
|
||||
@@ -75,6 +76,7 @@ export default class Container extends Component<ContainerProps> {
|
||||
console.error(e);
|
||||
},
|
||||
);
|
||||
initCfg();
|
||||
}, []);
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { ConfigType, load_settings, save_settings } from "../../config.ts";
|
||||
import { get_cfg_path, get_task_manager } from "../../server.ts";
|
||||
import {
|
||||
ConfigClientSocketData,
|
||||
ConfigSeverSocketData,
|
||||
} from "../../server/config.ts";
|
||||
import { parse_bool } from "../../server/parse_form.ts";
|
||||
import { return_json } from "../../server/utils.ts";
|
||||
import { ExitTarget } from "../../signal_handler.ts";
|
||||
|
||||
const UNSAFE_TYPE: (keyof ConfigType)[] = [
|
||||
"base",
|
||||
@@ -20,7 +25,51 @@ export const handler: Handlers = {
|
||||
const u = new URL(req.url);
|
||||
const current = await parse_bool(u.searchParams.get("current"), false);
|
||||
if (current) {
|
||||
const type = u.searchParams.get("type");
|
||||
const t = get_task_manager();
|
||||
if (type === "ws") {
|
||||
const { socket, response } = Deno.upgradeWebSocket(req);
|
||||
const handle = (e: CustomEvent<ConfigType>) => {
|
||||
sendMessage({ type: "cfg", cfg: e.detail });
|
||||
};
|
||||
const sendMessage = (mes: ConfigSeverSocketData) => {
|
||||
if (socket.readyState === socket.OPEN) {
|
||||
socket.send(JSON.stringify(mes));
|
||||
}
|
||||
};
|
||||
const close_handle = () => {
|
||||
sendMessage({ type: "close" });
|
||||
socket.close();
|
||||
};
|
||||
const removeListener = () => {
|
||||
t.removeEventListener("current_cfg_updated", handle);
|
||||
ExitTarget.removeEventListener("close", close_handle);
|
||||
};
|
||||
socket.onclose = () => {
|
||||
removeListener();
|
||||
};
|
||||
socket.onerror = () => {
|
||||
removeListener();
|
||||
console.error("WebSocket error.");
|
||||
};
|
||||
socket.onmessage = (e) => {
|
||||
try {
|
||||
const d: ConfigClientSocketData = JSON.parse(e.data);
|
||||
if (d.type == "close") {
|
||||
sendMessage({ type: "close" });
|
||||
socket.close();
|
||||
}
|
||||
} catch (_) {
|
||||
null;
|
||||
}
|
||||
};
|
||||
socket.onopen = () => {
|
||||
t.addEventListener("current_cfg_updated", handle);
|
||||
ExitTarget.addEventListener("close", close_handle);
|
||||
sendMessage({ type: "cfg", cfg: t.cfg.to_json() });
|
||||
};
|
||||
return response;
|
||||
}
|
||||
return return_json(t.cfg.to_json());
|
||||
}
|
||||
const path = get_cfg_path();
|
||||
@@ -35,16 +84,21 @@ export const handler: Handlers = {
|
||||
const m = get_task_manager();
|
||||
let is_unsafe = false;
|
||||
const cfg = await load_settings(path);
|
||||
let updated = false;
|
||||
Object.getOwnPropertyNames(d).forEach((k) => {
|
||||
if (UNSAFE_TYPE2.indexOf(k) === -1) {
|
||||
cfg._data[k] = d[k];
|
||||
m.cfg._data[k] = d[k];
|
||||
updated = true;
|
||||
} else {
|
||||
cfg._data[k] = d[k];
|
||||
is_unsafe = true;
|
||||
}
|
||||
});
|
||||
await save_settings(path, cfg, m.force_aborts);
|
||||
if (updated) {
|
||||
m.dispatchEvent("current_cfg_updated", m.cfg.to_json());
|
||||
}
|
||||
return return_json({ is_unsafe });
|
||||
} else {
|
||||
return new Response("Bad Request", { status: 400 });
|
||||
|
||||
@@ -32,7 +32,9 @@ export const handler: Handlers<Task[]> = {
|
||||
ExitTarget.removeEventListener("close", close_handle);
|
||||
};
|
||||
function sendMessage(mes: TaskServerSocketData) {
|
||||
socket.send(JSON.stringify(mes));
|
||||
if (socket.readyState === socket.OPEN) {
|
||||
socket.send(JSON.stringify(mes));
|
||||
}
|
||||
}
|
||||
socket.onclose = () => {
|
||||
removeListener();
|
||||
|
||||
25
server/cfg.ts
Normal file
25
server/cfg.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { signal } from "@preact/signals";
|
||||
import { ConfigType } from "../config.ts";
|
||||
import { get_ws_host } from "./utils.ts";
|
||||
import { ConfigClientSocketData, ConfigSeverSocketData } from "./config.ts";
|
||||
|
||||
export const cfg = signal<ConfigType | undefined>(undefined);
|
||||
|
||||
export function initCfg() {
|
||||
const ws = new WebSocket(`${get_ws_host()}/api/config?current=1&type=ws`);
|
||||
console.log(ws);
|
||||
function sendMessage(mes: ConfigClientSocketData) {
|
||||
ws.send(JSON.stringify(mes));
|
||||
}
|
||||
ws.onmessage = (e) => {
|
||||
const d: ConfigSeverSocketData = JSON.parse(e.data);
|
||||
if (d.type === "close") {
|
||||
ws.close();
|
||||
} else if (d.type === "cfg") {
|
||||
cfg.value = d.cfg;
|
||||
}
|
||||
};
|
||||
self.addEventListener("beforeunload", () => {
|
||||
sendMessage({ type: "close" });
|
||||
});
|
||||
}
|
||||
7
server/config.ts
Normal file
7
server/config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ConfigType } from "../config.ts";
|
||||
|
||||
export type ConfigClientSocketData = { type: "close" };
|
||||
export type ConfigSeverSocketData = { type: "close" } | {
|
||||
type: "cfg";
|
||||
cfg: ConfigType;
|
||||
};
|
||||
@@ -224,3 +224,45 @@ body {
|
||||
right: 50px;
|
||||
bottom: 50px;
|
||||
}
|
||||
|
||||
div.new_task {
|
||||
overflow: hidden;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 64px);
|
||||
max-width: 100vw;
|
||||
max-height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
div.new_task>div.container {
|
||||
position: relative;
|
||||
margin: 5% 10%;
|
||||
height: calc(100% - 10% - 64px);
|
||||
min-width: 400px;
|
||||
width: calc(100% - 20%);
|
||||
}
|
||||
|
||||
div.new_task .top {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
line-height: 40px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.new_task .top .title {
|
||||
margin-left: 40px;
|
||||
width: calc(100% - 80px);
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.new_task>div.container>div.content {
|
||||
overflow-y: auto;
|
||||
height: calc(100% - 80px);
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
div.new_task>div.container>div.bottom {
|
||||
line-height: 40px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
html::-webkit-scrollbar {
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Client } from "./client.ts";
|
||||
import { Config } from "./config.ts";
|
||||
import { Config, ConfigType } from "./config.ts";
|
||||
import { EhDb } from "./db.ts";
|
||||
import { MeiliSearchServer } from "./meilisearch.ts";
|
||||
import { check_running } from "./pid_check.ts";
|
||||
@@ -28,6 +28,7 @@ export class AlreadyClosedError extends Error {
|
||||
}
|
||||
|
||||
type EventMap = {
|
||||
current_cfg_updated: ConfigType;
|
||||
new_task: Task;
|
||||
task_started: Task;
|
||||
task_finished: Task;
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
"running": "Running",
|
||||
"waiting": "Waiting",
|
||||
"failed": "Failed",
|
||||
"finished": "Finished"
|
||||
"finished": "Finished",
|
||||
"add": "Add task"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
"running": "运行中",
|
||||
"waiting": "等待中",
|
||||
"failed": "已失败",
|
||||
"finished": "已完成"
|
||||
"finished": "已完成",
|
||||
"add": "新建任务"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user