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

+33 -15
View File
@@ -13,10 +13,10 @@ export function cover(item, className = "thumb") {
loading="lazy" referrerpolicy="no-referrer"></div>`;
}
export function rankBadge(rank) {
export function rankBadge(rank, className = "rank-badge") {
if (!rank) return "";
const top = rank <= 3 ? ` rank-${rank}` : "";
return `<span class="rank-badge${top}">${rank}</span>`;
return `<span class="${className}${top}">${rank}</span>`;
}
export function avatar(item, className = "avatar") {
@@ -51,19 +51,25 @@ export function videoCard(item, {
const upLink = upMid ? `<span class="up-name" data-up-mid="${upMid}">${up}</span>` : up;
const status = showStatus && item.status
? `<span class="badge status-${escapeAttr(item.status)}">${escapeHtml(statusLabel(item.status))}</span>` : "";
const duration = formatDuration(item.duration);
const durationBadge = duration === "—"
? ""
: `<span class="cover-duration">${escapeHtml(duration)}</span>`;
return `
<a class="video-card${rank ? "" : " no-rank"}" href="/video/${item.aid}" data-aid="${item.aid}">
<a class="video-card" href="/video/${item.aid}" data-aid="${item.aid}">
${rankBadge(rank)}
${cover(item, "video-thumb")}
<div class="video-cover">
${cover(item, "video-thumb")}
${durationBadge}
</div>
<div class="video-card-body">
<h3 class="video-title">${title}</h3>
<div class="video-meta">
<span>${upLink}</span>
<span>${escapeHtml(formatDate(item.pubdate))}</span>
<span>${escapeHtml(formatDuration(item.duration))}</span>
${status}
<div class="video-byline">
<div class="video-up">${upLink}</div>
<span class="video-date">${escapeHtml(formatDate(item.pubdate))}</span>
</div>
<div class="video-stats">
${status}
<span class="primary-stat">
<b>${escapeHtml(primaryValue ?? "—")}</b><small>${escapeHtml(label)}</small>
</span>
@@ -88,7 +94,9 @@ export function upCard(item, {
return `
<a class="up-card" href="/up/${item.up_mid}">
${rankBadge(rank)}
${avatar(item, "up-avatar")}
<div class="up-cover">
${avatar(item, "up-avatar")}
</div>
<div class="up-card-body">
<h3 class="video-title">${escapeHtml(item.up_name || `UP ${item.up_mid}`)}</h3>
<div class="video-meta">
@@ -120,12 +128,22 @@ export function metricGrid(item) {
</div>`;
}
export function mediaCard(item, { rank = null, meta = "", highlight = "" } = {}) {
export function mediaCard(item, { rank = null, highlight = "" } = {}) {
const duration = formatDuration(item.duration);
const durationBadge = duration === "—"
? ""
: `<span class="cover-duration">${escapeHtml(duration)}</span>`;
return `<a class="media-card" href="/video/${item.aid}" data-aid="${item.aid}">
${rank === null || rank === undefined ? "" : `<span class="media-rank">${escapeHtml(String(rank))}</span>`}
${cover(item, "media-thumb")}
<strong class="media-title">${escapeHtml(item.title || "(无标题)")}</strong>
${meta ? `<span class="media-meta">${meta}</span>` : ""}
${rankBadge(rank)}
<div class="media-cover">
${cover(item, "media-thumb")}
${durationBadge}
</div>
<span class="media-title">${escapeHtml(item.title || "(无标题)")}</span>
<span class="media-byline">
<span class="media-up">${escapeHtml(item.up_name || "未知 UP")}</span>
<span class="media-date">${escapeHtml(formatDate(item.pubdate))}</span>
</span>
${highlight ? `<span class="media-highlight">${highlight}</span>` : ""}
</a>`;
}