feat: 历史列表添加交错滑入动画
- renderHistory 改为索引循环,设置 CSS 变量 --i 实现交错延迟 - 最大交错层级限制为 10(400ms),避免过长等待
This commit is contained in:
41
web/app.ts
41
web/app.ts
@@ -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>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user