mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Update
This commit is contained in:
97
components/TaskFilterBar.tsx
Normal file
97
components/TaskFilterBar.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
// @ts-nocheck Chips
|
||||
import { Component } from "preact";
|
||||
import { Ref, useRef } from "preact/hooks";
|
||||
import Chips from "preact-material-components/Chips";
|
||||
import t from "../server/i18n.ts";
|
||||
|
||||
export enum TaskStatusFlag {
|
||||
None = 0,
|
||||
Running = 1 << 0,
|
||||
Waiting = 1 << 1,
|
||||
Failed = 1 << 2,
|
||||
Finished = 1 << 3,
|
||||
All = ~(~0 << 4),
|
||||
}
|
||||
|
||||
type Props = {
|
||||
value: TaskStatusFlag;
|
||||
set_value: (v: TaskStatusFlag) => void;
|
||||
};
|
||||
|
||||
export class TaskFilterBar extends Component<Props> {
|
||||
ref: Ref<Chips | null> | undefined;
|
||||
get is_all() {
|
||||
return this.props.value === TaskStatusFlag.All;
|
||||
}
|
||||
get is_failed() {
|
||||
return (this.props.value & TaskStatusFlag.Failed) !== 0;
|
||||
}
|
||||
get is_finished() {
|
||||
return (this.props.value & TaskStatusFlag.Finished) !== 0;
|
||||
}
|
||||
get is_running() {
|
||||
return (this.props.value & TaskStatusFlag.Running) !== 0;
|
||||
}
|
||||
get is_waiting() {
|
||||
return (this.props.value & TaskStatusFlag.Waiting) !== 0;
|
||||
}
|
||||
get value() {
|
||||
if (this.ref && this.ref.current) {
|
||||
const com = this.ref.current.MDComponent;
|
||||
if (com) {
|
||||
return com.chips.slice(1).reduce(
|
||||
(p, v, i) => v.selected ? p | 1 << i : p,
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
return TaskStatusFlag.None;
|
||||
}
|
||||
render() {
|
||||
this.ref = useRef<Chips>(null);
|
||||
const onClick = () => {
|
||||
const co = () => this.props.set_value(this.value);
|
||||
setTimeout(co, 0);
|
||||
};
|
||||
return (
|
||||
<Chips ref={this.ref} filter>
|
||||
<Chips.Chip
|
||||
selected={this.is_all}
|
||||
onClick={() => {
|
||||
const co = () => {
|
||||
if (this.ref && this.ref.current) {
|
||||
const com = this.ref.current.MDComponent;
|
||||
if (com) {
|
||||
com.chips.slice(1).forEach((v) => {
|
||||
v.selected = com.chips[0].selected;
|
||||
});
|
||||
}
|
||||
}
|
||||
this.props.set_value(this.value);
|
||||
};
|
||||
setTimeout(co, 0);
|
||||
}}
|
||||
>
|
||||
<Chips.Checkmark />
|
||||
<Chips.Text>{t("task.all")}</Chips.Text>
|
||||
</Chips.Chip>
|
||||
<Chips.Chip selected={this.is_running} onClick={onClick}>
|
||||
<Chips.Checkmark />
|
||||
<Chips.Text>{t("task.running")}</Chips.Text>
|
||||
</Chips.Chip>
|
||||
<Chips.Chip selected={this.is_waiting} onClick={onClick}>
|
||||
<Chips.Checkmark />
|
||||
<Chips.Text>{t("task.waiting")}</Chips.Text>
|
||||
</Chips.Chip>
|
||||
<Chips.Chip selected={this.is_failed} onClick={onClick}>
|
||||
<Chips.Checkmark />
|
||||
<Chips.Text>{t("task.failed")}</Chips.Text>
|
||||
</Chips.Chip>
|
||||
<Chips.Chip selected={this.is_finished} onClick={onClick}>
|
||||
<Chips.Checkmark />
|
||||
<Chips.Text>{t("task.finished")}</Chips.Text>
|
||||
</Chips.Chip>
|
||||
</Chips>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, ContextType } from "preact";
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { signal } from "@preact/signals";
|
||||
import { GlobalCtx } from "../components/GlobalContext.tsx";
|
||||
import { TaskDetail, TaskStatus } from "../task.ts";
|
||||
@@ -11,12 +11,20 @@ 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";
|
||||
import { TaskFilterBar, TaskStatusFlag } from "../components/TaskFilterBar.tsx";
|
||||
|
||||
export type TaskManagerProps = {
|
||||
base: string;
|
||||
show: boolean;
|
||||
};
|
||||
|
||||
function map_taskstatus(s: TaskStatus) {
|
||||
if (s === TaskStatus.Wait) return TaskStatusFlag.Waiting;
|
||||
else if (s === TaskStatus.Running) return TaskStatusFlag.Running;
|
||||
else if (s === TaskStatus.Finished) return TaskStatusFlag.Finished;
|
||||
return TaskStatusFlag.None;
|
||||
}
|
||||
|
||||
const tasks = signal(new Map<number, TaskDetail>());
|
||||
const task_list = signal(new Array<number>());
|
||||
export const task_ws = signal<WebSocket | undefined>(undefined);
|
||||
@@ -165,6 +173,7 @@ export default class TaskManager extends Component<TaskManagerProps> {
|
||||
});
|
||||
}, []);
|
||||
if (!this.props.show) return null;
|
||||
const [flags, set_flags] = useState(TaskStatusFlag.All);
|
||||
return (
|
||||
<div class="task_manager">
|
||||
<Fab
|
||||
@@ -176,28 +185,24 @@ export default class TaskManager extends Component<TaskManagerProps> {
|
||||
<Icon>add</Icon>
|
||||
</Fab>
|
||||
<div class="task_amounts">
|
||||
<div class="mdc-theme--secondary-light">
|
||||
<p>count</p>
|
||||
<p>{t("task.all")}</p>
|
||||
</div>
|
||||
<div class="btn-success">
|
||||
<p>count</p>
|
||||
<p>{t("task.running")}</p>
|
||||
</div>
|
||||
<div class="btn-warning">
|
||||
<p>count</p>
|
||||
<p>{t("task.waiting")}</p>
|
||||
</div>
|
||||
<div class="btn-danger">
|
||||
<p>count</p>
|
||||
<p>{t("task.failed")}</p>
|
||||
</div>
|
||||
<div class="btn-primary">
|
||||
<p>count</p>
|
||||
<p>{t("task.finished")}</p>
|
||||
</div>
|
||||
<TaskFilterBar value={flags} set_value={set_flags} />
|
||||
</div>
|
||||
<div class="task_details">
|
||||
<div
|
||||
class="task_details"
|
||||
// @ts-ignore Checked
|
||||
ref={ul}
|
||||
>
|
||||
{task_list.value.map((k) => {
|
||||
const t = tasks.value.get(k);
|
||||
if (t) {
|
||||
if (!(flags & map_taskstatus(t.status))) {
|
||||
return null;
|
||||
}
|
||||
return <Task task={t} />;
|
||||
} else {
|
||||
return <div data-id={k}></div>;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -172,25 +172,6 @@ body {
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.task_amounts>div {
|
||||
flex: auto;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: aliceblue;
|
||||
}
|
||||
|
||||
.task_amounts>div:first-child {
|
||||
border-radius: 8px 0 0 8px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.task_amounts>div:last-child {
|
||||
border-radius: 0 8px 8px 0
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: #28a745
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user