mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-24 03:36:36 +00:00
Move burn state to ImageWriterService
Previously, the burn state lived in the controller, however if the user moved to another page (the settings page for example) and then returned, the progress state would be lost, leading to a broken progress bar. Fixes: https://github.com/resin-io/etcher/issues/190
This commit is contained in:
parent
6367dd8a57
commit
793001e133
@ -35,6 +35,7 @@ require('./browser/modules/settings');
|
|||||||
require('./browser/modules/drive-scanner');
|
require('./browser/modules/drive-scanner');
|
||||||
require('./browser/modules/image-writer');
|
require('./browser/modules/image-writer');
|
||||||
require('./browser/modules/path');
|
require('./browser/modules/path');
|
||||||
|
require('./browser/modules/notifier');
|
||||||
require('./browser/modules/analytics');
|
require('./browser/modules/analytics');
|
||||||
|
|
||||||
const app = angular.module('Etcher', [
|
const app = angular.module('Etcher', [
|
||||||
@ -47,6 +48,7 @@ const app = angular.module('Etcher', [
|
|||||||
'Etcher.settings',
|
'Etcher.settings',
|
||||||
'Etcher.drive-scanner',
|
'Etcher.drive-scanner',
|
||||||
'Etcher.image-writer',
|
'Etcher.image-writer',
|
||||||
|
'Etcher.notifier',
|
||||||
'Etcher.analytics'
|
'Etcher.analytics'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -74,6 +76,8 @@ app.config(function($stateProvider, $urlRouterProvider) {
|
|||||||
app.controller('AppController', function(
|
app.controller('AppController', function(
|
||||||
$q,
|
$q,
|
||||||
$state,
|
$state,
|
||||||
|
$scope,
|
||||||
|
NotifierService,
|
||||||
DriveScannerService,
|
DriveScannerService,
|
||||||
SelectionStateService,
|
SelectionStateService,
|
||||||
ImageWriterService,
|
ImageWriterService,
|
||||||
@ -87,12 +91,16 @@ app.controller('AppController', function(
|
|||||||
AnalyticsService.logEvent('Restart');
|
AnalyticsService.logEvent('Restart');
|
||||||
|
|
||||||
if (!this.writer.isBurning()) {
|
if (!this.writer.isBurning()) {
|
||||||
this.state = {
|
this.writer.resetState();
|
||||||
progress: 0,
|
|
||||||
percentage: 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotifierService.subscribe($scope, 'image-writer:state', function(state) {
|
||||||
|
AnalyticsService.log(`Progress: ${state.progress}% at ${state.speed} MB/s`);
|
||||||
|
|
||||||
|
// Show progress inline in operating system task bar
|
||||||
|
currentWindow.setProgressBar(state.progress / 100);
|
||||||
|
});
|
||||||
|
|
||||||
this.scanner.start(2000).on('scan', function(drives) {
|
this.scanner.start(2000).on('scan', function(drives) {
|
||||||
|
|
||||||
// Notice we only autoselect the drive if there is an image,
|
// Notice we only autoselect the drive if there is an image,
|
||||||
@ -183,14 +191,7 @@ app.controller('AppController', function(
|
|||||||
device: drive.device
|
device: drive.device
|
||||||
});
|
});
|
||||||
|
|
||||||
return self.writer.burn(image, drive, function(state) {
|
return self.writer.burn(image, drive).then(function() {
|
||||||
self.state = state;
|
|
||||||
AnalyticsService.log(`Progress: ${self.state.progress}% at ${self.state.speed} MB/s`);
|
|
||||||
|
|
||||||
// Show progress inline in operating system task bar
|
|
||||||
currentWindow.setProgressBar(self.state.progress / 100);
|
|
||||||
|
|
||||||
}).then(function() {
|
|
||||||
AnalyticsService.logEvent('Done');
|
AnalyticsService.logEvent('Done');
|
||||||
$state.go('success');
|
$state.go('success');
|
||||||
}).catch(dialog.showError).finally(function() {
|
}).catch(dialog.showError).finally(function() {
|
||||||
|
@ -30,14 +30,39 @@ if (window.mocha) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
require('./settings');
|
require('./settings');
|
||||||
|
require('./notifier');
|
||||||
const imageWriter = angular.module('Etcher.image-writer', [
|
const imageWriter = angular.module('Etcher.image-writer', [
|
||||||
'Etcher.settings'
|
'Etcher.settings',
|
||||||
|
'Etcher.notifier'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
imageWriter.service('ImageWriterService', function($q, $timeout, SettingsService) {
|
imageWriter.service('ImageWriterService', function($q, $timeout, SettingsService, NotifierService) {
|
||||||
let self = this;
|
let self = this;
|
||||||
let burning = false;
|
let burning = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Reset burn state
|
||||||
|
* @function
|
||||||
|
* @public
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ImageWriterService.resetState();
|
||||||
|
*/
|
||||||
|
this.resetState = function() {
|
||||||
|
self.state = {
|
||||||
|
progress: 0,
|
||||||
|
speed: 0
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Burn progress state
|
||||||
|
* @type Object
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
this.state = {};
|
||||||
|
this.resetState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Check if currently burning
|
* @summary Check if currently burning
|
||||||
* @function
|
* @function
|
||||||
@ -102,11 +127,10 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsService
|
|||||||
* @public
|
* @public
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* This function will update `state.progress` with the current writing percentage.
|
* This function will update `ImageWriterService.state` with the current writing state.
|
||||||
*
|
*
|
||||||
* @param {String} image - image path
|
* @param {String} image - image path
|
||||||
* @param {Object} drive - drive
|
* @param {Object} drive - drive
|
||||||
* @param {Function} onProgress - in progress callback (state)
|
|
||||||
*
|
*
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*
|
*
|
||||||
@ -117,7 +141,7 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsService
|
|||||||
* console.log('Write completed!');
|
* console.log('Write completed!');
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
this.burn = function(image, drive, onProgress) {
|
this.burn = function(image, drive) {
|
||||||
if (self.isBurning()) {
|
if (self.isBurning()) {
|
||||||
return $q.reject(new Error('There is already a burn in progress'));
|
return $q.reject(new Error('There is already a burn in progress'));
|
||||||
}
|
}
|
||||||
@ -129,13 +153,14 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsService
|
|||||||
// Safely bring the state to the world of Angular
|
// Safely bring the state to the world of Angular
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
|
|
||||||
return onProgress({
|
self.state = {
|
||||||
progress: Math.floor(state.percentage),
|
progress: Math.floor(state.percentage),
|
||||||
|
|
||||||
// Transform bytes to megabytes preserving only two decimal places
|
// Transform bytes to megabytes preserving only two decimal places
|
||||||
speed: Math.floor(state.speed / 1e+6 * 100) / 100 || 0
|
speed: Math.floor(state.speed / 1e+6 * 100) / 100 || 0
|
||||||
|
};
|
||||||
|
|
||||||
});
|
NotifierService.emit('image-writer:state', self.state);
|
||||||
});
|
});
|
||||||
|
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
|
@ -56,17 +56,17 @@
|
|||||||
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">3</hero-badge>
|
<hero-badge class="block space-vertical-medium" ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">3</hero-badge>
|
||||||
|
|
||||||
<div class="space-vertical-large">
|
<div class="space-vertical-large">
|
||||||
<hero-progress-button percentage="{{ app.state.progress }}" ng-attr-active="{{ app.writer.isBurning() }}"
|
<hero-progress-button percentage="{{ app.writer.state.progress }}" ng-attr-active="{{ app.writer.isBurning() }}"
|
||||||
ng-click="app.burn(app.selection.getImage(), app.selection.getDrive())"
|
ng-click="app.burn(app.selection.getImage(), app.selection.getDrive())"
|
||||||
ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">
|
ng-disabled="!app.selection.hasImage() || !app.selection.hasDrive()">
|
||||||
<span ng-show="app.state.progress == 100 && app.writer.isBurning()">Finishing...</span>
|
<span ng-show="app.writer.state.progress == 100 && app.writer.isBurning()">Finishing...</span>
|
||||||
<span ng-show="app.state.progress == 0 && !app.writer.isBurning()">Burn!</span>
|
<span ng-show="app.writer.state.progress == 0 && !app.writer.isBurning()">Burn!</span>
|
||||||
<span ng-show="app.state.progress == 0 && app.writer.isBurning() && !app.state.speed">Starting...</span>
|
<span ng-show="app.writer.state.progress == 0 && app.writer.isBurning() && !app.writer.state.speed">Starting...</span>
|
||||||
<span ng-show="app.state.speed && app.state.progress != 100"
|
<span ng-show="app.writer.state.speed && app.writer.state.progress != 100"
|
||||||
ng-bind="app.state.progress + '% '"></span>
|
ng-bind="app.writer.state.progress + '% '"></span>
|
||||||
</hero-progress-button>
|
</hero-progress-button>
|
||||||
|
|
||||||
<p class="step-footer" ng-bind="app.state.speed.toFixed(2) + ' MB/s'" ng-show="app.state.speed && app.state.progress != 100"></p>
|
<p class="step-footer" ng-bind="app.writer.state.speed.toFixed(2) + ' MB/s'" ng-show="app.writer.state.speed && app.writer.state.progress != 100"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,6 +23,35 @@ describe('Browser: ImageWriter', function() {
|
|||||||
ImageWriterService = _ImageWriterService_;
|
ImageWriterService = _ImageWriterService_;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe('.state', function() {
|
||||||
|
|
||||||
|
it('should be reset by default', function() {
|
||||||
|
m.chai.expect(ImageWriterService.state).to.deep.equal({
|
||||||
|
progress: 0,
|
||||||
|
speed: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.resetState()', function() {
|
||||||
|
|
||||||
|
it('should be able to reset the state', function() {
|
||||||
|
ImageWriterService.state = {
|
||||||
|
progress: 50,
|
||||||
|
speed: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
ImageWriterService.resetState();
|
||||||
|
|
||||||
|
m.chai.expect(ImageWriterService.state).to.deep.equal({
|
||||||
|
progress: 0,
|
||||||
|
speed: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('.isBurning()', function() {
|
describe('.isBurning()', function() {
|
||||||
|
|
||||||
it('should return false by default', function() {
|
it('should return false by default', function() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user