@@ -5,6 +5,9 @@ const fs = require("fs");
55const { pathToFileURL } = require ( "url" ) ;
66
77const isDev = process . env . NODE_ENV === "development" ;
8+ const updaterMenuApi = {
9+ checkNow : null ,
10+ } ;
811
912function resolveNotificationIcon ( ) {
1013 const candidates = [
@@ -41,6 +44,14 @@ function setupAutoUpdater() {
4144 if ( isDev || ! app . isPackaged ) return ;
4245 try {
4346 const { autoUpdater } = require ( "electron-updater" ) ;
47+ let manualCheckInProgress = false ;
48+
49+ const showUpdateMessage = async ( title , message ) => {
50+ try {
51+ const win = BrowserWindow . getAllWindows ( ) [ 0 ] ;
52+ await dialog . showMessageBox ( win || null , { type : "info" , title, message } ) ;
53+ } catch ( _ ) { }
54+ } ;
4455 autoUpdater . logger = {
4556 info : ( m ) => log ( `[updater] ${ typeof m === "string" ? m : JSON . stringify ( m ) } ` ) ,
4657 warn : ( m ) => log ( `[updater] ${ typeof m === "string" ? m : JSON . stringify ( m ) } ` ) ,
@@ -123,6 +134,46 @@ function setupAutoUpdater() {
123134 } ) ;
124135 } ) ;
125136
137+ autoUpdater . on ( "checking-for-update" , ( ) => {
138+ if ( manualCheckInProgress ) {
139+ log ( "[updater] manual check started" ) ;
140+ }
141+ } ) ;
142+
143+ autoUpdater . on ( "update-available" , ( info ) => {
144+ if ( manualCheckInProgress ) {
145+ manualCheckInProgress = false ;
146+ void showUpdateMessage (
147+ "Update found" ,
148+ `Version ${ info ?. version || "new" } is available and downloading in background.`
149+ ) ;
150+ }
151+ } ) ;
152+
153+ autoUpdater . on ( "update-not-available" , ( ) => {
154+ if ( manualCheckInProgress ) {
155+ manualCheckInProgress = false ;
156+ void showUpdateMessage ( "No updates" , "You are already on the latest version." ) ;
157+ }
158+ } ) ;
159+
160+ autoUpdater . on ( "error" , ( err ) => {
161+ if ( manualCheckInProgress ) {
162+ manualCheckInProgress = false ;
163+ void showUpdateMessage ( "Update check failed" , err ?. message || String ( err ) ) ;
164+ }
165+ } ) ;
166+
167+ updaterMenuApi . checkNow = async ( ) => {
168+ try {
169+ manualCheckInProgress = true ;
170+ await autoUpdater . checkForUpdates ( ) ;
171+ } catch ( e ) {
172+ manualCheckInProgress = false ;
173+ await showUpdateMessage ( "Update check failed" , e ?. message || String ( e ) ) ;
174+ }
175+ } ;
176+
126177 app . on ( "before-quit" , ( ) => {
127178 if ( installRequested ) {
128179 log ( "[updater] before-quit for update install" ) ;
@@ -138,8 +189,8 @@ function setupAutoUpdater() {
138189 // 1) On startup (each app launch)
139190 markAndCheck ( ) ;
140191
141- // 2) While running: every 6 hours
142- const periodicMs = 1 * 60 * 60 * 1000 ;
192+ // 2) While running: every 1 minute (temporary aggressive polling)
193+ const periodicMs = 1 * 60 * 1000 ;
143194 setInterval ( markAndCheck , periodicMs ) ;
144195
145196 // 3) When user brings the app back to foreground (throttled: at most once per 30 min)
@@ -154,6 +205,52 @@ function setupAutoUpdater() {
154205 }
155206}
156207
208+ function setupAppMenu ( ) {
209+ const template = [
210+ {
211+ label : "File" ,
212+ submenu : [ { role : "quit" , label : "Exit" } ] ,
213+ } ,
214+ {
215+ label : "Edit" ,
216+ submenu : [
217+ { role : "undo" } ,
218+ { role : "redo" } ,
219+ { type : "separator" } ,
220+ { role : "cut" } ,
221+ { role : "copy" } ,
222+ { role : "paste" } ,
223+ { role : "selectAll" } ,
224+ ] ,
225+ } ,
226+ {
227+ label : "View" ,
228+ submenu : [ { role : "reload" } , { role : "togglefullscreen" } ] ,
229+ } ,
230+ {
231+ label : "Updates" ,
232+ submenu : [
233+ {
234+ label : "Check for updates now" ,
235+ click : ( ) => {
236+ if ( typeof updaterMenuApi . checkNow === "function" ) {
237+ void updaterMenuApi . checkNow ( ) ;
238+ } else {
239+ void dialog . showMessageBox ( {
240+ type : "info" ,
241+ title : "Updates unavailable" ,
242+ message : "Updater is not available in development mode." ,
243+ } ) ;
244+ }
245+ } ,
246+ } ,
247+ ] ,
248+ } ,
249+ ] ;
250+ const menu = Menu . buildFromTemplate ( template ) ;
251+ Menu . setApplicationMenu ( menu ) ;
252+ }
253+
157254protocol . registerSchemesAsPrivileged ( [
158255 { scheme : "app" , privileges : { standard : true , supportFetchAPI : true } } ,
159256] ) ;
@@ -240,7 +337,7 @@ app.whenReady().then(() => {
240337 if ( process . platform === "win32" ) {
241338 app . setAppUserModelId ( "com.sraibaby.app" ) ;
242339 }
243- Menu . setApplicationMenu ( null ) ; // We can enable standart app menu by deteng this line
340+ setupAppMenu ( ) ;
244341 if ( ! isDev ) {
245342 const appPath = app . getAppPath ( ) ;
246343 const distPath = path . join ( appPath , "dist" ) ;
0 commit comments