main.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. const { app, BrowserWindow, Menu, shell, dialog } = require('electron');
  2. const { autoUpdater } = require('electron-updater');
  3. const path = require('path');
  4. // Keep a global reference of the window object
  5. let mainWindow;
  6. function createWindow() {
  7. // Create the browser window
  8. mainWindow = new BrowserWindow({
  9. width: 1200,
  10. height: 800,
  11. minWidth: 800,
  12. minHeight: 600,
  13. icon: path.join(__dirname, 'img/logo.png'),
  14. webPreferences: {
  15. nodeIntegration: false,
  16. contextIsolation: true,
  17. enableRemoteModule: false,
  18. webSecurity: true
  19. },
  20. show: false // Don't show until ready
  21. });
  22. // Load the home page
  23. mainWindow.loadFile(path.join(__dirname, 'home.html'));
  24. // Show window when ready to prevent visual flash
  25. mainWindow.once('ready-to-show', () => {
  26. mainWindow.show();
  27. });
  28. // Handle external links
  29. mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  30. shell.openExternal(url);
  31. return { action: 'deny' };
  32. });
  33. // Emitted when the window is closed
  34. mainWindow.on('closed', () => {
  35. mainWindow = null;
  36. });
  37. // Create application menu
  38. createMenu();
  39. }
  40. function createMenu() {
  41. const template = [
  42. {
  43. label: 'File',
  44. submenu: [
  45. {
  46. label: 'New Note',
  47. accelerator: 'CmdOrCtrl+N',
  48. click: () => {
  49. mainWindow.loadFile(path.join(__dirname, 'index.html'));
  50. }
  51. },
  52. {
  53. label: 'Home',
  54. accelerator: 'CmdOrCtrl+H',
  55. click: () => {
  56. mainWindow.loadFile(path.join(__dirname, 'home.html'));
  57. }
  58. },
  59. { type: 'separator' },
  60. {
  61. label: 'Check for Updates',
  62. click: () => {
  63. autoUpdater.checkForUpdatesAndNotify();
  64. }
  65. },
  66. { type: 'separator' },
  67. {
  68. label: 'Quit',
  69. accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
  70. click: () => {
  71. app.quit();
  72. }
  73. }
  74. ]
  75. },
  76. {
  77. label: 'Edit',
  78. submenu: [
  79. { role: 'undo' },
  80. { role: 'redo' },
  81. { type: 'separator' },
  82. { role: 'cut' },
  83. { role: 'copy' },
  84. { role: 'paste' },
  85. { role: 'selectall' }
  86. ]
  87. },
  88. {
  89. label: 'View',
  90. submenu: [
  91. { role: 'reload' },
  92. { role: 'forceReload' },
  93. { role: 'toggleDevTools' },
  94. { type: 'separator' },
  95. { role: 'resetZoom' },
  96. { role: 'zoomIn' },
  97. { role: 'zoomOut' },
  98. { type: 'separator' },
  99. { role: 'togglefullscreen' }
  100. ]
  101. },
  102. {
  103. label: 'Window',
  104. submenu: [
  105. { role: 'minimize' },
  106. { role: 'close' }
  107. ]
  108. }
  109. ];
  110. // macOS specific menu adjustments
  111. if (process.platform === 'darwin') {
  112. template.unshift({
  113. label: app.getName(),
  114. submenu: [
  115. { role: 'about' },
  116. { type: 'separator' },
  117. { role: 'services' },
  118. { type: 'separator' },
  119. { role: 'hide' },
  120. { role: 'hideothers' },
  121. { role: 'unhide' },
  122. { type: 'separator' },
  123. { role: 'quit' }
  124. ]
  125. });
  126. // Window menu
  127. template[4].submenu = [
  128. { role: 'close' },
  129. { role: 'minimize' },
  130. { role: 'zoom' },
  131. { type: 'separator' },
  132. { role: 'front' }
  133. ];
  134. }
  135. const menu = Menu.buildFromTemplate(template);
  136. Menu.setApplicationMenu(menu);
  137. }
  138. // Auto-updater configuration
  139. function setupAutoUpdater() {
  140. // Configure auto-updater
  141. autoUpdater.checkForUpdatesAndNotify();
  142. // Auto-updater events
  143. autoUpdater.on('checking-for-update', () => {
  144. console.log('Checking for update...');
  145. });
  146. autoUpdater.on('update-available', (info) => {
  147. console.log('Update available:', info);
  148. dialog.showMessageBox(mainWindow, {
  149. type: 'info',
  150. title: 'Update Available',
  151. message: 'A new version is available. It will be downloaded in the background.',
  152. detail: `Version ${info.version} is now available. The update will be downloaded and installed automatically.`,
  153. buttons: ['OK']
  154. });
  155. });
  156. autoUpdater.on('update-not-available', (info) => {
  157. console.log('Update not available:', info);
  158. });
  159. autoUpdater.on('error', (err) => {
  160. console.error('Error in auto-updater:', err);
  161. });
  162. autoUpdater.on('download-progress', (progressObj) => {
  163. let log_message = "Download speed: " + progressObj.bytesPerSecond;
  164. log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
  165. log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
  166. console.log(log_message);
  167. });
  168. autoUpdater.on('update-downloaded', (info) => {
  169. console.log('Update downloaded:', info);
  170. dialog.showMessageBox(mainWindow, {
  171. type: 'info',
  172. title: 'Update Ready',
  173. message: 'Update downloaded and ready to install',
  174. detail: 'The application will restart to apply the update.',
  175. buttons: ['Restart Now', 'Later']
  176. }).then((result) => {
  177. if (result.response === 0) {
  178. autoUpdater.quitAndInstall();
  179. }
  180. });
  181. });
  182. }
  183. // This method will be called when Electron has finished initialization
  184. app.whenReady().then(() => {
  185. createWindow();
  186. // Set up auto-updater after window is created
  187. setTimeout(() => {
  188. setupAutoUpdater();
  189. }, 3000); // Wait 3 seconds after app start
  190. app.on('activate', () => {
  191. // On macOS, re-create a window when the dock icon is clicked
  192. if (BrowserWindow.getAllWindows().length === 0) {
  193. createWindow();
  194. }
  195. });
  196. });
  197. // Quit when all windows are closed
  198. app.on('window-all-closed', () => {
  199. // On macOS, keep the app running even when all windows are closed
  200. if (process.platform !== 'darwin') {
  201. app.quit();
  202. }
  203. });
  204. // Security: Prevent new window creation
  205. app.on('web-contents-created', (event, contents) => {
  206. contents.on('new-window', (event, url) => {
  207. event.preventDefault();
  208. shell.openExternal(url);
  209. });
  210. });