feat(ui): densify home and ranking video cards

Drop nested home panels, overlay rank and duration on covers, and keep
metrics fully visible by moving dates onto the author row.
This commit is contained in:
kairee committed 2026-11-02 12:19:30 +08:00
1 parent 2641ba6f87
commit 374b138041
3 files changed
+165 -86

No files matched your search

+11 -13
View File
@@ -1,8 +1,8 @@
import { api } from "../api.js";
import { emptyState, mediaCard } from "../components.js";
import {
escapeAttr, escapeHtml, formatCount, formatDate, formatDelta,
formatDuration, formatPercent, formatScore,
escapeAttr, escapeHtml, formatCount, formatDelta,
formatPercent, formatScore,
} from "../format.js";
import { canAccessProtected } from "../session.js";
@@ -19,7 +19,6 @@ function heatGrid(items) {
return `<div class="media-grid">
${items.map((item, index) => mediaCard(item, {
rank: index + 1,
meta: `${escapeHtml(item.up_name || "未知 UP")} · ${formatCount(item.metrics?.view)} 播放`,
highlight: `热度 ${formatScore(item.heat)} · 前 ${Math.max(0, 100 - (item.heat_percentile || 0)).toFixed(0)}%`,
})).join("")}
</div>`;
@@ -27,19 +26,18 @@ function heatGrid(items) {
function publishedCard(item) {
return mediaCard(item, {
meta: `${escapeHtml(item.up_name || "未知 UP")} · ${escapeHtml(formatDate(item.pubdate))} · ${escapeHtml(formatDuration(item.duration))}`,
highlight: `${formatCount(item.metrics?.view)} 播放 · 互动 ${formatPercent(item.interaction_rate)}`,
});
}
function growthCard(item, index) {
const delta = item.growth?.delta;
const deltaText = delta === null || delta === undefined ? "" : ` · ${formatDelta(delta)}`;
return mediaCard(item, {
rank: index + 1,
meta: `${escapeHtml(item.up_name || "未知 UP")} · ${escapeHtml(formatDate(item.pubdate))} · ${escapeHtml(formatDuration(item.duration))}`,
highlight: `${formatCount(item.metrics?.view)} 播放${deltaText}`,
});
let highlight = `${formatCount(item.metrics?.view)} 播放`;
if (delta !== null && delta !== undefined) {
const tone = Number(delta) >= 0 ? "up" : "down";
highlight += ` <span class="${tone}">${formatDelta(delta)}</span>`;
}
return mediaCard(item, { rank: index + 1, highlight });
}
export async function renderHome(root) {
@@ -96,7 +94,7 @@ export async function renderHome(root) {
<span>请在 Telegram 中处理 →</span>
</a>` : ""}
<section class="panel">
<section class="home-block">
<div class="section-head">
<h2>最近发布</h2>
<a class="text-link" href="/videos?sort=published&within_days=30">查看全部</a>
@@ -108,7 +106,7 @@ export async function renderHome(root) {
</div>
</section>
<section class="panel">
<section class="home-block">
<div class="section-head">
<h2>增长动态 · ${escapeHtml(growthLabel)}</h2>
<a class="text-link" href="/videos?sort=growth&growth_days=${growthDays}">增长榜</a>
@@ -118,7 +116,7 @@ export async function renderHome(root) {
: emptyState(growthEmptyTitle, growthEmptyHint)}
</section>
<section class="panel">
<section class="home-block">
<div class="section-head">
<h2>热度速览</h2>
<a class="text-link" href="/videos?sort=heat">完整榜单</a>