Save project: pick folder instead of file
All checks were successful
Release / Bump version and tag (push) Successful in 3s
Release / Build App (macOS) (push) Successful in 1m16s
Release / Build App (Windows) (push) Successful in 3m7s
Release / Build App (Linux) (push) Successful in 3m22s

Changed save dialog from file picker (.vtn) to folder picker. The
project name is derived from the folder name. Files are created
inside the chosen folder:
  Folder/
    Folder.vtn
    audio.wav

Also: save-in-place for already-saved projects (Ctrl+S just saves,
no dialog). Extracted buildProjectData() helper for reuse.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-03-23 09:51:12 -07:00
parent 543decd769
commit 168a43e0e1

View File

@@ -140,23 +140,8 @@
// 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'];
async function saveProject() { function buildProjectData(projectName: string) {
const defaultName = currentProjectName || 'Untitled'; return {
const outputPath = await save({
defaultPath: `${defaultName}.vtn`,
filters: [{ name: 'Voice to Notes Project', extensions: ['vtn'] }],
});
if (!outputPath) return;
// Derive folder path and file name from the chosen .vtn path
const vtnFileName = outputPath.split(/[\\/]/).pop() || `${defaultName}.vtn`;
const projectName = vtnFileName.replace(/\.vtn$/i, '');
const parentDir = outputPath.replace(/[\\/][^\\/]+$/, '');
const folderPath = `${parentDir}/${projectName}`;
const vtnInsideFolder = `${folderPath}/${vtnFileName}`;
const wavInsideFolder = `${folderPath}/audio.wav`;
const projectData = {
version: 2, version: 2,
name: projectName, name: projectName,
source_file: audioFilePath, source_file: audioFilePath,
@@ -184,10 +169,44 @@
color: s.color || '#e94560', color: s.color || '#e94560',
})), })),
}; };
}
async function saveProject() {
const defaultName = currentProjectName || 'Untitled';
// If already saved, save in place
if (currentProjectPath) {
const folderPath = currentProjectPath.replace(/[\\/][^\\/]+$/, '');
const projectName = currentProjectPath.split(/[\\/]/).pop()?.replace(/\.vtn$/i, '') || defaultName;
const wavInsideFolder = `${folderPath}/audio.wav`;
const projectData = buildProjectData(projectName);
try {
if (audioWavPath && audioWavPath !== wavInsideFolder) {
await invoke('copy_file', { src: audioWavPath, dst: wavInsideFolder });
}
await invoke('save_project_file', { path: currentProjectPath, project: projectData });
} catch (err) {
alert(`Failed to save: ${err}`);
}
return;
}
// Pick a folder for the new project
const folderPath = await open({
directory: true,
title: 'Choose a folder to save the project',
});
if (!folderPath) return;
// Use the folder name as the project name
const projectName = (folderPath as string).split(/[\\/]/).pop() || defaultName;
const vtnInsideFolder = `${folderPath}/${projectName}.vtn`;
const wavInsideFolder = `${folderPath}/audio.wav`;
const projectData = buildProjectData(projectName);
try { try {
// Create the project folder
await invoke('create_dir', { path: folderPath });
// Copy the extracted WAV into the project folder // Copy the extracted WAV into the project folder
if (audioWavPath) { if (audioWavPath) {