feat: 历史列表添加交错滑入动画

- renderHistory 改为索引循环,设置 CSS 变量 --i 实现交错延迟
- 最大交错层级限制为 10(400ms),避免过长等待
This commit is contained in:
2026-03-02 05:23:47 +08:00
parent 2c322f5ab1
commit 6c1b8e95c8

View File

@@ -128,19 +128,19 @@ function connectWS(): void {
micBtn.disabled = false; micBtn.disabled = false;
}; };
ws.onmessage = (e: MessageEvent) => handleServerMsg(e.data); ws.onmessage = (e: MessageEvent) => handleServerMsg(e.data);
ws.onclose = () => { ws.onclose = () => {
state.connected = false; state.connected = false;
state.ws = null; state.ws = null;
micBtn.disabled = true; micBtn.disabled = true;
if (state.recording) stopRecording(); if (state.recording) stopRecording();
if (state.pendingStart) { if (state.pendingStart) {
state.abortController?.abort(); state.abortController?.abort();
state.pendingStart = false; state.pendingStart = false;
micBtn.classList.remove("recording"); micBtn.classList.remove("recording");
} }
setStatus("disconnected", "已断开"); setStatus("disconnected", "已断开");
scheduleReconnect(); scheduleReconnect();
}; };
ws.onerror = () => ws.close(); ws.onerror = () => ws.close();
state.ws = ws; state.ws = ws;
} }
@@ -201,11 +201,14 @@ function showToast(msg: string): void {
const toast = q("#toast"); const toast = q("#toast");
toast.textContent = msg; toast.textContent = msg;
toast.classList.add("show"); toast.classList.add("show");
const timer = (toast as HTMLElement & { _timer?: ReturnType<typeof setTimeout> })._timer; const timer = (
toast as HTMLElement & { _timer?: ReturnType<typeof setTimeout> }
)._timer;
if (timer) clearTimeout(timer); if (timer) clearTimeout(timer);
(toast as HTMLElement & { _timer?: ReturnType<typeof setTimeout> })._timer = setTimeout(() => { (toast as HTMLElement & { _timer?: ReturnType<typeof setTimeout> })._timer =
toast.classList.remove("show"); setTimeout(() => {
}, 2000); toast.classList.remove("show");
}, 2000);
} }
// ── Audio pipeline ── // ── Audio pipeline ──
async function initAudio(): Promise<void> { async function initAudio(): Promise<void> {
@@ -331,8 +334,10 @@ function renderHistory(): void {
return; return;
} }
(historyEmpty as HTMLElement).style.display = "none"; (historyEmpty as HTMLElement).style.display = "none";
for (const item of items) { for (let i = 0; i < items.length; i++) {
const item = items[i];
const li = document.createElement("li"); const li = document.createElement("li");
li.style.setProperty("--i", String(Math.min(i, 10)));
li.innerHTML = li.innerHTML =
`<span class="hist-text">${escapeHtml(item.text)}</span>` + `<span class="hist-text">${escapeHtml(item.text)}</span>` +
`<span class="hist-time">${formatTime(item.ts)}</span>`; `<span class="hist-time">${formatTime(item.ts)}</span>`;