From aa2d64b599a33d891e5fcf9d06d060d7a68d95f5 Mon Sep 17 00:00:00 2001 From: davegilligan Date: Wed, 13 May 2026 19:12:09 +0200 Subject: [PATCH] =?UTF-8?q?Add=20transcribe=20progress=20indicator=20?= =?UTF-8?q?=E2=80=94=20elapsed=20timer=20and=20progressive=20trace=20messa?= =?UTF-8?q?ges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- assets/css/tools.css | 6 ++++++ assets/js/tools.js | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/assets/css/tools.css b/assets/css/tools.css index 3b1f3a6..23b1e87 100644 --- a/assets/css/tools.css +++ b/assets/css/tools.css @@ -457,6 +457,12 @@ p { .trace-status.running { background: var(--amber); + animation: trace-pulse 1.4s ease-in-out infinite; +} + +@keyframes trace-pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.4; transform: scale(0.7); } } .trace-status.warning { diff --git a/assets/js/tools.js b/assets/js/tools.js index 2adb355..50f08e2 100644 --- a/assets/js/tools.js +++ b/assets/js/tools.js @@ -564,7 +564,19 @@ async function runTranscribe() { return; } setBusy(true); - renderTrace([{ label: 'Sending to Whisper', detail: 'Uploading audio to cuttlefish GPU…', status: 'running' }]); + + const startTime = Date.now(); + let elapsed = 0; + updateTranscribeTrace(0); + els.status.textContent = 'Transcribing…'; + + const timer = setInterval(() => { + elapsed = Math.floor((Date.now() - startTime) / 1000); + const m = Math.floor(elapsed / 60); + const s = elapsed % 60; + els.status.textContent = m > 0 ? `Transcribing… ${m}:${pad2(s)}` : `Transcribing… ${s}s`; + updateTranscribeTrace(elapsed); + }, 1000); try { const formData = new FormData(); @@ -595,10 +607,29 @@ async function runTranscribe() { els.status.textContent = error.message; renderTrace([{ label: 'Transcription error', detail: error.message, status: 'warning' }]); } finally { + clearInterval(timer); setBusy(false); } } +function updateTranscribeTrace(elapsed) { + let label, detail; + if (elapsed < 10) { + label = 'Uploading to Whisper'; + detail = 'Sending audio to cuttlefish GPU…'; + } else if (elapsed < 60) { + label = 'Processing on GPU'; + detail = 'Whisper is transcribing. Large files take 1–3 minutes.'; + } else if (elapsed < 120) { + label = 'Still processing…'; + detail = `${Math.floor(elapsed / 60)} min elapsed — Whisper is working through the audio.`; + } else { + label = 'Still processing…'; + detail = `${Math.floor(elapsed / 60)} min ${pad2(elapsed % 60)}s — long recordings can take several minutes.`; + } + renderTrace([{ label, detail, status: 'running' }]); +} + function renderTranscriptResults(data) { const speakerRoles = data.speaker_roles || {}; const segments = data.segments || [];