v2.4: UI 规范化(token体系) + 复制直播链接 + 设置页间距
- 建立完整 token 体系: 色板/字号阶梯(9档)/圆角阶梯/阴影/动效/间距 - 字号 42→9 种、圆角 20→8 种、正文硬编码色清零 - 补丁区(v2/v2.1/v2.2 追加段)并入主体系: 统一缩进 + 全用 token - header「打开直播流」改为「复制直播流链接」(navigator.clipboard + 降级) - header 图标按钮统一为胶囊形(20px 圆角) - 设置页: .page.active 加 gap, section-body 内边距对齐, 缓解拥挤 测试: api 16/16, e2e 17/17, write 5/5 全绿
This commit is contained in:
1 parent
5d5d5cce19
commit
16df0a7d08
4 files changed
+593
-509
No files matched your search
+48
@@ -367,3 +367,51 @@ python test_enrich.py # 给 5 首补封面(已跑过,5/5 成功)
|
||||
### 16.6 未做 / 可选后续
|
||||
- 是否 `git commit`(工作区改动含本次 + 上轮 v2.2,均未提交)。
|
||||
- 深色模式、缓存条颜色再打磨、其余「AI 味」细节。
|
||||
|
||||
---
|
||||
|
||||
## 17. v2.4 UI 规范化 / Token 体系(已完成 2026-09-24)
|
||||
|
||||
> 老板反馈「整体 UI 风格很撕裂」→ 全量重构 `style.css` 的 token 与取值体系。
|
||||
|
||||
### 17.1 问题诊断
|
||||
`style.css` 原是两段拼接:**主体系**(1~1730,16 空格缩进、有分节) + **补丁区**(1731+,不缩进、硬编码色的 v2/v2.1/v2.2 追加)。具体失控:
|
||||
- 字号 **42 种**(0.54~2.4rem 密密麻麻,还混用 `0.82rem`/`.82rem` 写法)
|
||||
- 圆角 **约 20 种**(3/5/6/7/8/9/10/11/12/14/16/18/20/22/28px,定义了 `--radius-*` 却大半没用)
|
||||
- 颜色硬编码:55 hex + 38 rgba,兜底色 `#1f6feb` 出现 8 次(带 `var(--accent,#1f6feb)` fallback)
|
||||
|
||||
### 17.2 重构内容
|
||||
**建立完整 token 体系**(`:root` 重写):
|
||||
- 色板:`--bg/surface/white/accent*/text*/border*/danger*/success*/warning*/overlay/log-*`
|
||||
- 字号阶梯 9 档:`--fs-2xs/…/--fs-4xl`
|
||||
- 圆角阶梯:`--radius-xs/sm/base/lg/xl/pill`
|
||||
- 阴影:`--shadow-xs/sm/base/lg/accent`
|
||||
- 动效:`--dur-fast/base/slow` + `--ease-out/spring`
|
||||
- 间距:`--sp-1`~`--sp-6`
|
||||
|
||||
**全局收敛**:
|
||||
- `font-size`:42 种 → **9 种**(67 处替换为 var)
|
||||
- `border-radius`:20 种 → **8 种**(28 处替换为 var,余 50%/xl 特殊)
|
||||
- 硬编码色:正文区 **清零**(全转 var)
|
||||
- accent 阴影重复值收进 `--shadow-accent`;`#fff`→`--white`;`#fdd`→`--danger-hover`
|
||||
- **补丁区整体并入主体系**:统一 12 空格缩进、改用 `--fs-*`/`--radius-*`/`--sp-*`、重写分节注释
|
||||
|
||||
### 17.3 关键取值变化(有意微调,贴近原值)
|
||||
- `--radius-sm`: 12px→10px,`--radius`: 16px→14px,`--radius-lg`: 24px→20px,`--radius-xl`: 28px 保留
|
||||
- 补丁区硬编码圆角 14/18/22px → 归入 `--radius/--radius-lg`
|
||||
- live-cover-ph 大图标 2.4rem → `--fs-4xl`
|
||||
|
||||
### 17.4 验证
|
||||
- 全文括号配平({} 360/360、( ) 581/581),无 var 残渣/嵌套。
|
||||
- 回归:api 16/16、e2e 17/17、write 5/5 全绿。
|
||||
- `node --check app.js` 通过。
|
||||
|
||||
### 17.5 待老板浏览器实测
|
||||
- 整体观感是否统一(字号阶梯、圆角、配色)。
|
||||
- 特别注意:卡片圆角、按钮胶囊、模态框圆角的和谐度。
|
||||
|
||||
### 17.6 保留项(非撕裂)
|
||||
- 毛玻璃 `rgba(255,255,255,…)` 背景、阴影 rgba:正当设计值。
|
||||
- `login.html` 独立暗色主题(自己的 `:root`)。
|
||||
- `body` 字体栈、`--log-bg` 终端风格:保留。
|
||||
|
||||
+525
-503
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -39,8 +39,8 @@
|
||||
<div class="header-actions">
|
||||
<span class="cache-pill" id="cacheInfo"><i class="bi bi-database"></i> --</span>
|
||||
<button class="channel-btn" id="btnStreamMgr" title="频道与切换"><i class="bi bi-broadcast"></i><span id="currentChannelName">主电台</span></button>
|
||||
<a href="#" id="liveLink" class="btn-link-sm" target="_blank" title="打开直播流"
|
||||
><i class="bi bi-link-45deg"></i></a
|
||||
<button class="btn-link-sm" id="liveLink" title="复制直播流链接"
|
||||
><i class="bi bi-link-45deg"></i></button
|
||||
>
|
||||
<button class="btn-link-sm" id="btnLogout" title="退出登录"
|
||||
><i class="bi bi-box-arrow-right"></i></button>
|
||||
|
||||
+18
-4
@@ -5,6 +5,7 @@
|
||||
|
||||
// ==================== 全局状态 ====================
|
||||
let currentStreamId = "main";
|
||||
let liveStreamUrl = "/hls/main/index.m3u8";
|
||||
const state = { streams: [], resources: [], playlist: [] };
|
||||
|
||||
// ==================== Toast ====================
|
||||
@@ -101,13 +102,26 @@ async function loadStreams() {
|
||||
const cur = state.streams.find((s) => s.id === currentStreamId);
|
||||
const nameEl = document.getElementById("currentChannelName");
|
||||
if (nameEl) nameEl.textContent = cur ? (cur.name || cur.id) : "主电台";
|
||||
document.getElementById("liveLink").href = cur ? cur.m3u8 : "/hls/main/index.m3u8";
|
||||
liveStreamUrl = cur ? cur.m3u8 : "/hls/main/index.m3u8";
|
||||
updateLiveUI();
|
||||
} catch (e) { console.error("加载流失败", e); }
|
||||
}
|
||||
document.getElementById("liveLink").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
window.open(e.currentTarget.href, "_blank");
|
||||
document.getElementById("liveLink").addEventListener("click", async () => {
|
||||
const url = new URL(liveStreamUrl, location.origin).href;
|
||||
try {
|
||||
await navigator.clipboard.writeText(url);
|
||||
showToast("已复制直播流链接", "success");
|
||||
} catch (err) {
|
||||
const ta = document.createElement("textarea");
|
||||
ta.value = url;
|
||||
ta.style.position = "fixed";
|
||||
ta.style.opacity = "0";
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { document.execCommand("copy"); showToast("已复制直播流链接", "success"); }
|
||||
catch (e2) { showToast("复制失败,请手动复制: " + url, "error"); }
|
||||
ta.remove();
|
||||
}
|
||||
});
|
||||
document.getElementById("btnLogout").addEventListener("click", async () => {
|
||||
await post("/api/auth/logout").catch(() => {});
|
||||
|
||||
Reference in new issue
Block a user