feat(export): prefer native save dialog over browser blob fallback
DictationPage + FilesPage handleExport() now use Tauri save() + write_text_file_cmd when in the desktop runtime; browser blob path remains as fallback when hasTauriRuntime() is false. saveMarkdown.ts surfaces dialog errors via toasts. Adds txt to the extension map. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,14 +33,24 @@ export function suggestedFilename(item: TranscriptEntry): string {
|
||||
export async function saveTranscriptAsMarkdown(
|
||||
item: TranscriptEntry,
|
||||
): Promise<string | null> {
|
||||
if (!hasTauriRuntime()) return null;
|
||||
if (!hasTauriRuntime()) {
|
||||
toasts.error("Export unavailable", "Native save dialogs are only available in the desktop app.");
|
||||
return null;
|
||||
}
|
||||
const md = buildMarkdown(item);
|
||||
const defaultPath = suggestedFilename(item);
|
||||
const path = await save({
|
||||
title: "Save transcript as Markdown",
|
||||
defaultPath,
|
||||
filters: [{ name: "Markdown", extensions: ["md"] }],
|
||||
});
|
||||
let path: string | null = null;
|
||||
try {
|
||||
path = await save({
|
||||
title: "Save transcript as Markdown",
|
||||
defaultPath,
|
||||
filters: [{ name: "Markdown", extensions: ["md"] }],
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("saveTranscriptAsMarkdown dialog failed", err);
|
||||
toasts.error("Couldn't open save dialog", String(err));
|
||||
return null;
|
||||
}
|
||||
if (!path) return null;
|
||||
try {
|
||||
await invoke("write_text_file_cmd", { path, contents: md });
|
||||
@@ -64,13 +74,24 @@ export async function saveTranscriptAsMarkdown(
|
||||
export async function exportTranscriptsToDir(
|
||||
items: TranscriptEntry[],
|
||||
): Promise<number> {
|
||||
if (!hasTauriRuntime() || items.length === 0) return 0;
|
||||
if (items.length === 0) return 0;
|
||||
if (!hasTauriRuntime()) {
|
||||
toasts.error("Export unavailable", "Native folder dialogs are only available in the desktop app.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const dir = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
title: "Choose export folder",
|
||||
});
|
||||
let dir: string | string[] | null = null;
|
||||
try {
|
||||
dir = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
title: "Choose export folder",
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("exportTranscriptsToDir dialog failed", err);
|
||||
toasts.error("Couldn't open export folder dialog", String(err));
|
||||
return 0;
|
||||
}
|
||||
if (!dir || typeof dir !== "string") return 0;
|
||||
|
||||
const used = new Set<string>();
|
||||
|
||||
Reference in New Issue
Block a user