feat(web): subscription calendar view, reset action and quality preset fields

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 20:14:40 +08:00
1 parent 70d56645fe
commit 05350460f0
7 files changed
+638 -166

No files matched your search

@@ -1,10 +1,11 @@
import type { Subscription } from "@umt/contracts";
import { Grid3x3, MoreHorizontal, Pause, Pencil, Play, RotateCcw, Search, Trash2 } from "lucide-react";
import { Eraser, Grid3x3, MoreHorizontal, Pause, Pencil, Play, RotateCcw, Search, Trash2 } from "lucide-react";
import { type ReactNode, useState } from "react";
import { useNavigate } from "react-router";
import { toast } from "sonner";
import {
type SubscriptionAction,
useResetSubscription,
useSearchSubscription,
useSubscriptionAction,
useSubscriptionBatch,
@@ -26,7 +27,8 @@ export function useSubscriptionOps() {
const search = useSearchSubscription();
const action = useSubscriptionAction();
const batch = useSubscriptionBatch();
const pending = search.isPending || action.isPending || batch.isPending;
const reset = useResetSubscription();
const pending = search.isPending || action.isPending || batch.isPending || reset.isPending;
return {
pending,
search: (id: string) =>
@@ -42,6 +44,11 @@ export function useSubscriptionOps() {
onError: (e) => toast.error(errorMessage(e)),
},
),
reset: (id: string) =>
reset.mutateAsync(id).then((r) => {
const kept = r.keptPlans.length ? `,${r.keptPlans.length} 个仍在下载的保留` : "";
toast.success(`已重置:释放 ${r.releasedPlans.length} 个计划${kept}`);
}),
remove: (ids: string[]) =>
batch.mutateAsync({ ids, action: "delete" }).then((r) => {
const bad = r.results.filter((x) => !x.ok);
@@ -110,6 +117,7 @@ export function SubscriptionMenu({
const navigate = useNavigate();
const [open, setOpen] = useState(false);
const [confirm, setConfirm] = useState(false);
const [confirmReset, setConfirmReset] = useState(false);
const run = (fn: () => void) => () => {
setOpen(false);
fn();
@@ -156,6 +164,11 @@ export function SubscriptionMenu({
恢复
</MenuItem>
) : null}
{!ended ? (
<MenuItem icon={<Eraser />} disabled={ops.pending} onClick={run(() => setConfirmReset(true))}>
重置
</MenuItem>
) : null}
{ended ? (
<MenuItem icon={<RotateCcw />} disabled={ops.pending} onClick={run(() => ops.act(sub.id, "resubscribe"))}>
重新订阅
@@ -169,6 +182,19 @@ export function SubscriptionMenu({
</PopoverContent>
</Popover>
<DeleteSubscriptionsDialog open={confirm} onOpenChange={setConfirm} ids={[sub.id]} />
<ConfirmDialog
open={confirmReset}
onOpenChange={setConfirmReset}
title="重置这个订阅的进度?"
description="取消还没提交、或下载任务已不在的计划,清掉延后记录,然后重新评估。仍在下载的任务、已入库文件和总集数保留。"
confirmLabel="重置"
onConfirm={() =>
ops.reset(sub.id).catch((e) => {
toast.error(errorMessage(e));
throw e;
})
}
/>
</>
);
}