mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 17:26:23 +02:00
feat: add unified file and folder browsing functionality with IPC channel integration
This commit is contained in:
parent
f0a7c7134a
commit
b46c5532b3
8 changed files with 335 additions and 120 deletions
|
|
@ -17,4 +17,6 @@ export const IPC_CHANNELS = {
|
|||
FOLDER_SYNC_PAUSE: 'folder-sync:pause',
|
||||
FOLDER_SYNC_RESUME: 'folder-sync:resume',
|
||||
FOLDER_SYNC_RENDERER_READY: 'folder-sync:renderer-ready',
|
||||
BROWSE_FILE_OR_FOLDER: 'browse:file-or-folder',
|
||||
READ_LOCAL_FILES: 'browse:read-local-files',
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import {
|
|||
pauseWatcher,
|
||||
resumeWatcher,
|
||||
markRendererReady,
|
||||
browseFileOrFolder,
|
||||
readLocalFiles,
|
||||
} from '../modules/folder-watcher';
|
||||
|
||||
export function registerIpcHandlers(): void {
|
||||
|
|
@ -49,4 +51,10 @@ export function registerIpcHandlers(): void {
|
|||
ipcMain.handle(IPC_CHANNELS.FOLDER_SYNC_RENDERER_READY, () => {
|
||||
markRendererReady();
|
||||
});
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.BROWSE_FILE_OR_FOLDER, () => browseFileOrFolder());
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.READ_LOCAL_FILES, (_event, paths: string[]) =>
|
||||
readLocalFiles(paths)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,3 +391,71 @@ export async function unregisterFolderWatcher(): Promise<void> {
|
|||
}
|
||||
watchers.clear();
|
||||
}
|
||||
|
||||
export interface BrowseResult {
|
||||
type: 'files' | 'folder';
|
||||
paths: string[];
|
||||
}
|
||||
|
||||
export async function browseFileOrFolder(): Promise<BrowseResult | null> {
|
||||
const result = await dialog.showOpenDialog({
|
||||
properties: ['openFile', 'openDirectory', 'multiSelections'],
|
||||
title: 'Select files or a folder',
|
||||
});
|
||||
if (result.canceled || result.filePaths.length === 0) return null;
|
||||
|
||||
const stat = fs.statSync(result.filePaths[0]);
|
||||
if (stat.isDirectory()) {
|
||||
return { type: 'folder', paths: [result.filePaths[0]] };
|
||||
}
|
||||
return { type: 'files', paths: result.filePaths };
|
||||
}
|
||||
|
||||
const MIME_MAP: Record<string, string> = {
|
||||
'.pdf': 'application/pdf',
|
||||
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'.html': 'text/html', '.htm': 'text/html',
|
||||
'.csv': 'text/csv',
|
||||
'.txt': 'text/plain',
|
||||
'.md': 'text/markdown', '.markdown': 'text/markdown',
|
||||
'.mp3': 'audio/mpeg', '.mpeg': 'audio/mpeg', '.mpga': 'audio/mpeg',
|
||||
'.mp4': 'audio/mp4', '.m4a': 'audio/mp4',
|
||||
'.wav': 'audio/wav',
|
||||
'.webm': 'audio/webm',
|
||||
'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.bmp': 'image/bmp',
|
||||
'.webp': 'image/webp',
|
||||
'.tiff': 'image/tiff',
|
||||
'.doc': 'application/msword',
|
||||
'.rtf': 'application/rtf',
|
||||
'.xml': 'application/xml',
|
||||
'.epub': 'application/epub+zip',
|
||||
'.xls': 'application/vnd.ms-excel',
|
||||
'.ppt': 'application/vnd.ms-powerpoint',
|
||||
'.eml': 'message/rfc822',
|
||||
'.odt': 'application/vnd.oasis.opendocument.text',
|
||||
'.msg': 'application/vnd.ms-outlook',
|
||||
};
|
||||
|
||||
export interface LocalFileData {
|
||||
name: string;
|
||||
data: ArrayBuffer;
|
||||
mimeType: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export function readLocalFiles(filePaths: string[]): LocalFileData[] {
|
||||
return filePaths.map((p) => {
|
||||
const buf = fs.readFileSync(p);
|
||||
const ext = path.extname(p).toLowerCase();
|
||||
return {
|
||||
name: path.basename(p),
|
||||
data: buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength),
|
||||
mimeType: MIME_MAP[ext] || 'application/octet-stream',
|
||||
size: buf.byteLength,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,4 +45,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||
pauseWatcher: () => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_PAUSE),
|
||||
resumeWatcher: () => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_RESUME),
|
||||
signalRendererReady: () => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_RENDERER_READY),
|
||||
|
||||
// Unified browse (files + folders)
|
||||
browseFileOrFolder: () => ipcRenderer.invoke(IPC_CHANNELS.BROWSE_FILE_OR_FOLDER),
|
||||
readLocalFiles: (paths: string[]) => ipcRenderer.invoke(IPC_CHANNELS.READ_LOCAL_FILES, paths),
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue