| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- const { app, BrowserWindow, Menu, shell, dialog } = require('electron');
- const path = require('path');
- // Graceful auto-updater loading
- let autoUpdater = null;
- try {
- autoUpdater = require('electron-updater').autoUpdater;
- console.log('Auto-updater loaded successfully');
- } catch (error) {
- console.log('Auto-updater not available:', error.message);
- }
- // Keep a global reference of the window object
- let mainWindow;
- function createWindow() {
- // Create the browser window
- mainWindow = new BrowserWindow({
- width: 1200,
- height: 800,
- minWidth: 800,
- minHeight: 600,
- icon: path.join(__dirname, 'img/logo.png'),
- webPreferences: {
- nodeIntegration: false,
- contextIsolation: true,
- enableRemoteModule: false,
- webSecurity: true
- },
- show: false // Don't show until ready
- });
- // Load the home page
- mainWindow.loadFile(path.join(__dirname, 'home.html'));
- // Show window when ready to prevent visual flash
- mainWindow.once('ready-to-show', () => {
- mainWindow.show();
- });
- // Handle external links
- mainWindow.webContents.setWindowOpenHandler(({ url }) => {
- shell.openExternal(url);
- return { action: 'deny' };
- });
- // Emitted when the window is closed
- mainWindow.on('closed', () => {
- mainWindow = null;
- });
- // Create application menu
- createMenu();
- }
- function createMenu() {
- const template = [
- {
- label: 'File',
- submenu: [
- {
- label: 'New Note',
- accelerator: 'CmdOrCtrl+N',
- click: () => {
- mainWindow.loadFile(path.join(__dirname, 'index.html'));
- }
- },
- {
- label: 'Home',
- accelerator: 'CmdOrCtrl+H',
- click: () => {
- mainWindow.loadFile(path.join(__dirname, 'home.html'));
- }
- },
- { type: 'separator' },
- {
- label: 'Check for Updates',
- click: () => {
- if (autoUpdater) {
- autoUpdater.checkForUpdatesAndNotify();
- } else {
- dialog.showMessageBox(mainWindow, {
- type: 'info',
- title: 'Auto-updater Not Available',
- message: 'Automatic updates are not available in this build.',
- detail: 'Please check for updates manually at: https://github.com/lhamacorp/knotes/releases',
- buttons: ['OK']
- });
- }
- }
- },
- { type: 'separator' },
- {
- label: 'Quit',
- accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
- click: () => {
- app.quit();
- }
- }
- ]
- },
- {
- label: 'Edit',
- submenu: [
- { role: 'undo' },
- { role: 'redo' },
- { type: 'separator' },
- { role: 'cut' },
- { role: 'copy' },
- { role: 'paste' },
- { role: 'selectall' }
- ]
- },
- {
- label: 'View',
- submenu: [
- { role: 'reload' },
- { role: 'forceReload' },
- { role: 'toggleDevTools' },
- { type: 'separator' },
- { role: 'resetZoom' },
- { role: 'zoomIn' },
- { role: 'zoomOut' },
- { type: 'separator' },
- { role: 'togglefullscreen' }
- ]
- },
- {
- label: 'Window',
- submenu: [
- { role: 'minimize' },
- { role: 'close' }
- ]
- }
- ];
- // macOS specific menu adjustments
- if (process.platform === 'darwin') {
- template.unshift({
- label: app.getName(),
- submenu: [
- { role: 'about' },
- { type: 'separator' },
- { role: 'services' },
- { type: 'separator' },
- { role: 'hide' },
- { role: 'hideothers' },
- { role: 'unhide' },
- { type: 'separator' },
- { role: 'quit' }
- ]
- });
- // Window menu
- template[4].submenu = [
- { role: 'close' },
- { role: 'minimize' },
- { role: 'zoom' },
- { type: 'separator' },
- { role: 'front' }
- ];
- }
- const menu = Menu.buildFromTemplate(template);
- Menu.setApplicationMenu(menu);
- }
- // Auto-updater configuration
- function setupAutoUpdater() {
- // Skip if auto-updater is not available
- if (!autoUpdater) {
- console.log('Auto-updater not available, skipping setup');
- return;
- }
- // Configure auto-updater
- autoUpdater.checkForUpdatesAndNotify();
- // Auto-updater events
- autoUpdater.on('checking-for-update', () => {
- console.log('Checking for update...');
- });
- autoUpdater.on('update-available', (info) => {
- console.log('Update available:', info);
- dialog.showMessageBox(mainWindow, {
- type: 'info',
- title: 'Update Available',
- message: 'A new version is available. It will be downloaded in the background.',
- detail: `Version ${info.version} is now available. The update will be downloaded and installed automatically.`,
- buttons: ['OK']
- });
- });
- autoUpdater.on('update-not-available', (info) => {
- console.log('Update not available:', info);
- });
- autoUpdater.on('error', (err) => {
- console.error('Error in auto-updater:', err);
- });
- autoUpdater.on('download-progress', (progressObj) => {
- let log_message = "Download speed: " + progressObj.bytesPerSecond;
- log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
- log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
- console.log(log_message);
- });
- autoUpdater.on('update-downloaded', (info) => {
- console.log('Update downloaded:', info);
- dialog.showMessageBox(mainWindow, {
- type: 'info',
- title: 'Update Ready',
- message: 'Update downloaded and ready to install',
- detail: 'The application will restart to apply the update.',
- buttons: ['Restart Now', 'Later']
- }).then((result) => {
- if (result.response === 0) {
- autoUpdater.quitAndInstall();
- }
- });
- });
- }
- // This method will be called when Electron has finished initialization
- app.whenReady().then(() => {
- createWindow();
- // Set up auto-updater after window is created
- setTimeout(() => {
- setupAutoUpdater();
- }, 3000); // Wait 3 seconds after app start
- app.on('activate', () => {
- // On macOS, re-create a window when the dock icon is clicked
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
- });
- });
- // Quit when all windows are closed
- app.on('window-all-closed', () => {
- // On macOS, keep the app running even when all windows are closed
- if (process.platform !== 'darwin') {
- app.quit();
- }
- });
- // Security: Prevent new window creation
- app.on('web-contents-created', (event, contents) => {
- contents.on('new-window', (event, url) => {
- event.preventDefault();
- shell.openExternal(url);
- });
- });
|