diff --git a/lib/gui/models/flash-state.js b/lib/gui/models/flash-state.js index a883de22..23fcb526 100644 --- a/lib/gui/models/flash-state.js +++ b/lib/gui/models/flash-state.js @@ -145,7 +145,7 @@ FlashState.service('FlashStateModel', function() { /** * @summary Get the flash results * @function - * @public + * @private * * @returns {Object} flash results * @@ -170,6 +170,85 @@ FlashState.service('FlashStateModel', function() { return Store.getState().get('flashState').toJS(); }; + /** + * @summary Determine if the last flash was successful + * @function + * @public + * + * @description + * This function returns true if the flash was cancelled, given + * a cancellation is a user request, and doesn't represent an + * actual flash error. + * + * This function returns true if there was no last flash. + * + * @returns {Boolean} whether the last flash was successful + * + * @example + * if (FlashStateModel.wasLastFlashSuccessful()) { + * console.log('The last flash was successful'); + * } + */ + this.wasLastFlashSuccessful = () => { + return _.some([ + this.wasLastFlashCancelled(), + _.get(this.getFlashResults(), 'passedValidation', true) + ]); + }; + + /** + * @summary Determine if the last flash was cancelled + * @function + * @public + * + * @description + * This function returns false if there was no last flash. + * + * @returns {Boolean} whether the last flash was cancelled + * + * @example + * if (FlashStateModel.wasLastFlashCancelled()) { + * console.log('The last flash was cancelled'); + * } + */ + this.wasLastFlashCancelled = () => { + return _.get(this.getFlashResults(), 'cancelled', false); + }; + + /** + * @summary Get last flash source checksum + * @function + * @public + * + * @description + * This function returns undefined if there was no last flash. + * + * @returns {(String|Undefined)} the last flash source checksum + * + * @example + * const checksum = FlashStateModel.getLastFlashSourceChecksum(); + */ + this.getLastFlashSourceChecksum = () => { + return this.getFlashResults().sourceChecksum; + }; + + /** + * @summary Get last flash error code + * @function + * @public + * + * @description + * This function returns undefined if there was no last flash. + * + * @returns {(String|Undefined)} the last flash error code + * + * @example + * const errorCode = FlashStateModel.getLastFlashErrorCode(); + */ + this.getLastFlashErrorCode = () => { + return this.getFlashResults().errorCode; + }; + }); module.exports = MODULE_NAME; diff --git a/lib/gui/models/store.js b/lib/gui/models/store.js index 109f40f0..ed89a2ff 100644 --- a/lib/gui/models/store.js +++ b/lib/gui/models/store.js @@ -170,18 +170,15 @@ const storeReducer = (state, action) => { throw new Error('Missing results'); } - if (_.isUndefined(action.data.passedValidation) || _.isNull(action.data.passedValidation)) { - throw new Error('Missing results passedValidation'); - } + _.defaults(action.data, { + passedValidation: false, + cancelled: false + }); if (!_.isBoolean(action.data.passedValidation)) { throw new Error(`Invalid results passedValidation: ${action.data.passedValidation}`); } - if (_.isUndefined(action.data.cancelled) || _.isNull(action.data.cancelled)) { - throw new Error('Missing results cancelled'); - } - if (!_.isBoolean(action.data.cancelled)) { throw new Error(`Invalid results cancelled: ${action.data.cancelled}`); } @@ -202,6 +199,10 @@ const storeReducer = (state, action) => { throw new Error(`Invalid results sourceChecksum: ${action.data.sourceChecksum}`); } + if (action.data.passedValidation && action.data.errorCode) { + throw new Error('The errorCode value can\'t be set if the flashing passed validation'); + } + if (action.data.errorCode && !_.isString(action.data.errorCode)) { throw new Error(`Invalid results errorCode: ${action.data.errorCode}`); } diff --git a/lib/gui/modules/image-writer.js b/lib/gui/modules/image-writer.js index 4701d86a..13b75bb0 100644 --- a/lib/gui/modules/image-writer.js +++ b/lib/gui/modules/image-writer.js @@ -21,7 +21,6 @@ */ const angular = require('angular'); -const _ = require('lodash'); const childWriter = require('../../src/child-writer'); const MODULE_NAME = 'Etcher.Modules.ImageWriter'; @@ -102,20 +101,8 @@ imageWriter.service('ImageWriterService', function($q, $rootScope, SettingsModel FlashStateModel.setProgressState(state); }); - }).then((results) => { - - // TODO: Make sure `etcher-image-write` always - // sends a `cancelled` and `passedValidation` property. - _.defaults(results, { - cancelled: false, - passedValidation: false - }); - - FlashStateModel.unsetFlashingFlag(results); - }).catch((error) => { + }).then(FlashStateModel.unsetFlashingFlag).catch((error) => { FlashStateModel.unsetFlashingFlag({ - cancelled: false, - passedValidation: false, errorCode: error.code }); diff --git a/lib/gui/pages/finish/controllers/finish.js b/lib/gui/pages/finish/controllers/finish.js index c64a564f..496220a4 100644 --- a/lib/gui/pages/finish/controllers/finish.js +++ b/lib/gui/pages/finish/controllers/finish.js @@ -30,7 +30,7 @@ module.exports = function($state, FlashStateModel, SelectionStateModel, Analytic * @type String * @public */ - this.checksum = FlashStateModel.getFlashResults().sourceChecksum; + this.checksum = FlashStateModel.getLastFlashSourceChecksum(); /** * @summary Restart the flashing process diff --git a/lib/gui/pages/main/controllers/main.js b/lib/gui/pages/main/controllers/main.js index 1d5cabe9..4255d8b1 100644 --- a/lib/gui/pages/main/controllers/main.js +++ b/lib/gui/pages/main/controllers/main.js @@ -168,16 +168,6 @@ module.exports = function( AnalyticsService.logEvent('Restart after failure'); }; - this.wasLastFlashSuccessful = () => { - const flashResults = FlashStateModel.getFlashResults(); - - if (_.get(flashResults, 'cancelled', false)) { - return true; - } - - return _.get(flashResults, 'passedValidation', true); - }; - this.flash = (image, drive) => { if (FlashStateModel.isFlashing()) { @@ -194,13 +184,11 @@ module.exports = function( }); return ImageWriterService.flash(image, drive).then(() => { - const results = FlashStateModel.getFlashResults(); - - if (results.cancelled) { + if (FlashStateModel.wasLastFlashCancelled()) { return; } - if (results.passedValidation) { + if (FlashStateModel.wasLastFlashSuccessful()) { OSNotificationService.send('Success!', 'Your flash is complete'); AnalyticsService.logEvent('Done'); $state.go('success'); diff --git a/lib/gui/pages/main/templates/main.tpl.html b/lib/gui/pages/main/templates/main.tpl.html index 4a0feaba..5333351c 100644 --- a/lib/gui/pages/main/templates/main.tpl.html +++ b/lib/gui/pages/main/templates/main.tpl.html @@ -87,7 +87,7 @@ percentage="main.state.getFlashState().percentage" striped="{{ main.state.getFlashState().type == 'check' }}" ng-attr-active="{{ main.state.isFlashing() }}" - ng-show="main.wasLastFlashSuccessful()" + ng-show="main.state.wasLastFlashSuccessful()" ng-click="main.flash(main.selection.getImagePath(), main.selection.getDrive())" ng-disabled="!main.selection.hasImage() || !main.selection.hasDrive()"> Finishing... @@ -99,20 +99,20 @@ ng-bind="main.state.getFlashState().percentage + '% Validating...'"> -