"""主页:上传入口 + 最近 10 个任务的实时进度。 共享 _shared.py 的 BASE_CSS / SHARED_JS / 上传协议 JS。 页面专属:refreshList(拉取最近任务)、makeTaskCard、pollTask(轮询进行中任务)。 """ from __future__ import annotations from ._shared import POLL_INTERVAL, render_page, render_upload_js RECENT_LIMIT = 10 LIST_REFRESH_INTERVAL = 5000 _PAGE_JS = f""" const POLL_INTERVAL = {POLL_INTERVAL}; const LIST_REFRESH_INTERVAL = {LIST_REFRESH_INTERVAL}; const RECENT_LIMIT = {RECENT_LIMIT}; const tasksEl = document.getElementById("tasks"); const emptyEl = document.getElementById("empty"); let pollingIds = new Set(); // 初始化上传区 initUpload(document.getElementById("drop"), document.getElementById("file-input"), tasksEl); // ==================== 最近任务列表 ==================== async function refreshList() {{ try {{ const r = await fetch("/api/tasks?limit=" + RECENT_LIMIT); if (!r.ok) return; const data = await r.json(); renderTasks(data.tasks); }} catch (e) {{}} }} function renderTasks(tasks) {{ tasksEl.querySelectorAll(".server-task").forEach(el => el.remove()); const hasUploadCards = tasksEl.querySelector(".upload-task") !== null; emptyEl.style.display = (tasks.length === 0 && !hasUploadCards) ? "block" : "none"; for (const task of tasks) {{ tasksEl.appendChild(makeTaskCard(task)); }} // 对进行中的任务启动轮询(上传会话用 upload_id 去重,Task 用 id 去重) for (const task of tasks) {{ if (!ACTIVE_STATES.includes(task.status)) continue; const pollKey = task.is_upload ? task.upload_id : String(task.id); if (pollingIds.has(pollKey)) continue; pollingIds.add(pollKey); pollTask(task); }} }} function downloadLinks(taskId) {{ return `双语 SRT` + ` 英` + ` 中`; }} function makeTaskCard(task) {{ const el = document.createElement("div"); el.className = "card task server-task"; el.dataset.taskId = task.id; if (task.is_upload) el.dataset.uploadId = task.upload_id; el.innerHTML = renderTaskInner(task); return el; }} function renderTaskInner(task) {{ const label = STATUS_LABEL[task.status] || task.status; const stateClass = task.status === "done" ? "state-done" : task.status === "failed" ? "state-fail" : "state-running"; // 上传中:created_at 可能是 naive UTC,前端按 UTC 解析 let created; try {{ created = fmtDateTime24(new Date(task.created_at + "Z")); }} catch (e) {{ created = task.created_at; }} let body; if (task.status === "done") {{ body = `
`; }} else if (task.status === "failed") {{ body = ``; }} else {{ const pct = (task.progress == null) ? 0 : task.progress; const sizeInfo = task.size_bytes ? ` · ${{fmtBytes(task.size_bytes)}}` : ""; body = ``; }} return `上传视频或音频文件,自动生成双语(英/中)SRT 字幕。支持大文件分片上传与断点续传。
把文件拖到这里,或