feat(web): refresh palette, simplify ranking toolbar and drop export

This commit is contained in:
kairee committed 2026-11-01 00:37:20 +08:00
1 parent 6a053bdfe8
commit c2ef998720
16 files changed
+141 -206

No files matched your search

+12 -19
View File
@@ -1,4 +1,4 @@
import { api, apiUrl } from "../api.js";
import { api } from "../api.js";
import {
centerActiveChips, chip, emptyState, pager, sectionHeader, upCard, videoCard,
} from "../components.js";
@@ -8,7 +8,7 @@ import { replaceQuery } from "../router.js";
const VIDEO_SORTS = [
["heat", "综合热度"], ["view", "播放"], ["like", "点赞"], ["coin", "投币"],
["favorite", "收藏"], ["share", "转发"], ["reply", "评论"], ["danmaku", "弹幕"],
["interaction", "互动率"], ["growth", "增长"], ["growth_rate", "增速"],
["interaction", "互动率"], ["growth", "播放增量"], ["growth_rate", "播放增速"],
];
const UP_SORTS = [
["avg_views", "平均播放"], ["avg_interaction", "平均互动"],
@@ -20,18 +20,20 @@ const METRIC_PRIMARY = new Set(["view", "like", "coin", "favorite", "share", "re
function controls({ scope, sort, within, growthDays, q, folder, minVideos, folders }) {
const sorts = scope === "up" ? UP_SORTS : VIDEO_SORTS;
return `
<div class="segmented" role="tablist">
<button type="button" class="${scope === "video" ? "active" : ""}" data-scope="video">视频</button>
<button type="button" class="${scope === "up" ? "active" : ""}" data-scope="up">UP</button>
<div class="rank-toolbar">
<div class="segmented" role="tablist">
<button type="button" class="${scope === "video" ? "active" : ""}" data-scope="video">视频</button>
<button type="button" class="${scope === "up" ? "active" : ""}" data-scope="up">UP</button>
</div>
<form class="rank-search" id="rank-filter">
<input class="search-input" type="search" name="q" value="${escapeAttr(q || "")}"
placeholder="${scope === "up" ? "搜索 UP 名" : "搜索标题或 UP"}" autocomplete="off">
<button class="button" type="submit">搜索</button>
</form>
</div>
<div class="chip-row scroll-x">
${sorts.map(([value, label]) => chip(label, sort === value, "sort", value)).join("")}
</div>
<form class="filter-bar" id="rank-filter">
<input class="search-input" type="search" name="q" value="${escapeAttr(q || "")}"
placeholder="${scope === "up" ? "搜索 UP 名" : "搜索标题或 UP"}" autocomplete="off">
<button class="button" type="submit">搜索</button>
</form>
<div class="filter-row">
<div class="chip-row scroll-x">
${[["all", "全部发布时间"], ["7", "近 7 天"], ["30", "近 30 天"], ["90", "近 90 天"]]
@@ -106,12 +108,6 @@ export async function renderRankings(root, { query }) {
}
const startRank = (data.page - 1) * data.page_size + 1;
const exportParams = {
...params, folder: folder || null, scope,
min_videos: scope === "up" ? minVideos : null,
};
delete exportParams.page;
delete exportParams.page_size;
root.innerHTML = `<section class="page rankings-page">
<header class="page-head">
@@ -119,9 +115,6 @@ export async function renderRankings(root, { query }) {
<h1>榜单</h1>
<p class="page-sub">共 ${formatCount(data.total)} ${scope === "up" ? "个 UP" : "条视频"}</p>
</div>
${scope === "video"
? `<a class="button ghost" href="${escapeAttr(apiUrl("/api/export.csv", exportParams))}">导出 CSV</a>`
: ""}
</header>
${controls({ scope, sort, within, growthDays, q, folder, minVideos, folders })}
${data.available === false ? `<div class="notice-row warning">