diff --git a/dist-electron/main.js b/dist-electron/main.js index fce1288..7343b29 100644 --- a/dist-electron/main.js +++ b/dist-electron/main.js @@ -1,4 +1,4 @@ -import { BrowserWindow, screen, ipcMain, desktopCapturer, shell, app, nativeImage, Tray, Menu } from "electron"; +import { BrowserWindow, screen, ipcMain, desktopCapturer, shell, app, dialog, nativeImage, Tray, Menu } from "electron"; import { fileURLToPath } from "node:url"; import path from "node:path"; import fs from "node:fs/promises"; @@ -202,12 +202,25 @@ function registerIpcHandlers(createEditorWindow2, createSourceSelectorWindow2, g }); ipcMain.handle("save-exported-video", async (_, videoData, fileName) => { try { - const downloadsPath = app.getPath("downloads"); - const videoPath = path.join(downloadsPath, fileName); - await fs.writeFile(videoPath, Buffer.from(videoData)); + const result = await dialog.showSaveDialog({ + title: "Save Exported Video", + defaultPath: path.join(app.getPath("downloads"), fileName), + filters: [ + { name: "MP4 Video", extensions: ["mp4"] } + ], + properties: ["createDirectory", "showOverwriteConfirmation"] + }); + if (result.canceled || !result.filePath) { + return { + success: false, + cancelled: true, + message: "Export cancelled" + }; + } + await fs.writeFile(result.filePath, Buffer.from(videoData)); return { success: true, - path: videoPath, + path: result.filePath, message: "Video exported successfully" }; } catch (error) { diff --git a/electron/electron-env.d.ts b/electron/electron-env.d.ts index c2d40ea..2b817e6 100644 --- a/electron/electron-env.d.ts +++ b/electron/electron-env.d.ts @@ -35,7 +35,7 @@ interface Window { setRecordingState: (recording: boolean) => Promise onStopRecordingFromTray: (callback: () => void) => () => void openExternalUrl: (url: string) => Promise<{ success: boolean; error?: string }> - saveExportedVideo: (videoData: ArrayBuffer, fileName: string) => Promise<{ success: boolean; path?: string; message?: string }> + saveExportedVideo: (videoData: ArrayBuffer, fileName: string) => Promise<{ success: boolean; path?: string; message?: string; cancelled?: boolean }> } } diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 5f92ed3..2a4267c 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -1,4 +1,4 @@ -import { ipcMain, desktopCapturer, BrowserWindow, shell, app } from 'electron' +import { ipcMain, desktopCapturer, BrowserWindow, shell, app, dialog } from 'electron' import fs from 'node:fs/promises' import path from 'node:path' @@ -128,22 +128,40 @@ export function registerIpcHandlers( ipcMain.handle('save-exported-video', async (_, videoData: ArrayBuffer, fileName: string) => { try { - const downloadsPath = app.getPath('downloads') - const videoPath = path.join(downloadsPath, fileName) - await fs.writeFile(videoPath, Buffer.from(videoData)) + // Show save dialog to let user choose location and filename + const result = await dialog.showSaveDialog({ + title: 'Save Exported Video', + defaultPath: path.join(app.getPath('downloads'), fileName), + filters: [ + { name: 'MP4 Video', extensions: ['mp4'] } + ], + properties: ['createDirectory', 'showOverwriteConfirmation'] + }); + + // User cancelled the dialog + if (result.canceled || !result.filePath) { + return { + success: false, + cancelled: true, + message: 'Export cancelled' + }; + } + + // Write the file to the chosen location + await fs.writeFile(result.filePath, Buffer.from(videoData)); return { success: true, - path: videoPath, + path: result.filePath, message: 'Video exported successfully' - } + }; } catch (error) { - console.error('Failed to save exported video:', error) + console.error('Failed to save exported video:', error); return { success: false, message: 'Failed to save exported video', error: String(error) - } + }; } }) } diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index f49315a..22b3b77 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -248,8 +248,10 @@ export default function VideoEditor() { const saveResult = await window.electronAPI.saveExportedVideo(arrayBuffer, fileName); - if (saveResult.success) { - toast.success('Video exported successfully!'); + if (saveResult.cancelled) { + toast.info('Export cancelled'); + } else if (saveResult.success) { + toast.success(`Video exported successfully to ${saveResult.path}`); } else { setExportError(saveResult.message || 'Failed to save video'); toast.error(saveResult.message || 'Failed to save video'); diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 06d51c1..f0e2546 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -724,7 +724,7 @@ const VideoPlayback = forwardRef(({ className="absolute inset-0 bg-cover bg-center" style={{ ...backgroundStyle, - filter: showBlur ? 'blur(3px)' : 'none', + filter: showBlur ? 'blur(2px)' : 'none', }} />
} } \ No newline at end of file