Extract browser window progress into WindowProgressService

This commit is contained in:
Juan Cruz Viotti 2016-04-01 10:08:14 -04:00
parent 91400922cd
commit 832d6843df
4 changed files with 203 additions and 15 deletions

View File

@ -24,8 +24,6 @@ var angular = require('angular');
const _ = require('lodash'); const _ = require('lodash');
const electron = require('electron'); const electron = require('electron');
const dialog = electron.remote.require('./src/dialog'); const dialog = electron.remote.require('./src/dialog');
const BrowserWindow = electron.remote.BrowserWindow;
const currentWindow = BrowserWindow.fromId(1);
require('angular-ui-bootstrap'); require('angular-ui-bootstrap');
require('angular-ui-router'); require('angular-ui-router');
@ -40,6 +38,7 @@ require('./browser/components/progress-button/progress-button');
require('./browser/components/drive-selector'); require('./browser/components/drive-selector');
require('./browser/pages/finish/finish'); require('./browser/pages/finish/finish');
require('./browser/pages/settings/settings'); require('./browser/pages/settings/settings');
require('./browser/utils/window-progress/window-progress');
const app = angular.module('Etcher', [ const app = angular.module('Etcher', [
'ui.router', 'ui.router',
@ -62,7 +61,10 @@ const app = angular.module('Etcher', [
// Pages // Pages
'Etcher.Pages.Finish', 'Etcher.Pages.Finish',
'Etcher.Pages.Settings' 'Etcher.Pages.Settings',
// Utils
'Etcher.Utils.WindowProgress'
]); ]);
app.config(function($stateProvider, $urlRouterProvider) { app.config(function($stateProvider, $urlRouterProvider) {
@ -85,7 +87,8 @@ app.controller('AppController', function(
SelectionStateService, SelectionStateService,
ImageWriterService, ImageWriterService,
AnalyticsService, AnalyticsService,
DriveSelectorService DriveSelectorService,
WindowProgressService
) { ) {
let self = this; let self = this;
this.selection = SelectionStateService; this.selection = SelectionStateService;
@ -110,9 +113,7 @@ app.controller('AppController', function(
NotifierService.subscribe($scope, 'image-writer:state', function(state) { NotifierService.subscribe($scope, 'image-writer:state', function(state) {
AnalyticsService.log(`Progress: ${state.progress}% at ${state.speed} MB/s`); AnalyticsService.log(`Progress: ${state.progress}% at ${state.speed} MB/s`);
WindowProgressService.set(state.progress);
// 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) {
@ -213,13 +214,8 @@ app.controller('AppController', function(
return self.writer.burn(image, drive).then(function() { return self.writer.burn(image, drive).then(function() {
AnalyticsService.logEvent('Done'); AnalyticsService.logEvent('Done');
$state.go('success'); $state.go('success');
}).catch(dialog.showError).finally(function() { })
.catch(dialog.showError)
// Remove progress bar from task bar .finally(WindowProgressService.clear);
// Passing 0 or null/undefined doesn't do
// the trick for Electron for some reason.
currentWindow.setProgressBar(-1);
});
}; };
}); });

View File

@ -0,0 +1,73 @@
/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const electron = require('electron');
module.exports = function() {
const self = this;
/**
* @summary A reference to the current renderer Electron window
* @property
* @protected
*
* @description
* Since electron only has one renderer view, we can assume the
* current window is the one with id == 1.
*
* We expose this property to `this` for testability purposes.
*/
this.currentWindow = electron.remote.BrowserWindow.fromId(1);
/**
* @summary Set operating system window progress
* @function
* @public
*
* @description
* Show progress inline in operating system task bar
*
* @param {Number} percentage - percentage
*
* @example
* WindowProgressService.set(85);
*/
this.set = function(percentage) {
if (percentage > 100 || percentage < 0) {
throw new Error(`Invalid window progress percentage: ${percentage}`);
}
self.currentWindow.setProgressBar(percentage / 100);
};
/**
* @summary Clear the operating system window progress bar
* @function
* @public
*
* @example
* WindowProgressService.clear();
*/
this.clear = function() {
// Passing 0 or null/undefined doesn't work.
self.currentWindow.setProgressBar(-1);
};
};

View File

@ -0,0 +1,29 @@
/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
/**
* @module Etcher.Utils.WindowProgress
*
* The purpose of this module is to provide an easy way
* to interact with the operating system's window progress
* functionality, as described in Electron docs.
*/
const angular = require('angular');
const WindowProgress = angular.module('Etcher.Utils.WindowProgress', []);
WindowProgress.service('WindowProgressService', require('./services/window-progress'));

View File

@ -0,0 +1,90 @@
/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const m = require('mochainon');
const angular = require('angular');
require('angular-mocks');
require('../../../lib/browser/utils/window-progress/window-progress');
describe('Browser: WindowProgress', function() {
beforeEach(angular.mock.module('Etcher.Utils.WindowProgress'));
describe('WindowProgressService', function() {
let WindowProgressService;
beforeEach(angular.mock.inject(function(_WindowProgressService_) {
WindowProgressService = _WindowProgressService_;
}));
describe('given a stubbed current window', function() {
beforeEach(function() {
this.setProgressBarSpy = m.sinon.spy();
WindowProgressService.currentWindow = {
setProgressBar: this.setProgressBarSpy
};
});
describe('.set()', function() {
it('should translate 0-100 percentages to 0-1 ranges', function() {
WindowProgressService.set(85);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0.85);
});
it('should set 0 given 0', function() {
WindowProgressService.set(0);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(0);
});
it('should set 1 given 100', function() {
WindowProgressService.set(100);
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(1);
});
it('should throw if given a percentage higher than 100', function() {
m.chai.expect(function() {
WindowProgressService.set(101);
}).to.throw('Invalid window progress percentage: 101');
});
it('should throw if given a percentage less than 0', function() {
m.chai.expect(function() {
WindowProgressService.set(-1);
}).to.throw('Invalid window progress percentage: -1');
});
});
describe('.clear()', function() {
it('should set -1', function() {
WindowProgressService.clear();
m.chai.expect(this.setProgressBarSpy).to.have.been.calledWith(-1);
});
});
});
});
});