Skip to content

Commit 17b4795

Browse files
committed
chore: electron support initial
1 parent 4f0f47a commit 17b4795

2 files changed

Lines changed: 77 additions & 2 deletions

File tree

src-electron/main.js

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
const { app, BrowserWindow, ipcMain } = require('electron');
1+
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
22
const { spawn } = require('child_process');
33
const path = require('path');
44
const readline = require('readline');
5+
const fs = require('fs');
6+
const fsp = require('fs/promises');
7+
const os = require('os');
58

69
let mainWindow;
710
let nodeProcess;
@@ -150,6 +153,62 @@ ipcMain.on('console-log', (event, message) => {
150153
console.log('Renderer:', message);
151154
});
152155

156+
// Directory APIs
157+
ipcMain.handle('get-documents-dir', () => {
158+
return path.join(os.homedir(), 'Documents');
159+
});
160+
161+
ipcMain.handle('get-app-data-dir', () => {
162+
// Returns app-specific data directory similar to Tauri's appLocalDataDir
163+
// Linux: ~/.local/share/<app-name>/
164+
// macOS: ~/Library/Application Support/<app-name>/
165+
// Windows: %APPDATA%/<app-name>/
166+
return app.getPath('userData');
167+
});
168+
169+
// Dialogs
170+
ipcMain.handle('show-open-dialog', async (event, options) => {
171+
const result = await dialog.showOpenDialog(mainWindow, options);
172+
return result.filePaths;
173+
});
174+
175+
ipcMain.handle('show-save-dialog', async (event, options) => {
176+
const result = await dialog.showSaveDialog(mainWindow, options);
177+
return result.filePath;
178+
});
179+
180+
// FS operations
181+
ipcMain.handle('fs-readdir', async (event, dirPath) => {
182+
const entries = await fsp.readdir(dirPath, { withFileTypes: true });
183+
return entries.map(e => ({ name: e.name, isDirectory: e.isDirectory() }));
184+
});
185+
186+
ipcMain.handle('fs-stat', async (event, filePath) => {
187+
const stats = await fsp.stat(filePath);
188+
return {
189+
isFile: stats.isFile(),
190+
isDirectory: stats.isDirectory(),
191+
isSymbolicLink: stats.isSymbolicLink(),
192+
size: stats.size,
193+
mode: stats.mode,
194+
ctimeMs: stats.ctimeMs,
195+
atimeMs: stats.atimeMs,
196+
mtimeMs: stats.mtimeMs,
197+
nlink: stats.nlink,
198+
dev: stats.dev
199+
};
200+
});
201+
202+
ipcMain.handle('fs-mkdir', (event, dirPath, options) => fsp.mkdir(dirPath, options));
203+
ipcMain.handle('fs-unlink', (event, filePath) => fsp.unlink(filePath));
204+
ipcMain.handle('fs-rmdir', (event, dirPath, options) => fsp.rm(dirPath, options));
205+
ipcMain.handle('fs-rename', (event, oldPath, newPath) => fsp.rename(oldPath, newPath));
206+
ipcMain.handle('fs-read-file', async (event, filePath) => {
207+
const buffer = await fsp.readFile(filePath);
208+
return buffer; // Electron serializes Buffer automatically
209+
});
210+
ipcMain.handle('fs-write-file', (event, filePath, data) => fsp.writeFile(filePath, Buffer.from(data)));
211+
153212
function waitForTrue(fn, timeout) {
154213
return new Promise((resolve) => {
155214
const startTime = Date.now();

src-electron/preload.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,21 @@ contextBridge.exposeInMainWorld('electronAPI', {
1111
consoleLog: (message) => ipcRenderer.send('console-log', message),
1212

1313
// Flag to identify Electron environment
14-
isElectron: true
14+
isElectron: true,
15+
16+
// File system APIs
17+
getDocumentsDir: () => ipcRenderer.invoke('get-documents-dir'),
18+
getAppDataDir: () => ipcRenderer.invoke('get-app-data-dir'),
19+
showOpenDialog: (options) => ipcRenderer.invoke('show-open-dialog', options),
20+
showSaveDialog: (options) => ipcRenderer.invoke('show-save-dialog', options),
21+
22+
// FS operations (fallback when NodeTauriFS not available)
23+
fsReaddir: (path) => ipcRenderer.invoke('fs-readdir', path),
24+
fsStat: (path) => ipcRenderer.invoke('fs-stat', path),
25+
fsMkdir: (path, options) => ipcRenderer.invoke('fs-mkdir', path, options),
26+
fsUnlink: (path) => ipcRenderer.invoke('fs-unlink', path),
27+
fsRmdir: (path, options) => ipcRenderer.invoke('fs-rmdir', path, options),
28+
fsRename: (oldPath, newPath) => ipcRenderer.invoke('fs-rename', oldPath, newPath),
29+
fsReadFile: (path) => ipcRenderer.invoke('fs-read-file', path),
30+
fsWriteFile: (path, data) => ipcRenderer.invoke('fs-write-file', path, data)
1531
});

0 commit comments

Comments
 (0)