150 lines
4.1 KiB
JavaScript
150 lines
4.1 KiB
JavaScript
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
|
|
import { fileURLToPath } from 'url';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const SETTINGS_FILE = path.join(app.getPath('userData'), 'settings.json');
|
|
|
|
let mainWindow;
|
|
|
|
function loadSettings() {
|
|
try {
|
|
if (fs.existsSync(SETTINGS_FILE)) {
|
|
return JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to load settings:', err);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
function saveSettings(settings) {
|
|
try {
|
|
const current = loadSettings();
|
|
const updated = { ...current, ...settings };
|
|
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(updated, null, 2));
|
|
} catch (err) {
|
|
console.error('Failed to save settings:', err);
|
|
}
|
|
}
|
|
|
|
function createWindow() {
|
|
const settings = loadSettings();
|
|
const windowBounds = settings.windowBounds || { width: 1200, height: 800 };
|
|
|
|
mainWindow = new BrowserWindow({
|
|
x: windowBounds.x,
|
|
y: windowBounds.y,
|
|
width: windowBounds.width,
|
|
height: windowBounds.height,
|
|
minWidth: 1000,
|
|
minHeight: 600,
|
|
webPreferences: {
|
|
preload: path.join(__dirname, 'preload.js'),
|
|
contextIsolation: true,
|
|
nodeIntegration: false,
|
|
},
|
|
});
|
|
|
|
const isDev = process.env.NODE_ENV === 'development';
|
|
|
|
if (isDev) {
|
|
mainWindow.loadURL('http://localhost:5173');
|
|
mainWindow.webContents.openDevTools();
|
|
} else {
|
|
// In production, use app.getAppPath() to correctly resolve the ASAR root
|
|
const appPath = app.getAppPath();
|
|
mainWindow.loadFile(path.join(appPath, 'dist/index.html'));
|
|
}
|
|
|
|
// Persist window bounds on change
|
|
const saveBounds = () => {
|
|
const bounds = mainWindow.getBounds();
|
|
saveSettings({ windowBounds: bounds });
|
|
};
|
|
mainWindow.on('resize', saveBounds);
|
|
mainWindow.on('move', saveBounds);
|
|
}
|
|
|
|
app.whenReady().then(() => {
|
|
createWindow();
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
// Settings Handlers
|
|
ipcMain.handle('get-settings', async () => {
|
|
return loadSettings();
|
|
});
|
|
|
|
ipcMain.handle('update-settings', async (event, settings) => {
|
|
saveSettings(settings);
|
|
return { success: true };
|
|
});
|
|
|
|
// IPC Handler for Image Export
|
|
// IPC Handler for Image/PDF/HTML Export
|
|
ipcMain.handle('save-image', async (event, dataUrl, format) => {
|
|
const isPdf = format === 'pdf';
|
|
const isHtml = format === 'html';
|
|
|
|
let filters = [{ name: 'Images', extensions: [format] }];
|
|
if (isPdf) filters = [{ name: 'PDF Documents', extensions: ['pdf'] }];
|
|
if (isHtml) filters = [{ name: 'HTML Files', extensions: ['html'] }];
|
|
|
|
const { canceled, filePath } = await dialog.showSaveDialog(mainWindow, {
|
|
title: isPdf ? 'Save PDF' : (isHtml ? 'Save HTML' : 'Save Image'),
|
|
defaultPath: `export.${format}`,
|
|
filters: filters,
|
|
});
|
|
|
|
if (canceled || !filePath) {
|
|
return { success: false, message: 'Cancelled' };
|
|
}
|
|
|
|
// Remove header (e.g., "data:image/png;base64," or "data:application/pdf;base64," or "data:text/html;base64,")
|
|
const base64Data = dataUrl.replace(/^data:(image\/\w+|application\/pdf|text\/html);base64,/, '');
|
|
|
|
try {
|
|
fs.writeFileSync(filePath, base64Data, 'base64');
|
|
return { success: true, filePath };
|
|
} catch (error) {
|
|
console.error('Failed to save file:', error);
|
|
return { success: false, message: error.message };
|
|
}
|
|
});
|
|
|
|
// IPC Handler for HTML Import
|
|
ipcMain.handle('open-file', async () => {
|
|
const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {
|
|
title: 'Open HTML File',
|
|
filters: [{ name: 'HTML Files', extensions: ['html'] }],
|
|
properties: ['openFile']
|
|
});
|
|
|
|
if (canceled || filePaths.length === 0) {
|
|
return { success: false, message: 'Cancelled' };
|
|
}
|
|
|
|
try {
|
|
const content = fs.readFileSync(filePaths[0], 'utf-8');
|
|
return { success: true, content, filePath: filePaths[0] };
|
|
} catch (error) {
|
|
console.error('Failed to open file:', error);
|
|
return { success: false, message: error.message };
|
|
}
|
|
});
|