Add Save Project As menu action and force prompt behavior
This commit is contained in:
Vendored
+1
@@ -43,6 +43,7 @@ interface Window {
|
||||
loadProjectFile: () => Promise<{ success: boolean; path?: string; project?: unknown; message?: string; cancelled?: boolean; error?: string }>
|
||||
onMenuLoadProject: (callback: () => void) => () => void
|
||||
onMenuSaveProject: (callback: () => void) => () => void
|
||||
onMenuSaveProjectAs: (callback: () => void) => () => void
|
||||
getPlatform: () => Promise<string>
|
||||
hudOverlayHide: () => void;
|
||||
hudOverlayClose: () => void;
|
||||
|
||||
+6
-1
@@ -57,7 +57,7 @@ function isEditorWindow(window: BrowserWindow) {
|
||||
return window.webContents.getURL().includes('windowType=editor')
|
||||
}
|
||||
|
||||
function sendEditorMenuAction(channel: 'menu-load-project' | 'menu-save-project') {
|
||||
function sendEditorMenuAction(channel: 'menu-load-project' | 'menu-save-project' | 'menu-save-project-as') {
|
||||
let targetWindow = BrowserWindow.getFocusedWindow() ?? mainWindow
|
||||
|
||||
if (!targetWindow || targetWindow.isDestroyed() || !isEditorWindow(targetWindow)) {
|
||||
@@ -102,6 +102,11 @@ function setupApplicationMenu() {
|
||||
accelerator: 'CmdOrCtrl+S',
|
||||
click: () => sendEditorMenuAction('menu-save-project'),
|
||||
},
|
||||
{
|
||||
label: 'Save Project As…',
|
||||
accelerator: 'CmdOrCtrl+Shift+S',
|
||||
click: () => sendEditorMenuAction('menu-save-project-as'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -76,6 +76,11 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
ipcRenderer.on('menu-save-project', listener)
|
||||
return () => ipcRenderer.removeListener('menu-save-project', listener)
|
||||
},
|
||||
onMenuSaveProjectAs: (callback: () => void) => {
|
||||
const listener = () => callback()
|
||||
ipcRenderer.on('menu-save-project-as', listener)
|
||||
return () => ipcRenderer.removeListener('menu-save-project-as', listener)
|
||||
},
|
||||
getPlatform: () => {
|
||||
return ipcRenderer.invoke('get-platform')
|
||||
},
|
||||
|
||||
@@ -303,7 +303,7 @@ export default function VideoEditor() {
|
||||
loadVideo();
|
||||
}, []);
|
||||
|
||||
const handleSaveProject = useCallback(async () => {
|
||||
const saveProject = useCallback(async (forceSaveAs: boolean) => {
|
||||
if (!videoPath) {
|
||||
toast.error('No video loaded');
|
||||
return;
|
||||
@@ -339,7 +339,11 @@ export default function VideoEditor() {
|
||||
};
|
||||
|
||||
const fileNameBase = sourcePath.split(/[\\/]/).pop()?.replace(/\.[^.]+$/, '') || `project-${Date.now()}`;
|
||||
const result = await window.electronAPI.saveProjectFile(projectData, fileNameBase, currentProjectPath ?? undefined);
|
||||
const result = await window.electronAPI.saveProjectFile(
|
||||
projectData,
|
||||
fileNameBase,
|
||||
forceSaveAs ? undefined : currentProjectPath ?? undefined,
|
||||
);
|
||||
|
||||
if (result.cancelled) {
|
||||
toast.info('Project save cancelled');
|
||||
@@ -378,6 +382,14 @@ export default function VideoEditor() {
|
||||
gifSizePreset,
|
||||
]);
|
||||
|
||||
const handleSaveProject = useCallback(async () => {
|
||||
await saveProject(false);
|
||||
}, [saveProject]);
|
||||
|
||||
const handleSaveProjectAs = useCallback(async () => {
|
||||
await saveProject(true);
|
||||
}, [saveProject]);
|
||||
|
||||
const handleLoadProject = useCallback(async () => {
|
||||
const result = await window.electronAPI.loadProjectFile();
|
||||
|
||||
@@ -455,12 +467,14 @@ export default function VideoEditor() {
|
||||
useEffect(() => {
|
||||
const removeLoadListener = window.electronAPI.onMenuLoadProject(handleLoadProject);
|
||||
const removeSaveListener = window.electronAPI.onMenuSaveProject(handleSaveProject);
|
||||
const removeSaveAsListener = window.electronAPI.onMenuSaveProjectAs(handleSaveProjectAs);
|
||||
|
||||
return () => {
|
||||
removeLoadListener?.();
|
||||
removeSaveListener?.();
|
||||
removeSaveAsListener?.();
|
||||
};
|
||||
}, [handleLoadProject, handleSaveProject]);
|
||||
}, [handleLoadProject, handleSaveProject, handleSaveProjectAs]);
|
||||
|
||||
// Initialize default wallpaper with resolved asset path
|
||||
useEffect(() => {
|
||||
|
||||
Vendored
+1
@@ -59,5 +59,6 @@ interface Window {
|
||||
}>
|
||||
onMenuLoadProject: (callback: () => void) => () => void
|
||||
onMenuSaveProject: (callback: () => void) => () => void
|
||||
onMenuSaveProjectAs: (callback: () => void) => () => void
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user