Add cancel button to processing overlay with confirmation
- Cancel button on the progress overlay during transcription - Clicking Cancel shows confirmation: "Processing is incomplete. If you cancel now, the transcription will need to be started over." - "Continue Processing" dismisses the dialog, "Cancel Processing" stops - Cancel clears partial results (segments, speakers) and resets UI - Pipeline results are discarded if cancelled during processing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,9 +4,25 @@
|
|||||||
percent?: number;
|
percent?: number;
|
||||||
stage?: string;
|
stage?: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
|
onCancel?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { visible = false, percent = 0, stage = '', message = '' }: Props = $props();
|
let { visible = false, percent = 0, stage = '', message = '', onCancel }: Props = $props();
|
||||||
|
|
||||||
|
let showConfirm = $state(false);
|
||||||
|
|
||||||
|
function handleCancelClick() {
|
||||||
|
showConfirm = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmCancel() {
|
||||||
|
showConfirm = false;
|
||||||
|
onCancel?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismissCancel() {
|
||||||
|
showConfirm = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Pipeline steps in order
|
// Pipeline steps in order
|
||||||
const pipelineSteps = [
|
const pipelineSteps = [
|
||||||
@@ -89,6 +105,20 @@
|
|||||||
|
|
||||||
<p class="status-text">{message || 'Please wait...'}</p>
|
<p class="status-text">{message || 'Please wait...'}</p>
|
||||||
<p class="hint-text">This may take several minutes for large files</p>
|
<p class="hint-text">This may take several minutes for large files</p>
|
||||||
|
|
||||||
|
{#if onCancel && !showConfirm}
|
||||||
|
<button class="cancel-btn" onclick={handleCancelClick}>Cancel</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if showConfirm}
|
||||||
|
<div class="confirm-box">
|
||||||
|
<p class="confirm-text">Processing is incomplete. If you cancel now, the transcription will need to be started over.</p>
|
||||||
|
<div class="confirm-actions">
|
||||||
|
<button class="confirm-keep" onclick={dismissCancel}>Continue Processing</button>
|
||||||
|
<button class="confirm-cancel" onclick={confirmCancel}>Cancel Processing</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -174,4 +204,62 @@
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
|
.cancel-btn {
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: none;
|
||||||
|
border: 1px solid #4a5568;
|
||||||
|
color: #999;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.cancel-btn:hover {
|
||||||
|
color: #e0e0e0;
|
||||||
|
border-color: #e94560;
|
||||||
|
}
|
||||||
|
.confirm-box {
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: rgba(233, 69, 96, 0.08);
|
||||||
|
border: 1px solid #e94560;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
.confirm-text {
|
||||||
|
margin: 0 0 0.75rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #e0e0e0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.confirm-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.confirm-keep {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.4rem;
|
||||||
|
background: #0f3460;
|
||||||
|
border: 1px solid #4a5568;
|
||||||
|
color: #e0e0e0;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
.confirm-keep:hover {
|
||||||
|
background: #1a4a7a;
|
||||||
|
}
|
||||||
|
.confirm-cancel {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.4rem;
|
||||||
|
background: #e94560;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
.confirm-cancel:hover {
|
||||||
|
background: #d63851;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -119,11 +119,23 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
let isTranscribing = $state(false);
|
let isTranscribing = $state(false);
|
||||||
|
let transcriptionCancelled = $state(false);
|
||||||
let transcriptionProgress = $state(0);
|
let transcriptionProgress = $state(0);
|
||||||
let transcriptionStage = $state('');
|
let transcriptionStage = $state('');
|
||||||
let transcriptionMessage = $state('');
|
let transcriptionMessage = $state('');
|
||||||
let extractingAudio = $state(false);
|
let extractingAudio = $state(false);
|
||||||
|
|
||||||
|
function handleCancelProcessing() {
|
||||||
|
transcriptionCancelled = true;
|
||||||
|
isTranscribing = false;
|
||||||
|
transcriptionProgress = 0;
|
||||||
|
transcriptionStage = '';
|
||||||
|
transcriptionMessage = '';
|
||||||
|
// Clear any partial results
|
||||||
|
segments.set([]);
|
||||||
|
speakers.set([]);
|
||||||
|
}
|
||||||
|
|
||||||
// Speaker color palette for auto-assignment
|
// Speaker color palette for auto-assignment
|
||||||
const speakerColors = ['#e94560', '#4ecdc4', '#ffe66d', '#a8e6cf', '#ff8b94', '#c7ceea', '#ffd93d', '#6bcb77'];
|
const speakerColors = ['#e94560', '#4ecdc4', '#ffe66d', '#a8e6cf', '#ff8b94', '#c7ceea', '#ffd93d', '#6bcb77'];
|
||||||
|
|
||||||
@@ -310,6 +322,7 @@
|
|||||||
|
|
||||||
// Start pipeline (transcription + diarization)
|
// Start pipeline (transcription + diarization)
|
||||||
isTranscribing = true;
|
isTranscribing = true;
|
||||||
|
transcriptionCancelled = false;
|
||||||
transcriptionProgress = 0;
|
transcriptionProgress = 0;
|
||||||
transcriptionStage = 'Starting...';
|
transcriptionStage = 'Starting...';
|
||||||
transcriptionMessage = 'Initializing pipeline...';
|
transcriptionMessage = 'Initializing pipeline...';
|
||||||
@@ -420,6 +433,9 @@
|
|||||||
numSpeakers: $settings.num_speakers && $settings.num_speakers > 0 ? $settings.num_speakers : undefined,
|
numSpeakers: $settings.num_speakers && $settings.num_speakers > 0 ? $settings.num_speakers : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If cancelled while processing, discard results
|
||||||
|
if (transcriptionCancelled) return;
|
||||||
|
|
||||||
// Create speaker entries from pipeline result
|
// Create speaker entries from pipeline result
|
||||||
const newSpeakers: Speaker[] = (result.speakers || []).map((label, idx) => ({
|
const newSpeakers: Speaker[] = (result.speakers || []).map((label, idx) => ({
|
||||||
id: `speaker-${idx}`,
|
id: `speaker-${idx}`,
|
||||||
@@ -607,6 +623,7 @@
|
|||||||
percent={transcriptionProgress}
|
percent={transcriptionProgress}
|
||||||
stage={transcriptionStage}
|
stage={transcriptionStage}
|
||||||
message={transcriptionMessage}
|
message={transcriptionMessage}
|
||||||
|
onCancel={handleCancelProcessing}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if extractingAudio}
|
{#if extractingAudio}
|
||||||
|
|||||||
Reference in New Issue
Block a user