import { api } from "../api.js"; import { emptyState, cover, sectionHeader, videoCard, } from "../components.js"; import { escapeHtml, formatCount, formatDate, formatDelta, formatDateTime, formatPercent, formatScore, } from "../format.js"; function statChip(label, value, tone = "") { return `
${escapeHtml(label)}${value}
`; } function heatStrip(items) { if (!items.length) return emptyState("暂无热度数据", "完成一次快照后这里会出现榜单。"); return `
${items.map((item, index) => ` ${index + 1} ${cover(item, "heat-thumb")} ${escapeHtml(item.title)} ${escapeHtml(item.up_name || "未知 UP")} · ${formatCount(item.metrics?.view)} 播放 热度 ${formatScore(item.heat)} · 前 ${Math.max(0, 100 - (item.heat_percentile || 0)).toFixed(0)}% `).join("")}
`; } function capacity(folders) { if (!folders.length) return ""; return `
${sectionHeader("年度收藏夹")} ${folders.map((folder) => `
${escapeHtml(folder.title || String(folder.year))} ${formatCount(folder.media_count)} / ${formatCount(folder.capacity)}
${folder.warning ? `

接近容量上限,请准备新建年度收藏夹。

` : ""}
`).join("")}
`; } export async function renderHome(root) { const [overview, added, published, heat, growth] = await Promise.all([ api("/api/overview"), api("/api/videos", { sort: "added", within_days: 7, limit: 5 }), api("/api/videos", { sort: "published", within_days: 14, limit: 5 }), api("/api/videos", { sort: "heat", limit: 5 }), api("/api/videos", { sort: "growth", growth_days: 7, limit: 3 }), ]); const pending = overview.counts.candidates_pending || 0; const fans = overview.fans; const firstDay = overview.is_first_day; const addedLabel = firstDay ? formatCount(overview.initial_import_count) : formatCount(overview.added_today); const health = overview.snapshot_health || { total: 0, ok: 0, failed: 0 }; const addedNote = firstDay ? `

首次导入共 ${formatCount(overview.initial_import_count)} 条, 按发布时间倒序展示。后续每日增量从下一次快照开始。

` : `

按入库时间排序,展示最近 7 天新收录的视频。

`; root.innerHTML = `

最新动态

数据 ${escapeHtml(overview.data_date || "—")} · 采集 ${health.ok}/${health.total}${health.failed ? ` · 失败 ${health.failed}` : ""}

${statChip(firstDay ? "首次导入" : "今日入库", escapeHtml(addedLabel), "accent")} ${statChip("播放增量", overview.view_delta_available ? formatDelta(overview.view_delta) : "—")} ${statChip("粉丝日增", fans?.delta_1d === null || fans?.delta_1d === undefined ? "—" : formatDelta(fans.delta_1d))} ${statChip("待确认候选", formatCount(pending), pending ? "warning" : "")}
${pending ? ` ${formatCount(pending)} 条候选待确认 请在 Telegram 中处理 → ` : ""}

最新入库

查看全部
${addedNote}
${added.items.length ? added.items.map((item) => videoCard(item)).join("") : emptyState("最近 7 天没有新入库视频", "收藏夹同步或搜索确认后会出现在这里。")}

最近发布

查看全部

按视频发布时间排序,与入库时间无关。

${published.items.length ? published.items.map((item) => videoCard(item)).join("") : emptyState("最近 14 天没有新发布视频", "搜索发现的新视频会逐步补充。")}

增长动态

增长榜
${growth.available && growth.items.length ? `
${growth.items.map((item, index) => videoCard(item, { rank: index + 1 })).join("")}
` : emptyState("需要至少 2 天快照", growth.reason || "当前只有 1 个数据点,明天开始显示播放增量。")}

热度速览

完整榜单
${heatStrip(heat.items)}
${capacity(overview.folders || [])}
${sectionHeader("采集状态")}
快照完成${overview.snapshot_completed_today ? "是" : "否"}
数据日期${escapeHtml(overview.data_date || "—")}
粉丝${formatCount(fans?.follower)}
7 日粉丝${fans?.delta_7d === null || fans?.delta_7d === undefined ? "—" : formatDelta(fans.delta_7d)}
最近快照${escapeHtml(formatDateTime(overview.tasks?.snapshot?.finished_at))}
最近发现${escapeHtml(formatDateTime(overview.tasks?.discovery?.finished_at))}
查看系统状态 →
`; root.querySelector("#refresh-home")?.addEventListener("click", () => window.location.reload()); }