文案(下载):重写下载面板、后台任务、下载盘与手动下载文案
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
5aa19a9a9b
commit
3853a65754
7 files changed
+30
-30
No files matched your search
@@ -24,15 +24,15 @@ import { formatDateTime } from "~/lib/utils.ts";
|
||||
const TaskPage = cursorPage(Task);
|
||||
|
||||
export const TASK_KIND_LABEL: Record<TaskKind, string> = {
|
||||
ingestFeed: "抓取 Feed",
|
||||
ingestFeed: "抓取 RSS",
|
||||
resolveObservation: "识别资源",
|
||||
evaluateAcquisition: "评估候选",
|
||||
evaluateAcquisition: "评估资源",
|
||||
submitDownload: "提交下载",
|
||||
verifyAndImport: "核验整理",
|
||||
refreshMetadata: "刷新元数据",
|
||||
reconcileLibrary: "文件核对",
|
||||
cleanupDownloadCache: "清理缓存",
|
||||
resolveDecision: "处理待处理事项",
|
||||
resolveDecision: "处理事项",
|
||||
agentRun: "智能体运行",
|
||||
};
|
||||
|
||||
@@ -40,13 +40,13 @@ export const TASK_STATUS: Record<
|
||||
TaskStatus,
|
||||
{ label: string; tone: "success" | "warning" | "destructive" | "neutral" }
|
||||
> = {
|
||||
pending: { label: "排队", tone: "neutral" },
|
||||
pending: { label: "排队中", tone: "neutral" },
|
||||
running: { label: "运行中", tone: "neutral" },
|
||||
waiting: { label: "等待", tone: "warning" },
|
||||
succeeded: { label: "成功", tone: "success" },
|
||||
failed: { label: "失败", tone: "destructive" },
|
||||
cancelled: { label: "已取消", tone: "neutral" },
|
||||
dead: { label: "放弃", tone: "destructive" },
|
||||
dead: { label: "已放弃", tone: "destructive" },
|
||||
};
|
||||
|
||||
export const ACTIVE_TASK: TaskStatus[] = ["pending", "running", "waiting"];
|
||||
@@ -245,8 +245,8 @@ export function BusinessTasks() {
|
||||
loadingMore={list.isFetchingNextPage}
|
||||
empty={{
|
||||
icon: ListTodo,
|
||||
title: f.active ? "没有符合筛选的任务" : "还没有业务任务",
|
||||
description: f.active ? undefined : "提交下载、核验整理、清理缓存、对账等后台任务会出现在这里。",
|
||||
title: f.active ? "没有符合筛选的任务" : "还没有后台任务",
|
||||
description: f.active ? undefined : "提交下载、核验整理、清理缓存、文件核对等任务会出现在这里。",
|
||||
}}
|
||||
/>
|
||||
<DetailSheet
|
||||
@@ -259,7 +259,7 @@ export function BusinessTasks() {
|
||||
<>
|
||||
<TaskActions t={open} />
|
||||
<Button asChild size="sm">
|
||||
<Link to={consolePath("tasks", open.id)}>在独立页面打开</Link>
|
||||
<Link to={consolePath("tasks", open.id)}>打开详情页</Link>
|
||||
</Button>
|
||||
</>
|
||||
) : null
|
||||
|
||||
@@ -36,7 +36,7 @@ export function BusinessTimeline({ events, loading }: { events: TimelineEvent[];
|
||||
})}
|
||||
</div>
|
||||
{ongoing.length ? (
|
||||
<p className="text-caption text-muted-foreground">当前:{ongoing.map((e) => e.title).join(";")}</p>
|
||||
<p className="text-caption text-muted-foreground">当前:{ongoing.map((e) => e.title).join(";")}</p>
|
||||
) : null}
|
||||
{loading && !events.length ? (
|
||||
<LoadingState rows={3} />
|
||||
@@ -60,7 +60,7 @@ export function BusinessTimeline({ events, loading }: { events: TimelineEvent[];
|
||||
/>
|
||||
)}
|
||||
{loading && events.length ? (
|
||||
<p className="text-meta text-muted-foreground">正在加载关联的整理记录与引擎运行…</p>
|
||||
<p className="text-meta text-muted-foreground">加载整理记录和引擎运行…</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -81,9 +81,9 @@ function VolumeBar({ v }: { v: Volume }) {
|
||||
/>
|
||||
<div className="mt-1.5 flex flex-wrap gap-1.5">
|
||||
{pct === null ? <StatusBadge tone="warning">读不到磁盘状态,已暂停新提交</StatusBadge> : null}
|
||||
{tripped ? <StatusBadge tone="destructive">超过暂停线,停止新下载</StatusBadge> : null}
|
||||
{tripped ? <StatusBadge tone="destructive">超过暂停线,已停止新下载</StatusBadge> : null}
|
||||
{v.pausedByThreshold ? (
|
||||
<StatusBadge tone="warning">因下载盘暂停 {v.pausedByThreshold} 个任务</StatusBadge>
|
||||
<StatusBadge tone="warning">超过暂停线,暂停了 {v.pausedByThreshold} 个任务</StatusBadge>
|
||||
) : null}
|
||||
</div>
|
||||
{v.notes.map((n) => (
|
||||
@@ -119,7 +119,7 @@ export function CacheVolumes() {
|
||||
</Button>
|
||||
}
|
||||
title="按规则清理下载缓存?"
|
||||
description="只清理已整理、且满足保留期与 H&R 的本工具任务,其余不动。"
|
||||
description="只清理本工具管理、已整理且满足保留期和 H&R 要求的任务,其余不动。"
|
||||
confirmLabel="清理"
|
||||
onConfirm={() =>
|
||||
cleanup.mutateAsync(undefined).then(
|
||||
@@ -138,7 +138,7 @@ export function CacheVolumes() {
|
||||
) : vols.error ? (
|
||||
<ErrorState plain error={vols.error} onRetry={() => void vols.refetch()} />
|
||||
) : !vols.data.length ? (
|
||||
<p className="text-caption text-muted-foreground">还没有缓存卷数据。登记下载器并完成巡检后显示。</p>
|
||||
<p className="text-caption text-muted-foreground">还没有下载盘。添加下载器后显示。</p>
|
||||
) : (
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
{vols.data.map((v) => (
|
||||
|
||||
@@ -333,11 +333,11 @@ export const BOARD_EMPTY: Record<DownloadBoardState, { title: string; descriptio
|
||||
active: {
|
||||
icon: Download,
|
||||
title: "没有进行中的下载",
|
||||
description: "自动收录或在站点页下载后出现在这里,等批准、等磁盘空间的也在这里;下载完成的在「已完成」。",
|
||||
description: "自动收录和手动下载的任务都在这里,包括等批准、等磁盘空间的。下载完成后移到「已完成」。",
|
||||
},
|
||||
completed: {
|
||||
icon: CheckCircle2,
|
||||
title: "还没有下载完成的任务",
|
||||
description: "下载完成(含做种)后出现在这里。",
|
||||
description: "下载完成的任务在这里,包括做种中的。",
|
||||
},
|
||||
};
|
||||
@@ -49,7 +49,7 @@ export function DownloadStatusBadges({ t }: { t: DownloadTask }) {
|
||||
<span className="flex flex-wrap gap-1">
|
||||
<StatusBadge tone={DOWNLOAD_STATUS_TONE[t.status]}>{DOWNLOAD_STATUS_LABEL[t.status]}</StatusBadge>
|
||||
{t.pauseReason === "threshold" ? (
|
||||
<StatusBadge tone="warning">下载盘满,已暂停</StatusBadge>
|
||||
<StatusBadge tone="warning">超过暂停线,已暂停</StatusBadge>
|
||||
) : t.pauseReason ? (
|
||||
<StatusBadge>{PAUSE_REASON_LABEL[t.pauseReason]}</StatusBadge>
|
||||
) : null}
|
||||
@@ -151,7 +151,7 @@ export function DownloadDetail({ task, live }: { task: DownloadTask; live?: Down
|
||||
) : null}
|
||||
{task.noProgressSince ? (
|
||||
<p className="rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-caption text-warning">
|
||||
自 {formatDateTime(task.noProgressSince)} 起无进展,不会自动换源;开了自动调查时智能体会在授权内尝试恢复。
|
||||
{formatDateTime(task.noProgressSince)} 起没有进展,不会自动换源。开启自动调查时,智能体会在持续授权范围内尝试恢复。
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ describe("保存目录", () => {
|
||||
expect(custom).not.toHaveProperty("downloaderInstanceId");
|
||||
});
|
||||
|
||||
it("界面:并排两个下拉,下方写明将保存到哪;自定义时展开输入框", () => {
|
||||
it("界面:并排两个下拉,下方写明保存到哪;自定义时展开输入框", () => {
|
||||
const props = {
|
||||
formId: "f",
|
||||
instances: paths.instances,
|
||||
@@ -101,10 +101,10 @@ describe("保存目录", () => {
|
||||
const html = render(createElement(SaveTargetFields, props));
|
||||
expect(html).toContain("下载器");
|
||||
expect(html).toContain("自动:qb-main");
|
||||
expect(html).toContain("将保存到:/data/downloads(本机 /mnt/dl)");
|
||||
expect(html).toContain("保存到:/data/downloads(本机 /mnt/dl)");
|
||||
expect(html).not.toContain("自定义路径</label>");
|
||||
const custom = render(createElement(SaveTargetFields, { ...props, dir: CUSTOM_DIR, custom: "/x" }));
|
||||
expect(custom).toContain("将保存到:/x");
|
||||
expect(custom).toContain("保存到:/x");
|
||||
expect(custom).toContain('id="f-custom"');
|
||||
const none = render(
|
||||
createElement(SaveTargetFields, { ...props, instances: [], autoInstanceId: null, target: null }),
|
||||
@@ -136,7 +136,7 @@ describe("作品身份", () => {
|
||||
expect(html).toContain("未识别");
|
||||
expect(html).toContain("TMDB 编号");
|
||||
expect(html).toContain('id="f-tmdb"');
|
||||
expect(html).toContain("暂未识别到作品");
|
||||
expect(html).toContain("没识别出作品");
|
||||
});
|
||||
|
||||
it("已识别:折叠只显示当前作品", () => {
|
||||
|
||||
@@ -282,7 +282,7 @@ export function ManualDownloadDialog({
|
||||
}}
|
||||
>
|
||||
<Bot />
|
||||
委托智能体
|
||||
交给智能体
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
@@ -329,7 +329,7 @@ export function ResourceSummary({ resource: r }: { resource: ManualDownloadResou
|
||||
{r.leechers ?? "—"}
|
||||
</span>
|
||||
) : null}
|
||||
{r.publishedAt ? <span title={absTime(r.publishedAt)}>发布 {relTime(r.publishedAt)}</span> : null}
|
||||
{r.publishedAt ? <span title={absTime(r.publishedAt)}>发布于 {relTime(r.publishedAt)}</span> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -372,7 +372,7 @@ export function SaveTargetFields({
|
||||
: !target && dir !== CUSTOM_DIR
|
||||
? "没有可用的下载器,先在设置里添加下载器和保存目录"
|
||||
: resolved
|
||||
? `将保存到:${savePathText(resolved)}`
|
||||
? `保存到:${savePathText(resolved)}`
|
||||
: "填写下载器能访问的路径";
|
||||
return (
|
||||
<div className="grid items-start gap-x-3 sm:grid-cols-2">
|
||||
@@ -504,7 +504,7 @@ export function IdentitySection({
|
||||
<div id={`${formId}-identity`} className="space-y-3 border-t border-border px-3 pt-3 pb-1">
|
||||
{unrecognized && !changed ? (
|
||||
<p className="text-caption text-warning">
|
||||
暂未识别到作品。指定后绑定到这个资源;不指定也能下载,整理时再补全识别和元数据。
|
||||
没识别出作品。指定后绑定到这个资源;不指定也能下载,整理时再识别。
|
||||
</p>
|
||||
) : null}
|
||||
{picked ? (
|
||||
@@ -533,7 +533,7 @@ export function IdentitySection({
|
||||
<FormField
|
||||
label="TMDB 编号"
|
||||
htmlFor={`${formId}-tmdb`}
|
||||
error={tmdbId && !valid ? "TMDB 编号是数字" : preview.error ? errorMessage(preview.error) : null}
|
||||
error={tmdbId && !valid ? "TMDB 编号只能是数字" : preview.error ? errorMessage(preview.error) : null}
|
||||
hint={
|
||||
preview.data
|
||||
? `${preview.data.title}${preview.data.year ? ` (${preview.data.year})` : ""}${preview.data.localEntityId ? " · 在媒体库" : ""}`
|
||||
@@ -602,8 +602,8 @@ export function ExistingVersionsSection({
|
||||
selected: string[];
|
||||
onSelectedChange: (ids: string[]) => void;
|
||||
}) {
|
||||
if (loading) return <p className="text-caption text-muted-foreground">正在读取已有版本…</p>;
|
||||
if (error) return <p className="text-caption text-destructive">已有版本读取失败,重试后再选洗版</p>;
|
||||
if (loading) return <p className="text-caption text-muted-foreground">读取已有版本…</p>;
|
||||
if (error) return <p className="text-caption text-destructive">读取已有版本失败,重新打开后再选洗版</p>;
|
||||
if (!versions.length) return null;
|
||||
return (
|
||||
<div className="min-w-0 space-y-2">
|
||||
@@ -640,7 +640,7 @@ export function ExistingVersionsSection({
|
||||
))}
|
||||
</fieldset>
|
||||
<p className="text-meta text-muted-foreground">
|
||||
本次新文件整理成功后替换所选旧文件。剧集只替换成功对应的季集,其余保留。
|
||||
新文件整理成功后替换所选旧文件。剧集只替换整理成功的季集,其余保留。
|
||||
</p>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
Reference in new issue
Block a user