1
- import { dialog , shell } from 'electron'
1
+ import { app , dialog , shell } from 'electron'
2
2
import { autoUpdater } from 'electron-updater'
3
3
import { t } from 'i18next'
4
4
5
- import { configStore , icon , isLinux } from './constants'
6
- import { logError , logInfo , LogPrefix } from './logger/logger'
7
- import { isOnline } from './online_monitor'
5
+ import { configStore , icon , isLinux } from '../constants'
6
+ import { logError , logInfo , LogPrefix } from '../logger/logger'
8
7
import { captureException } from '@sentry/electron'
9
- import { getFileSize } from './utils'
8
+ import { getFileSize } from '.. /utils'
10
9
import { ClientUpdateStatuses } from '@hyperplay/utils'
11
- import { trackEvent } from './metrics/metrics'
12
- // to test auto update on windows locally make sure you added the option "verifyUpdateCodeSignature": false
13
- // under build.win in package.json and also change the app version to an old one there
10
+ import { trackEvent } from '../metrics/metrics'
11
+ import { getErrorMessage , removeCachedUpdatesFolder } from './utils'
12
+ // to test auto update on windows locally make sure you added the option verifyUpdateCodeSignature: false
13
+ // under build.win in electron-builder.yml and also change the app version to an old one there
14
14
15
15
const appSettings = configStore . get_nodefault ( 'settings' )
16
16
const shouldCheckForUpdates = appSettings ?. checkForUpdatesOnStartup === true
@@ -21,17 +21,35 @@ autoUpdater.autoInstallOnAppQuit = true
21
21
22
22
let isAppUpdating = false
23
23
let hasUpdated = false
24
+ let hasReportedDownloadStart = false
24
25
25
- // check for updates every hour
26
- const checkUpdateInterval = 1 * 60 * 60 * 1000
27
- setInterval ( ( ) => {
28
- if ( isOnline ( ) && shouldCheckForUpdates ) {
29
- autoUpdater . checkForUpdates ( )
26
+ let updateAttempts = 0
27
+ const MAX_UPDATE_ATTEMPTS = 10
28
+ // check for updates every 3 hours
29
+ const checkUpdateInterval = 3 * 1000 * 60 * 60
30
+
31
+ setInterval ( async ( ) => {
32
+ if ( shouldCheckForUpdates && ! hasUpdated && ! isAppUpdating ) {
33
+ logInfo ( 'Checking for client updates...' , LogPrefix . AutoUpdater )
34
+ await autoUpdater . checkForUpdates ( )
30
35
}
31
36
} , checkUpdateInterval )
32
37
33
38
autoUpdater . on ( 'update-available' , async ( info ) => {
34
- if ( ! isOnline ( ) || ! shouldCheckForUpdates ) {
39
+ if ( isAppUpdating && hasUpdated ) {
40
+ logInfo (
41
+ 'New update available, but user has already updated the app' ,
42
+ LogPrefix . AutoUpdater
43
+ )
44
+ return
45
+ }
46
+
47
+ if ( ! shouldCheckForUpdates ) {
48
+ logInfo (
49
+ 'New update available, but user has disabled auto updates' ,
50
+ LogPrefix . AutoUpdater
51
+ )
52
+
35
53
return
36
54
}
37
55
newVersion = info . version
@@ -56,6 +74,19 @@ autoUpdater.on('update-available', async (info) => {
56
74
// log download progress
57
75
autoUpdater . on ( 'download-progress' , ( progress ) => {
58
76
isAppUpdating = true
77
+
78
+ // Track download start only once
79
+ if ( ! hasReportedDownloadStart ) {
80
+ trackEvent ( {
81
+ event : 'Downloading Client Update' ,
82
+ properties : {
83
+ currentVersion : autoUpdater . currentVersion . version ,
84
+ newVersion
85
+ }
86
+ } )
87
+ hasReportedDownloadStart = true
88
+ }
89
+
59
90
logInfo (
60
91
'Downloading HyperPlay update...' +
61
92
`Download speed: ${ progress . bytesPerSecond } , ` +
@@ -68,7 +99,10 @@ autoUpdater.on('download-progress', (progress) => {
68
99
} )
69
100
70
101
autoUpdater . on ( 'update-downloaded' , async ( ) => {
71
- logInfo ( 'App update is downloaded' )
102
+ logInfo ( 'The App update was downloaded' , LogPrefix . AutoUpdater )
103
+ hasUpdated = true
104
+ isAppUpdating = false
105
+ hasReportedDownloadStart = false // Reset for potential future updates
72
106
73
107
trackEvent ( {
74
108
event : 'Client Update Downloaded' ,
@@ -91,16 +125,38 @@ autoUpdater.on('update-downloaded', async () => {
91
125
if ( response === 1 ) {
92
126
return autoUpdater . quitAndInstall ( )
93
127
}
94
- hasUpdated = true
128
+ logInfo ( 'User chose not to update the app for now.' , LogPrefix . AutoUpdater )
95
129
} )
96
130
97
131
autoUpdater . on ( 'error' , async ( error ) => {
98
- if ( ! isOnline ( ) ) {
132
+ isAppUpdating = false
133
+ const isNewVersion = newVersion !== app . getVersion ( )
134
+
135
+ // To avoid false positives, we should not show the error dialog if the app has already updated successfully
136
+ if ( hasUpdated || ! isNewVersion ) {
99
137
return
100
138
}
101
139
102
- isAppUpdating = false
103
- logError ( `Error updating HyperPlay: ${ error . message } ` , LogPrefix . AutoUpdater )
140
+ const errorMessage = getErrorMessage ( error . message )
141
+ logError ( `Error updating HyperPlay: ${ errorMessage } ` , LogPrefix . AutoUpdater )
142
+
143
+ // will remove cached updates when it fails to avoid corrupted updates
144
+ if ( updateAttempts > 3 ) {
145
+ await removeCachedUpdatesFolder ( )
146
+ }
147
+
148
+ updateAttempts ++
149
+
150
+ if ( updateAttempts < MAX_UPDATE_ATTEMPTS ) {
151
+ logInfo (
152
+ `Retrying update attempt ${ updateAttempts + 1 } /${ MAX_UPDATE_ATTEMPTS } ` ,
153
+ LogPrefix . AutoUpdater
154
+ )
155
+ setTimeout ( ( ) => {
156
+ autoUpdater . checkForUpdates ( )
157
+ } , 6000 )
158
+ return
159
+ }
104
160
105
161
trackEvent ( {
106
162
event : 'Client Update Error' ,
@@ -115,17 +171,19 @@ autoUpdater.on('error', async (error) => {
115
171
tags : {
116
172
event : 'Client Update Error' ,
117
173
currentVersion : autoUpdater . currentVersion . version ,
118
- newVersion
174
+ newVersion,
175
+ totalAttempts : MAX_UPDATE_ATTEMPTS
119
176
}
120
177
} )
121
178
179
+ updateAttempts = 0
180
+
122
181
const { response } = await dialog . showMessageBox ( {
123
- title : t ( 'box.error.update.title ' , 'Error Updating' ) ,
182
+ title : t ( 'box.error.update.message ' , 'Error Updating' ) ,
124
183
message : t (
125
- 'box.error.update.message' ,
126
- `Something went wrong with the update after multiple attempts! Please manually uninstall and reinstall HyperPlay. error: ${ JSON . stringify (
127
- error
128
- ) } `
184
+ 'box.error.update.body' ,
185
+ `Something went wrong with the update after multiple attempts! Please check the error message below or reinstall HyperPlay. error: {{error}}` ,
186
+ { error : errorMessage }
129
187
) ,
130
188
type : 'error' ,
131
189
buttons : [ t ( 'button.cancel' , 'Cancel' ) , t ( 'button.download' , 'Download' ) ]
0 commit comments