diff --git a/src/extension.ts b/src/extension.ts index f0e84a331..a8f7f3514 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -821,12 +821,16 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand("codex-editor-extension.generateTranscriptions", async () => { const countInput = await vscode.window.showInputBox({ - prompt: "How many cells to transcribe?", - placeHolder: "e.g., 5", - validateInput: (val) => (val && !isNaN(Number(val)) && Number(val) >= 1 ? undefined : "Enter a positive number"), + prompt: "How many cells to transcribe? (0 or blank = all untranscribed cells)", + placeHolder: "0 for all, or a specific number", + value: "0", + validateInput: (val) => { + if (!val || val.trim() === "") return undefined; + return !isNaN(Number(val)) && Number(val) >= 0 ? undefined : "Enter 0 for all, or a positive number"; + }, }); - if (!countInput) return; - const count = Math.max(1, Math.floor(Number(countInput))); + if (countInput === undefined) return; // user cancelled + const count = Math.max(0, Math.floor(Number(countInput || 0))); const provider = GlobalProvider.getInstance().getProvider("codex-cell-editor") as CodexCellEditorProvider | undefined; if (!provider) { @@ -835,7 +839,10 @@ export async function activate(context: vscode.ExtensionContext) { } provider.postMessageToWebviews({ type: "startBatchTranscription", content: { count } } as any); - vscode.window.showInformationMessage(`Starting transcription for up to ${count} cells...`); + const label = count > 0 ? `up to ${count}` : "all untranscribed"; + vscode.window.showInformationMessage( + `Starting transcription for ${label} cells... First request may take ~45s to warm up.` + ); }) ); diff --git a/src/providers/NewSourceUploader/NewSourceUploaderProvider.ts b/src/providers/NewSourceUploader/NewSourceUploaderProvider.ts index ec8a5f52c..2b76b4464 100644 --- a/src/providers/NewSourceUploader/NewSourceUploaderProvider.ts +++ b/src/providers/NewSourceUploader/NewSourceUploaderProvider.ts @@ -1653,7 +1653,13 @@ export class NewSourceUploaderProvider implements vscode.CustomTextEditorProvide processedCells.set(paratextId, paratextCell); paratextCount++; } else if (alignedCell.notebookCell) { - const targetId = alignedCell.importedContent.id; + // Use the matched target cell's ID (from the aligner) to preserve + // source-to-target linkage. The imported content may have a different + // UUID generated during re-parsing, but the existing target cell's ID + // is what matches the source notebook. + const targetId = alignedCell.notebookCell.metadata?.id + || alignedCell.notebookCell.id + || alignedCell.importedContent.id; const existingCell = existingCellsMap.get(targetId); const existingValue = existingCell?.value ?? alignedCell.notebookCell.value ?? ""; @@ -1703,7 +1709,9 @@ export class NewSourceUploaderProvider implements vscode.CustomTextEditorProvide newCells.push(paratextCell); } } else if (alignedCell.notebookCell) { - const targetId = alignedCell.importedContent.id; + const targetId = alignedCell.notebookCell.metadata?.id + || alignedCell.notebookCell.id + || alignedCell.importedContent.id; const processedCell = processedCells.get(targetId); if (processedCell) { diff --git a/src/providers/codexCellEditorProvider/codexCellEditorMessagehandling.ts b/src/providers/codexCellEditorProvider/codexCellEditorMessagehandling.ts index 6bd5465aa..944372811 100644 --- a/src/providers/codexCellEditorProvider/codexCellEditorMessagehandling.ts +++ b/src/providers/codexCellEditorProvider/codexCellEditorMessagehandling.ts @@ -394,10 +394,11 @@ const messageHandlers: Record Promise("asrLanguage", "eng"); + debug(`[getAsrConfig] Sending config: endpoint=${endpoint}, hasToken=${!!authToken}, language=${language}`); safePostMessageToPanel(webviewPanel, { type: "asrConfig", - content: { endpoint, authToken } + content: { endpoint, authToken, language } }); } catch (error) { console.error("Error sending ASR config:", error); @@ -417,6 +418,19 @@ const messageHandlers: Record Promise { + const count = (event as any).content?.count ?? 0; + // Forward to the webview as a startBatchTranscription message + safePostMessageToPanel(webviewPanel, { + type: "startBatchTranscription", + content: { count }, + } as any); + const label = count > 0 ? `up to ${count}` : "all untranscribed"; + vscode.window.showInformationMessage( + `Starting transcription for ${label} cells... First request may take ~45s to warm up.` + ); + }, + updateCellAfterTranscription: async ({ event, document, webviewPanel, provider }) => { const typedEvent = event as Extract; const { cellId, transcribedText, language } = typedEvent.content; diff --git a/webviews/codex-webviews/src/CodexCellEditor/AudioWaveformWithTranscription.tsx b/webviews/codex-webviews/src/CodexCellEditor/AudioWaveformWithTranscription.tsx index e658762c4..47978831f 100644 --- a/webviews/codex-webviews/src/CodexCellEditor/AudioWaveformWithTranscription.tsx +++ b/webviews/codex-webviews/src/CodexCellEditor/AudioWaveformWithTranscription.tsx @@ -33,6 +33,7 @@ interface AudioWaveformWithTranscriptionProps { isTranscribing: boolean; transcriptionProgress: number; onTranscribe: () => void; + onTranscribeAll?: () => void; onInsertTranscription: () => void; disabled?: boolean; onRequestRemove?: () => void; @@ -50,6 +51,7 @@ const AudioWaveformWithTranscription: React.FC {!transcription && !isTranscribing && ( - + <> + + {onTranscribeAll && ( + + )} + )}