feat(web): up avatars, follower count, and dedupe views/avg secondary

This commit is contained in:
kairee committed 2026-11-01 14:34:23 +08:00
1 parent 1ed3746f4b
commit 2ff3e7952b
23 files changed
+209 -58

No files matched your search

+20 -7
View File
@@ -19,6 +19,17 @@ export function rankBadge(rank) {
return `<span class="rank-badge${top}">${rank}</span>`;
}
export function avatar(item, className = "avatar") {
const url = coverUrl(item?.up_face || item?.avatar);
const name = escapeHtml(item?.up_name || "UP");
if (!url) {
const initial = String(item?.up_name || "U").trim().slice(0, 1).toUpperCase() || "U";
return `<div class="${className} avatar-placeholder" aria-hidden="true">${escapeHtml(initial)}</div>`;
}
return `<div class="${className}"><img src="${escapeAttr(url)}" alt="${name}"
loading="lazy" referrerpolicy="no-referrer"></div>`;
}
export function videoCard(item, {
rank = null, primary = "view", primaryLabel = "", primaryText = null,
showStatus = false,
@@ -64,27 +75,29 @@ export function videoCard(item, {
export function upCard(item, {
rank = null, primary = "efficiency", primaryLabel = "播放/小时", primaryText = null,
secondaryLabel = "总播放", secondaryText = null,
} = {}) {
const best = item.best_video || {};
const displayCover = cover(
{ title: best.title || item.up_name, cover: best.cover },
"video-thumb up-thumb",
);
const value = primaryText !== null ? primaryText : item[primary];
const secondary = secondaryText !== null ? secondaryText : formatCount(item.total_views);
const hours = item.content_hours;
const follower = item.follower_latest;
const followerText = follower === null || follower === undefined
? "粉丝 —"
: `粉丝 ${formatCount(follower)}`;
return `
<a class="up-card" href="/up/${item.up_mid}">
${rankBadge(rank)}
${displayCover}
${avatar(item, "up-avatar")}
<div class="up-card-body">
<h3 class="video-title">${escapeHtml(item.up_name || `UP ${item.up_mid}`)}</h3>
<div class="video-meta">
<span>${formatNumber(item.video_count)} 条视频</span>
<span>${hours === null || hours === undefined ? "时长未知" : `${formatNumber(hours)} 小时`}</span>
<span>${followerText}</span>
</div>
<div class="video-stats">
<span class="primary-stat"><b>${escapeHtml(value ?? "—")}</b><small>${escapeHtml(primaryLabel)}</small></span>
<span class="secondary-stat">总播放 ${formatCount(item.total_views)}</span>
<span class="secondary-stat">${escapeHtml(secondaryLabel)} ${escapeHtml(secondary)}</span>
</div>
</div>
<span class="card-arrow" aria-hidden="true">›</span>