@@ -60,7 +60,7 @@ function getCurrentPackage() {
60
60
return NativeCodePush . isFailedUpdate ( currentPackage . packageHash ) ;
61
61
} )
62
62
. then ( ( failedUpdate ) => {
63
- localPackage . failedApply = failedUpdate ;
63
+ localPackage . failedInstall = failedUpdate ;
64
64
return NativeCodePush . isFirstRun ( localPackage . packageHash ) ;
65
65
} )
66
66
. then ( ( isFirstRun ) => {
@@ -98,7 +98,7 @@ function checkForUpdate() {
98
98
}
99
99
100
100
// Ignore updates that require a newer app version,
101
- // since the end-user couldn't reliably apply it
101
+ // since the end-user couldn't reliably install it
102
102
if ( ! update || update . updateAppVersion ) {
103
103
return resolve ( null ) ;
104
104
}
@@ -107,7 +107,7 @@ function checkForUpdate() {
107
107
108
108
NativeCodePush . isFailedUpdate ( update . packageHash )
109
109
. then ( ( isFailedHash ) => {
110
- update . failedApply = isFailedHash ;
110
+ update . failedInstall = isFailedHash ;
111
111
resolve ( update ) ;
112
112
} )
113
113
. catch ( reject )
@@ -117,6 +117,11 @@ function checkForUpdate() {
117
117
} ) ;
118
118
}
119
119
120
+ /* Logs messages to console with the [CodePush] prefix */
121
+ function log ( message ) {
122
+ console . log ( `[CodePush] ${ message } ` )
123
+ }
124
+
120
125
/**
121
126
* The sync method provides a simple, one-line experience for
122
127
* incorporating the check, download and application of an update.
@@ -126,75 +131,128 @@ function checkForUpdate() {
126
131
* releases, and displaying a standard confirmation UI to the end-user
127
132
* when an update is available.
128
133
*/
129
- function sync ( options = { } ) {
134
+ function sync ( options = { } , syncStatusChangeCallback , downloadProgressCallback ) {
130
135
var syncOptions = {
131
- descriptionPrefix : " Description: " ,
132
- appendReleaseDescription : false ,
133
136
134
137
ignoreFailedUpdates : true ,
135
-
136
- mandatoryContinueButtonLabel : "Continue" ,
137
- mandatoryUpdateMessage : "An update is available that must be installed." ,
138
-
139
- optionalIgnoreButtonLabel : "Ignore" ,
140
- optionalInstallButtonLabel : "Install" ,
141
- optionalUpdateMessage : "An update is available. Would you like to install it?" ,
142
-
138
+ installMode : CodePush . InstallMode . ON_NEXT_RESTART ,
143
139
rollbackTimeout : 0 ,
144
-
145
- updateTitle : "Update available" ,
140
+ updateDialog : null ,
146
141
147
142
...options
148
143
} ;
149
-
144
+
145
+ syncStatusChangeCallback = typeof syncStatusChangeCallback == "function"
146
+ ? syncStatusChangeCallback
147
+ : function ( syncStatus ) {
148
+ switch ( syncStatus ) {
149
+ case CodePush . SyncStatus . CHECKING_FOR_UPDATE :
150
+ log ( "Checking for update." ) ;
151
+ break ;
152
+ case CodePush . SyncStatus . AWAITING_USER_ACTION :
153
+ log ( "Awaiting user action." ) ;
154
+ break ;
155
+ case CodePush . SyncStatus . DOWNLOADING_PACKAGE :
156
+ log ( "Downloading package." ) ;
157
+ break ;
158
+ case CodePush . SyncStatus . INSTALLING_UPDATE :
159
+ log ( "Installing update." ) ;
160
+ break ;
161
+ case CodePush . SyncStatus . UP_TO_DATE :
162
+ log ( "App is up to date." ) ;
163
+ break ;
164
+ case CodePush . SyncStatus . UPDATE_IGNORED :
165
+ log ( "User cancelled the update." ) ;
166
+ break ;
167
+ case CodePush . SyncStatus . UPDATE_INSTALLED :
168
+ /*
169
+ * If the install mode is IMMEDIATE, this will not get returned as the
170
+ * app will be restarted to a new Javascript context.
171
+ */
172
+ if ( syncOptions . installMode == CodePush . InstallMode . ON_NEXT_RESTART ) {
173
+ log ( "Update is installed and will be run on the next app restart." ) ;
174
+ } else {
175
+ log ( "Update is installed and will be run when the app next resumes." ) ;
176
+ }
177
+ break ;
178
+ case CodePush . SyncStatus . UNKNOWN_ERROR :
179
+ log ( "An unknown error occurred." ) ;
180
+ break ;
181
+ }
182
+ } ;
183
+
184
+ downloadProgressCallback = typeof downloadProgressCallback == "function"
185
+ ? downloadProgressCallback
186
+ : function ( downloadProgress ) {
187
+ log ( `Expecting ${ downloadProgress . totalBytes } bytes, received ${ downloadProgress . receivedBytes } bytes.` ) ;
188
+ } ;
189
+
150
190
return new Promise ( ( resolve , reject ) => {
191
+ syncStatusChangeCallback ( CodePush . SyncStatus . CHECKING_FOR_UPDATE ) ;
151
192
checkForUpdate ( )
152
193
. then ( ( remotePackage ) => {
153
- if ( ! remotePackage || ( remotePackage . failedApply && syncOptions . ignoreFailedUpdates ) ) {
194
+ var doDownloadAndInstall = ( ) => {
195
+ syncStatusChangeCallback ( CodePush . SyncStatus . DOWNLOADING_PACKAGE ) ;
196
+ remotePackage . download ( downloadProgressCallback )
197
+ . then ( ( localPackage ) => {
198
+ syncStatusChangeCallback ( CodePush . SyncStatus . INSTALLING_UPDATE ) ;
199
+ return localPackage . install ( syncOptions . rollbackTimeout , syncOptions . installMode , ( ) => {
200
+ syncStatusChangeCallback ( CodePush . SyncStatus . UPDATE_INSTALLED ) ;
201
+ resolve ( CodePush . SyncStatus . UPDATE_INSTALLED ) ;
202
+ } ) ;
203
+ } )
204
+ . catch ( reject )
205
+ . done ( ) ;
206
+ }
207
+
208
+ if ( ! remotePackage || ( remotePackage . failedInstall && syncOptions . ignoreFailedUpdates ) ) {
209
+ syncStatusChangeCallback ( CodePush . SyncStatus . UP_TO_DATE ) ;
154
210
resolve ( CodePush . SyncStatus . UP_TO_DATE ) ;
155
211
}
156
- else {
212
+ else if ( syncOptions . updateDialog ) {
213
+ syncOptions . updateDialog = Object . assign ( CodePush . DEFAULT_UPDATE_DIALOG , syncOptions . updateDialog ) ;
214
+
157
215
var message = null ;
158
216
var dialogButtons = [
159
217
{
160
218
text : null ,
161
219
onPress : ( ) => {
162
- remotePackage . download ( )
163
- . then ( ( localPackage ) => {
164
- resolve ( CodePush . SyncStatus . UPDATE_APPLIED )
165
- return localPackage . apply ( syncOptions . rollbackTimeout ) ;
166
- } )
167
- . catch ( reject )
168
- . done ( ) ;
220
+ doDownloadAndInstall ( ) ;
169
221
}
170
222
}
171
223
] ;
172
224
173
225
if ( remotePackage . isMandatory ) {
174
- message = syncOptions . mandatoryUpdateMessage ;
226
+ message = syncOptions . updateDialog . mandatoryUpdateMessage ;
175
227
dialogButtons [ 0 ] . text = syncOptions . mandatoryContinueButtonLabel ;
176
228
} else {
177
- message = syncOptions . optionalUpdateMessage ;
178
- dialogButtons [ 0 ] . text = syncOptions . optionalInstallButtonLabel ;
229
+ message = syncOptions . updateDialog . optionalUpdateMessage ;
230
+ dialogButtons [ 0 ] . text = syncOptions . updateDialog . optionalInstallButtonLabel ;
179
231
180
232
// Since this is an optional update, add another button
181
233
// to allow the end-user to ignore it
182
234
dialogButtons . push ( {
183
- text : syncOptions . optionalIgnoreButtonLabel ,
235
+ text : syncOptions . updateDialog . optionalIgnoreButtonLabel ,
184
236
onPress : ( ) => resolve ( CodePush . SyncStatus . UPDATE_IGNORED )
185
237
} ) ;
186
238
}
187
239
188
240
// If the update has a description, and the developer
189
241
// explicitly chose to display it, then set that as the message
190
- if ( syncOptions . appendReleaseDescription && remotePackage . description ) {
191
- message += `${ syncOptions . descriptionPrefix } ${ remotePackage . description } ` ;
242
+ if ( syncOptions . updateDialog . appendReleaseDescription && remotePackage . description ) {
243
+ message += `${ syncOptions . updateDialog . descriptionPrefix } ${ remotePackage . description } ` ;
192
244
}
193
245
246
+ syncStatusChangeCallback ( CodePush . SyncStatus . AWAITING_USER_ACTION ) ;
194
247
AlertIOS . alert ( syncOptions . updateTitle , message , dialogButtons ) ;
248
+ } else {
249
+ doDownloadAndInstall ( ) ;
195
250
}
196
251
} )
197
- . catch ( reject )
252
+ . catch ( ( error ) => {
253
+ syncStatusChangeCallback ( CodePush . SyncStatus . UNKNOWN_ERROR ) ;
254
+ reject ( error ) ;
255
+ } )
198
256
. done ( ) ;
199
257
} ) ;
200
258
} ;
@@ -203,19 +261,35 @@ var CodePush = {
203
261
checkForUpdate : checkForUpdate ,
204
262
getConfiguration : getConfiguration ,
205
263
getCurrentPackage : getCurrentPackage ,
264
+ log : log ,
206
265
notifyApplicationReady : NativeCodePush . notifyApplicationReady ,
207
266
setUpTestDependencies : setUpTestDependencies ,
208
267
sync : sync ,
209
- RestartMode : {
210
- NONE : NativeCodePush . codePushRestartModeNone , // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart
211
- IMMEDIATE : NativeCodePush . codePushRestartModeImmediate , // Restart the app immediately
212
- ON_NEXT_RESUME : NativeCodePush . codePushRestartModeOnNextResume // Restart the app the next time it is resumed from the background
268
+ InstallMode : {
269
+ IMMEDIATE : NativeCodePush . codePushInstallModeImmediate , // Restart the app immediately
270
+ ON_NEXT_RESTART : NativeCodePush . codePushInstallModeOnNextRestart , // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart
271
+ ON_NEXT_RESUME : NativeCodePush . codePushInstallModeOnNextResume // Restart the app the next time it is resumed from the background
213
272
} ,
214
273
SyncStatus : {
215
- UP_TO_DATE : 0 , // The running app is up-to-date
216
- UPDATE_IGNORED : 1 , // The app had an optional update and the end-user chose to ignore it
217
- UPDATE_APPLIED : 2 // The app had an optional/mandatory update that was successfully downloaded and is about to be applied
274
+ CHECKING_FOR_UPDATE : 0 ,
275
+ AWAITING_USER_ACTION : 1 ,
276
+ DOWNLOADING_PACKAGE : 2 ,
277
+ INSTALLING_UPDATE : 3 ,
278
+ UP_TO_DATE : 4 , // The running app is up-to-date
279
+ UPDATE_IGNORED : 5 , // The app had an optional update and the end-user chose to ignore it
280
+ UPDATE_INSTALLED : 6 , // The app had an optional/mandatory update that was successfully downloaded and is about to be installed.
281
+ UNKNOWN_ERROR : - 1
282
+ } ,
283
+ DEFAULT_UPDATE_DIALOG : {
284
+ appendReleaseDescription : false ,
285
+ descriptionPrefix : " Description: " ,
286
+ mandatoryContinueButtonLabel : "Continue" ,
287
+ mandatoryUpdateMessage : "An update is available that must be installed." ,
288
+ optionalIgnoreButtonLabel : "Ignore" ,
289
+ optionalInstallButtonLabel : "Install" ,
290
+ optionalUpdateMessage : "An update is available. Would you like to install it?" ,
291
+ updateTitle : "Update available" ,
218
292
}
219
293
} ;
220
294
221
- module . exports = CodePush ;
295
+ module . exports = CodePush ;
0 commit comments