mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-06-06 05:38:44 +08:00
Update
This commit is contained in:
17
components/Task.tsx
Normal file
17
components/Task.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Component } from "preact";
|
||||
import { TaskDetail, TaskStatus } from "../task.ts";
|
||||
|
||||
type Props = {
|
||||
task: TaskDetail;
|
||||
};
|
||||
|
||||
export default class Task extends Component<Props> {
|
||||
render() {
|
||||
const task = this.props.task;
|
||||
return (
|
||||
<div data-id={task.base.id}>
|
||||
Task Id: {task.base.id}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,48 @@
|
||||
import { Component, ContextType } from "preact";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { signal } from "@preact/signals";
|
||||
import { GlobalCtx } from "../components/GlobalContext.tsx";
|
||||
import { TaskDetail, TaskStatus } from "../task.ts";
|
||||
import { Sortable } from "sortable";
|
||||
import { TaskClientSocketData, TaskServerSocketData } from "../server/task.ts";
|
||||
import { get_ws_host } from "../server/utils.ts";
|
||||
import Task from "../components/Task.tsx";
|
||||
|
||||
export type TaskManagerProps = {
|
||||
show: boolean;
|
||||
};
|
||||
|
||||
const tasks = signal(new Map<number, TaskDetail>());
|
||||
const task_list = signal(new Array<number>());
|
||||
|
||||
type SortableEvent = CustomEvent & {
|
||||
oldIndex: number | undefined;
|
||||
newIndex: number | undefined;
|
||||
};
|
||||
|
||||
export default class TaskManager extends Component<TaskManagerProps> {
|
||||
static contextType = GlobalCtx;
|
||||
declare context: ContextType<typeof GlobalCtx>;
|
||||
sortable?: Sortable;
|
||||
render() {
|
||||
if (!this.props.show) return null;
|
||||
const [tasks, set_tasks] = useState<Map<number, TaskDetail>>(new Map());
|
||||
const ul = useRef<HTMLDivElement>();
|
||||
useEffect(() => {
|
||||
new Sortable(ul.current, {
|
||||
onSort: (evt: CustomEvent) => {
|
||||
console.log(evt);
|
||||
if (!this.props.show) {
|
||||
this.sortable?.destroy();
|
||||
this.sortable = undefined;
|
||||
return;
|
||||
}
|
||||
this.sortable = new Sortable(ul.current, {
|
||||
onSort: (evt: SortableEvent) => {
|
||||
if (
|
||||
evt.newIndex === undefined || evt.oldIndex === undefined
|
||||
) return;
|
||||
const tl = task_list.value;
|
||||
tl.splice(evt.newIndex, 0, tl.splice(evt.oldIndex, 1)[0]);
|
||||
},
|
||||
});
|
||||
}, [this.props.show]);
|
||||
useEffect(() => {
|
||||
const ws = new WebSocket(`${get_ws_host()}/api/task`);
|
||||
console.log(ws);
|
||||
function sendMessage(mes: TaskClientSocketData) {
|
||||
@@ -36,34 +56,47 @@ export default class TaskManager extends Component<TaskManagerProps> {
|
||||
if (t.type == "close") {
|
||||
ws.close();
|
||||
} else if (t.type == "tasks") {
|
||||
set_tasks((tasks) => {
|
||||
t.tasks.forEach((ta) => {
|
||||
tasks.set(ta.id, {
|
||||
base: ta,
|
||||
status: t.running.includes(ta.id)
|
||||
? TaskStatus.Running
|
||||
: TaskStatus.Wait,
|
||||
});
|
||||
let running_index = -1;
|
||||
t.tasks.forEach((ta) => {
|
||||
const is_running = t.running.includes(ta.id);
|
||||
tasks.value.set(ta.id, {
|
||||
base: ta,
|
||||
status: is_running
|
||||
? TaskStatus.Running
|
||||
: TaskStatus.Wait,
|
||||
});
|
||||
this.forceUpdate();
|
||||
return tasks;
|
||||
const tl = task_list.value;
|
||||
if (!tl.includes(ta.id)) {
|
||||
tl.push(ta.id);
|
||||
if (is_running) {
|
||||
if (tl.length) {
|
||||
tl.splice(
|
||||
running_index + 1,
|
||||
0,
|
||||
tl.splice(tl.length - 1, 1)[0],
|
||||
);
|
||||
}
|
||||
running_index += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.forceUpdate();
|
||||
} else if (t.type == "new_task") {
|
||||
set_tasks((tasks) => {
|
||||
tasks.set(t.detail.id, {
|
||||
base: t.detail,
|
||||
status: TaskStatus.Wait,
|
||||
});
|
||||
this.forceUpdate();
|
||||
return tasks;
|
||||
tasks.value.set(t.detail.id, {
|
||||
base: t.detail,
|
||||
status: TaskStatus.Wait,
|
||||
});
|
||||
if (!task_list.value.includes(t.detail.id)) {
|
||||
task_list.value.push(t.detail.id);
|
||||
}
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
self.addEventListener("beforeunload", () => {
|
||||
sendMessage({ type: "close" });
|
||||
});
|
||||
}, []);
|
||||
console.log(tasks.size);
|
||||
if (!this.props.show) return null;
|
||||
return (
|
||||
<div class="task_manager">
|
||||
<div
|
||||
@@ -71,7 +104,14 @@ export default class TaskManager extends Component<TaskManagerProps> {
|
||||
// @ts-ignore checked
|
||||
ref={ul}
|
||||
>
|
||||
{Array.from(tasks.keys()).map((k) => <div>{k}</div>)}
|
||||
{task_list.value.map((k) => {
|
||||
const t = tasks.value.get(k);
|
||||
if (t) {
|
||||
return <Task task={t} />;
|
||||
} else {
|
||||
return <div data-id={k}></div>;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user