Commit 38245bd442863a55fcb4f06b05e4c864545828e9
1 parent
af536bdd
Replace preview modal with inline video player per row
The modal (previous commit) meant an extra click and a popup just to see the clip. Swap it for a native <video controls preload="none"> directly in the 预览 column — preload="none" keeps the 361-row table from firing off thumbnails for every row on load, and clicking the player's own play button starts it right there, no dialog involved. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011DUiYs6UjxDMkfvnjtsKFo
Showing
1 changed file
with
3 additions
and
20 deletions
admin.html
| ... | ... | @@ -25,9 +25,7 @@ |
| 25 | 25 | .count-hint { color: var(--muted); font-size: 12px; margin-bottom: 10px; } |
| 26 | 26 | .channel-tabs { display: flex; gap: 8px; margin-bottom: 14px; } |
| 27 | 27 | .channel-tabs button.active { background: var(--accent); color: #fff; border-color: var(--accent); } |
| 28 | - #previewDialog { padding: 0; border: none; border-radius: var(--radius); background: #000; } | |
| 29 | - #previewDialog::backdrop { background: rgba(0,0,0,.6); } | |
| 30 | - #previewDialog video { display: block; max-width: 80vw; max-height: 80vh; } | |
| 28 | + td.preview video { display: block; width: 180px; max-height: 200px; background: #000; border-radius: 4px; } | |
| 31 | 29 | </style> |
| 32 | 30 | </head> |
| 33 | 31 | <body> |
| ... | ... | @@ -103,10 +101,6 @@ |
| 103 | 101 | </div> |
| 104 | 102 | </main> |
| 105 | 103 | |
| 106 | -<dialog id="previewDialog"> | |
| 107 | - <video id="previewVideo" controls autoplay></video> | |
| 108 | -</dialog> | |
| 109 | - | |
| 110 | 104 | <script> |
| 111 | 105 | // Redirect to login whenever any /api/admin/* call comes back 401 (T6 auth |
| 112 | 106 | // gate) — a single interceptor instead of touching every fetch call site. |
| ... | ... | @@ -208,7 +202,7 @@ function render() { |
| 208 | 202 | <td class="name"><input data-field="promptEn" value="${escapeHtml(c.promptEn || "")}" /></td> |
| 209 | 203 | <td class="prompt"><textarea data-field="fullPrompt">${escapeHtml(c.fullPrompt || "")}</textarea></td> |
| 210 | 204 | <td><input data-field="videoUrl" value="${escapeHtml(c.videoUrl || "")}" placeholder="留空=保持原有播放源" /></td> |
| 211 | - <td><button class="secondary" data-preview="${c.id}">▶ 预览</button></td> | |
| 205 | + <td class="preview"><video controls preload="none" src="${videoHref(c)}"></video></td> | |
| 212 | 206 | <td> |
| 213 | 207 | <select data-field="channel"> |
| 214 | 208 | <option value="video" ${c.channel === "dance" ? "" : "selected"}>视频直播间</option> |
| ... | ... | @@ -233,7 +227,7 @@ function render() { |
| 233 | 227 | <td class="name">${escapeHtml(c.promptEn || "")}</td> |
| 234 | 228 | <td class="prompt" title="${escapeHtml(c.fullPrompt || "")}">${escapeHtml((c.fullPrompt || "").slice(0, 80))}${(c.fullPrompt || "").length > 80 ? "…" : ""}</td> |
| 235 | 229 | <td><a class="video-link" href="${videoHref(c)}" target="_blank">${videoHref(c)}</a></td> |
| 236 | - <td><button class="secondary" data-preview="${c.id}">▶ 预览</button></td> | |
| 230 | + <td class="preview"><video controls preload="none" src="${videoHref(c)}"></video></td> | |
| 237 | 231 | <td>${c.channel === "dance" ? "跳舞直播间" : "视频直播间"}</td> |
| 238 | 232 | <td>${escapeHtml(traceability(c))}</td> |
| 239 | 233 | <td>${c.duration ?? "-"}s</td> |
| ... | ... | @@ -267,12 +261,6 @@ function render() { |
| 267 | 261 | } |
| 268 | 262 | }) |
| 269 | 263 | ); |
| 270 | - tbody.querySelectorAll("[data-preview]").forEach((b) => | |
| 271 | - b.addEventListener("click", () => { | |
| 272 | - previewVideo.src = videoHref(rows.find((c) => c.id === b.dataset.preview)); | |
| 273 | - previewDialog.showModal(); | |
| 274 | - }) | |
| 275 | - ); | |
| 276 | 264 | tbody.querySelectorAll("[data-del]").forEach((b) => |
| 277 | 265 | b.addEventListener("click", async () => { |
| 278 | 266 | if (!confirm("确认删除这条片段?(如果来自 H3 Console 会同步从那边删除)")) return; |
| ... | ... | @@ -293,11 +281,6 @@ document.querySelectorAll("th[data-sort]").forEach((th) => { |
| 293 | 281 | }); |
| 294 | 282 | }); |
| 295 | 283 | |
| 296 | -const previewDialog = document.getElementById("previewDialog"); | |
| 297 | -const previewVideo = document.getElementById("previewVideo"); | |
| 298 | -previewDialog.addEventListener("click", (e) => { if (e.target === previewDialog) previewDialog.close(); }); | |
| 299 | -previewDialog.addEventListener("close", () => { previewVideo.pause(); previewVideo.src = ""; }); | |
| 300 | - | |
| 301 | 284 | document.getElementById("searchInput").addEventListener("input", render); |
| 302 | 285 | document.getElementById("sourceFilter").addEventListener("change", render); |
| 303 | 286 | ... | ... |