diff --git a/python/voice_to_notes/services/pipeline.py b/python/voice_to_notes/services/pipeline.py index fe4bf04..59f8186 100644 --- a/python/voice_to_notes/services/pipeline.py +++ b/python/voice_to_notes/services/pipeline.py @@ -140,7 +140,7 @@ class PipelineService: # Step 3: Merge (or skip if diarization failed) if diarization is not None: write_message( - progress_message(request_id, 90, "pipeline", "Merging transcript with speakers...") + progress_message(request_id, 90, "merging", "Merging transcript with speakers...") ) result = self._merge_results(transcription, diarization.speaker_segments) result.speakers = diarization.speakers diff --git a/src/lib/components/ProgressOverlay.svelte b/src/lib/components/ProgressOverlay.svelte index d88a147..2b7f40c 100644 --- a/src/lib/components/ProgressOverlay.svelte +++ b/src/lib/components/ProgressOverlay.svelte @@ -7,6 +7,38 @@ } let { visible = false, percent = 0, stage = '', message = '' }: Props = $props(); + + // Map internal stage names to user-friendly labels + const stageLabels: Record = { + 'pipeline': 'Pipeline', + 'loading_model': 'Loading Model', + 'transcribing': 'Transcribing', + 'loading_diarization': 'Loading Diarization', + 'diarizing': 'Speaker Detection', + 'done': 'Complete', + }; + + // Pipeline steps for the task list + const pipelineSteps = [ + { key: 'loading_model', label: 'Load transcription model' }, + { key: 'transcribing', label: 'Transcribe audio' }, + { key: 'loading_diarization', label: 'Load speaker detection model' }, + { key: 'diarizing', label: 'Identify speakers' }, + { key: 'merging', label: 'Merge results' }, + ]; + + function getStepStatus(stepKey: string, currentStage: string): 'pending' | 'active' | 'done' { + const stepOrder = pipelineSteps.map(s => s.key); + const currentIdx = stepOrder.indexOf(currentStage); + const stepIdx = stepOrder.indexOf(stepKey); + + if (currentStage === 'done') return 'done'; + if (stepIdx < currentIdx) return 'done'; + if (stepIdx === currentIdx) return 'active'; + return 'pending'; + } + + let displayStage = $derived(stageLabels[stage] || stage || 'Processing...'); {#if visible} @@ -14,12 +46,28 @@
-

{stage || 'Processing...'}

+

{displayStage}

-
-
+ +
+ {#each pipelineSteps as step} + {@const status = getStepStatus(step.key, stage)} +
+ + {#if status === 'done'} + ✓ + {:else if status === 'active'} + ⟳ + {:else} + · + {/if} + + {step.label} +
+ {/each}
-

{percent}% — {message || 'Please wait...'}

+ +

{message || 'Please wait...'}

This may take several minutes for large files

@@ -39,7 +87,8 @@ background: #16213e; padding: 2rem 2.5rem; border-radius: 12px; - min-width: 420px; + min-width: 380px; + max-width: 440px; color: #e0e0e0; border: 1px solid #2a3a5e; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); @@ -57,35 +106,52 @@ border-top-color: #e94560; border-radius: 50%; animation: spin 0.8s linear infinite; + flex-shrink: 0; } @keyframes spin { to { transform: rotate(360deg); } } h3 { margin: 0; - text-transform: capitalize; font-size: 1.1rem; } - .bar-track { - height: 10px; - background: #0f3460; - border-radius: 5px; - overflow: hidden; + .steps { + display: flex; + flex-direction: column; + gap: 0.4rem; + margin-bottom: 1rem; } - .bar-fill { - height: 100%; - background: linear-gradient(90deg, #e94560, #ff6b81); - transition: width 0.3s; - border-radius: 5px; + .step { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.85rem; + color: #555; + } + .step-done { + color: #4ecdc4; + } + .step-active { + color: #e0e0e0; + font-weight: 500; + } + .step-icon { + width: 1.2rem; + text-align: center; + flex-shrink: 0; + } + .step-active .step-icon { + animation: spin 1.5s linear infinite; + display: inline-block; } .status-text { margin: 0.75rem 0 0; - font-size: 0.9rem; + font-size: 0.85rem; color: #b0b0b0; } .hint-text { margin: 0.5rem 0 0; font-size: 0.75rem; - color: #666; + color: #555; } diff --git a/src/lib/components/SpeakerManager.svelte b/src/lib/components/SpeakerManager.svelte index c5a925b..a3c773a 100644 --- a/src/lib/components/SpeakerManager.svelte +++ b/src/lib/components/SpeakerManager.svelte @@ -34,7 +34,11 @@

Speakers

{#if $speakers.length === 0} -

No speakers detected yet

+

No speakers detected

+

+ Speaker detection requires a HuggingFace token. + Set the HF_TOKEN environment variable and restart. +

{:else}