Save project: pick folder instead of file
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:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user