import { api } from "../api.js"; import { cover, emptyState, sectionHeader } from "../components.js"; import { escapeAttr, escapeHtml, formatCount, formatDate, formatDuration, } from "../format.js"; function candidateCard(item) { const score = Number(item.score || 0); return `
${cover(item, "candidate-thumb")}
= 2 ? "mid" : "low"}">score ${score} ${item.notified_at ? `已通知` : `未通知`} 剩余 ${item.days_left} 天

${escapeHtml(item.title || "(无标题)")}

${escapeHtml(item.up_name || "未知 UP")} 发布 ${escapeHtml(formatDate(item.pubdate))} ${escapeHtml(formatDuration(item.duration))} ${escapeHtml(item.channel || "")}
播放 ${formatCount(item.play)} 点赞 ${formatCount(item.like)} 收藏 ${formatCount(item.favorite)} 弹幕 ${formatCount(item.danmaku)} 评论 ${formatCount(item.review)}
${item.url ? `打开 B 站` : ""} 请在 Telegram 中收藏 / 忽略 / 拉黑
`; } export async function renderCandidates(root) { const data = await api("/api/candidates"); const pending = data.items.filter((item) => item.decision === null); const decided = data.items.filter((item) => item.decision !== null); root.innerHTML = `

候选池

${formatCount(data.pending)} 条待确认 · ${formatCount(data.total)} 条总计 · 保留 ${data.ttl_days} 天

${data.items.length ? `
候选处理 ${data.telegram_enabled ? "请在 Telegram 消息中收藏、忽略或拉黑。" : "Telegram 未启用,请使用 CLI 或数据库处理候选。"}
` : ""}
${sectionHeader("待确认")} ${pending.length ? `
${pending.map(candidateCard).join("")}
` : emptyState("没有待确认候选", "搜索发现达到阈值的视频会出现在这里,同时发送 Telegram 通知。")}
${decided.length ? `
已处理候选(${decided.length})
${decided.map((item) => `
${escapeHtml(item.decision)} ${escapeHtml(item.title)} ${escapeHtml(item.up_name || "")}
`).join("")}
` : ""}
`; }