@@ -19,9 +19,14 @@ import type MenuBuilder from './menu';
1919export default class AppUpdater {
2020 private readonly menubar : Menubar ;
2121 private readonly menuBuilder : MenuBuilder ;
22+ private notificationsEnabled = true ;
2223 private started = false ;
2324 private noUpdateMessageTimeout ?: NodeJS . Timeout ;
2425
26+ /**
27+ * @param menubar - The menubar instance whose tray and window the updater reports status through.
28+ * @param menuBuilder - The menu builder whose update menu items track the update state.
29+ */
2530 constructor ( menubar : Menubar , menuBuilder : MenuBuilder ) {
2631 this . menubar = menubar ;
2732 this . menuBuilder = menuBuilder ;
@@ -30,6 +35,14 @@ export default class AppUpdater {
3035 autoUpdater . logger = null ;
3136 }
3237
38+ /**
39+ * Enable or suppress update notifications without changing update checks,
40+ * downloads, or menubar state.
41+ */
42+ setNotificationsEnabled ( enabled : boolean ) : void {
43+ this . notificationsEnabled = enabled ;
44+ }
45+
3346 /**
3447 * Start the updater: register event listeners, perform the initial update check,
3548 * and schedule periodic checks. Idempotent — safe to call multiple times.
@@ -46,11 +59,10 @@ export default class AppUpdater {
4659
4760 logInfo ( 'app updater' , 'Starting updater' ) ;
4861
62+ this . started = true ;
4963 this . registerListeners ( ) ;
5064 await this . performInitialCheck ( ) ;
5165 this . schedulePeriodicChecks ( ) ;
52-
53- this . started = true ;
5466 }
5567
5668 /**
@@ -81,7 +93,9 @@ export default class AppUpdater {
8193 this . setTooltipWithStatus ( 'A new update is ready to install' ) ;
8294 this . menuBuilder . setUpdateAvailableMenuVisibility ( false ) ;
8395 this . menuBuilder . setUpdateReadyForInstallMenuVisibility ( true ) ;
84- this . showUpdateReadyDialog ( event . releaseName ?? event . version ) ;
96+ if ( this . notificationsEnabled ) {
97+ this . showUpdateReadyDialog ( event . releaseName ?? event . version ) ;
98+ }
8599 } ) ;
86100
87101 autoUpdater . on ( 'update-not-available' , ( ) => {
@@ -115,7 +129,7 @@ export default class AppUpdater {
115129 private async performInitialCheck ( ) {
116130 try {
117131 logInfo ( 'app updater' , 'Checking for updates on application launch' ) ;
118- await autoUpdater . checkForUpdatesAndNotify ( ) ;
132+ await this . checkForUpdates ( ) ;
119133 } catch ( err ) {
120134 logError ( 'auto updater' , 'Initial check failed' , toError ( err ) ) ;
121135 }
@@ -128,7 +142,7 @@ export default class AppUpdater {
128142 const runScheduledCheck = async ( ) => {
129143 try {
130144 logInfo ( 'app updater' , 'Checking for updates on a periodic schedule' ) ;
131- await autoUpdater . checkForUpdatesAndNotify ( ) ;
145+ await this . checkForUpdates ( ) ;
132146 } catch ( e ) {
133147 logError ( 'auto updater' , 'Scheduled check failed' , toError ( e ) ) ;
134148 }
@@ -142,6 +156,18 @@ export default class AppUpdater {
142156 } , APPLICATION . UPDATE_CHECK_INTERVAL_MS ) ;
143157 }
144158
159+ /**
160+ * Check and download updates, using electron-updater's native notification
161+ * only when the user has opted in.
162+ */
163+ private async checkForUpdates ( ) {
164+ if ( this . notificationsEnabled ) {
165+ return await autoUpdater . checkForUpdatesAndNotify ( ) ;
166+ }
167+
168+ return await autoUpdater . checkForUpdates ( ) ;
169+ }
170+
145171 /**
146172 * Update the tray tooltip to show the application name alongside a status message.
147173 *
0 commit comments