feat(web): 只按标题的订阅明确提示不会下载;收录版本提示按自动建默认版本改写

- 订阅列表 / 卡片的收录版本位置显示「未关联作品,不会自动搜索和下载」,详情页加一段说明(L5)
- 订阅表单:没有收录版本时说明保存会自动建默认版本,模板说明改为给本订阅创建

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 23:22:16 +08:00
1 parent fcd0d8f223
commit df1a9bc1a9
3 files changed
+16 -6

No files matched your search

@@ -73,7 +73,11 @@ export function ProgressBlock({ x, className }: { x: Pick<Item, "progress" | "mo
); );
} }
export function SlotBadges({ slots, max = 4 }: { slots: Item["slots"]; max?: number }) { /** 只按标题订阅、没关联媒体库作品时的提示:这类订阅不搜索也不下载(L5) */
export const UNBOUND_HINT = "未关联作品,不会自动搜索和下载";
export function SlotBadges({ slots, max = 4, unbound }: { slots: Item["slots"]; max?: number; unbound?: boolean }) {
if (unbound) return <span className="text-meta text-warning">{UNBOUND_HINT}</span>;
if (slots.length === 0) return <span className="text-meta text-muted-foreground">没有收录版本</span>; if (slots.length === 0) return <span className="text-meta text-muted-foreground">没有收录版本</span>;
return ( return (
<div className="flex min-w-0 flex-wrap gap-1"> <div className="flex min-w-0 flex-wrap gap-1">
@@ -181,7 +185,7 @@ export function SubscriptionCard({
</div> </div>
</div> </div>
<ProgressBlock x={x} /> <ProgressBlock x={x} />
<SlotBadges slots={x.slots} /> <SlotBadges slots={x.slots} unbound={!x.mediaEntityId} />
<Meta x={x} /> <Meta x={x} />
<p className="text-meta text-muted-foreground">{autoFillText(x.autoFill)}</p> <p className="text-meta text-muted-foreground">{autoFillText(x.autoFill)}</p>
</article> </article>
@@ -227,7 +231,7 @@ export function SubscriptionRow({
</Link> </Link>
<ProgressBlock x={x} className="hidden md:block" /> <ProgressBlock x={x} className="hidden md:block" />
<div className="relative hidden min-w-0 md:block"> <div className="relative hidden min-w-0 md:block">
<SlotBadges slots={x.slots} max={3} /> <SlotBadges slots={x.slots} max={3} unbound={!x.mediaEntityId} />
</div> </div>
<span className="hidden text-meta text-muted-foreground tabular-nums md:block">{relTime(x.lastUpdatedAt)}</span> <span className="hidden text-meta text-muted-foreground tabular-nums md:block">{relTime(x.lastUpdatedAt)}</span>
<span className="hidden text-meta text-muted-foreground tabular-nums md:block">{nextSearchText(x)}</span> <span className="hidden text-meta text-muted-foreground tabular-nums md:block">{nextSearchText(x)}</span>
@@ -830,7 +830,7 @@ export function SubscriptionFormDialog({
slotsQ.isPending ? ( slotsQ.isPending ? (
<p className="text-caption text-muted-foreground">读取收录版本…</p> <p className="text-caption text-muted-foreground">读取收录版本…</p>
) : subSlots.length === 0 ? ( ) : subSlots.length === 0 ? (
<p className="text-caption text-muted-foreground">还没有收录版本。在对比视图里新建。</p> <p className="text-caption text-muted-foreground">还没有收录版本,保存时自动建一个默认版本。</p>
) : ( ) : (
<FormField label="顺序" htmlFor={f("order")} hint="第一个是主版本;其他版本按自动补全设置补齐"> <FormField label="顺序" htmlFor={f("order")} hint="第一个是主版本;其他版本按自动补全设置补齐">
<SlotOrderList <SlotOrderList
@@ -846,7 +846,7 @@ export function SubscriptionFormDialog({
htmlFor={f("tpl")} htmlFor={f("tpl")}
hint={ hint={
target?.kind === "entity" target?.kind === "entity"
? "作品还没有收录版本时按模板顺序创建,第一个是主版本" ? "按模板顺序给本订阅创建收录版本,第一个是主版本;没有模板时建一个默认版本"
: "作品加入媒体库后按模板创建收录版本" : "作品加入媒体库后按模板创建收录版本"
} }
> >
@@ -121,10 +121,16 @@ export default function SubscriptionDetailPage() {
{item?.awaitingNewSeason ? <StatusBadge tone="success">等待新季</StatusBadge> : null} {item?.awaitingNewSeason ? <StatusBadge tone="success">等待新季</StatusBadge> : null}
{!sub.mediaEntityId ? <StatusBadge tone="warning">不在媒体库</StatusBadge> : null} {!sub.mediaEntityId ? <StatusBadge tone="warning">不在媒体库</StatusBadge> : null}
</div> </div>
{!sub.mediaEntityId ? (
<p className="max-w-xl rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-caption text-warning">
只按标题「{sub.titleQuery ?? title}
」订阅,还没关联到媒体库作品,不会自动搜索和下载。先把作品加入媒体库,再从作品订阅。
</p>
) : null}
{item ? ( {item ? (
<div className="grid max-w-xl gap-2"> <div className="grid max-w-xl gap-2">
<ProgressBlock x={item} /> <ProgressBlock x={item} />
<SlotBadges slots={item.slots} max={6} /> <SlotBadges slots={item.slots} max={6} unbound={!sub.mediaEntityId} />
</div> </div>
) : null} ) : null}
</div> </div>