From 27c31d6e0cb95b5440c7bab297fc0aa0228a408e Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 29 Sep 2025 19:36:05 +0800 Subject: [PATCH] feat(file): add showInFolder IPC channel to reveal files in explorer Implement functionality to show files/folders in system explorer through IPC. Includes channel definition, preload API, main handler, and error handling for non-existent paths. --- packages/shared/IpcChannel.ts | 1 + src/main/ipc.ts | 1 + src/main/services/FileStorage.ts | 13 +++++++++++++ src/preload/index.ts | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/shared/IpcChannel.ts b/packages/shared/IpcChannel.ts index d066c6d3c9..337d8181b5 100644 --- a/packages/shared/IpcChannel.ts +++ b/packages/shared/IpcChannel.ts @@ -187,6 +187,7 @@ export enum IpcChannel { File_ValidateNotesDirectory = 'file:validateNotesDirectory', File_StartWatcher = 'file:startWatcher', File_StopWatcher = 'file:stopWatcher', + File_ShowInFolder = 'file:showInFolder', // file service FileService_Upload = 'file-service:upload', diff --git a/src/main/ipc.ts b/src/main/ipc.ts index dacc296112..49a0b76444 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -526,6 +526,7 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { ipcMain.handle(IpcChannel.File_ValidateNotesDirectory, fileManager.validateNotesDirectory.bind(fileManager)) ipcMain.handle(IpcChannel.File_StartWatcher, fileManager.startFileWatcher.bind(fileManager)) ipcMain.handle(IpcChannel.File_StopWatcher, fileManager.stopFileWatcher.bind(fileManager)) + ipcMain.handle(IpcChannel.File_ShowInFolder, fileManager.showInFolder.bind(fileManager)) // file service ipcMain.handle(IpcChannel.FileService_Upload, async (_, provider: Provider, file: FileMetadata) => { diff --git a/src/main/services/FileStorage.ts b/src/main/services/FileStorage.ts index 985f6dfef9..58a6519fea 100644 --- a/src/main/services/FileStorage.ts +++ b/src/main/services/FileStorage.ts @@ -1229,6 +1229,19 @@ class FileStorage { return false } } + + public showInFolder = async (_: Electron.IpcMainInvokeEvent, path: string): Promise => { + if (!fs.existsSync(path)) { + const msg = `File or folder does not exist: ${path}` + logger.error(msg) + throw new Error(msg) + } + try { + shell.showItemInFolder(path) + } catch (error) { + logger.error('Failed to show item in folder:', error as Error) + } + } } export const fileStorage = new FileStorage() diff --git a/src/preload/index.ts b/src/preload/index.ts index 10b0c00ab3..d497015506 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -199,7 +199,8 @@ const api = { } ipcRenderer.on('file-change', listener) return () => ipcRenderer.off('file-change', listener) - } + }, + showInFolder: (path: string): Promise => ipcRenderer.invoke(IpcChannel.File_ShowInFolder, path) }, fs: { read: (pathOrUrl: string, encoding?: BufferEncoding) => ipcRenderer.invoke(IpcChannel.Fs_Read, pathOrUrl, encoding),