Skip to content

Commit 707a1e2

Browse files
jrichter1dgolovin
authored andcommitted
Progress bars reflect real state
1 parent 5014660 commit 707a1e2

7 files changed

Lines changed: 78 additions & 69 deletions

File tree

browser/directives/progressBar.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ function progressBar() {
2727
<div>{{productDesc}}</div>
2828
</div>
2929
<div class="progress progress-label-top-right">
30-
<div class="progress-bar" role="progressbar" aria-valuenow="{{current}}" aria-valuemin="{{min}}" aria-valuemax="{{max}}" style="width: {{current}}%;">
30+
<div class="progress-bar" ng-class="{'progress-bar-striped active': status == 'Installing' || status == 'Setting up' || status.indexOf('Waiting') > -1}" role="progressbar" aria-valuenow="{{current}}" aria-valuemin="{{min}}" aria-valuemax="{{max}}"
31+
style="width: {{current}}%; animation: progress-bar-stripes 2s infinite steps(15);">
3132
<span>{{label}}</span>
3233
</div>
3334
</div>

browser/model/cdk.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,9 @@ class CDKInstall extends InstallableItem {
5252
downloadInstaller(progress, success, failure) {
5353
progress.setStatus('Downloading');
5454

55-
let downloadSize = 869598013;
56-
5755
let totalDownloads = 3;
5856

59-
this.downloader = new Downloader(progress, success, failure, downloadSize, totalDownloads);
57+
this.downloader = new Downloader(progress, success, failure, totalDownloads);
6058
let username = this.installerDataSvc.getUsername(),
6159
password = this.installerDataSvc.getPassword();
6260

browser/model/helpers/downloader.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ import Hash from './hash';
88
const remote = require('electron').remote;
99

1010
class Downloader {
11-
constructor(progress, success, failure, downloadSize = 0, totalDownloads = 1) {
12-
this.downloadSize = downloadSize;
11+
constructor(progress, success, failure, totalDownloads = 1) {
12+
this.downloadSize = 0;
1313
this.totalDownloads = totalDownloads;
14-
this.lastTime = 0;
14+
this.currentSize = 0;
1515
this.progress = progress;
1616
this.success = success;
1717
this.failure = failure;
1818
this.downloads = new Map();
1919
this.userAgentString = '';
20+
this.received = 0;
21+
this.lastTime = 0;
2022
if(remote) {
2123
this.userAgentString = remote.getCurrentWindow().webContents.session.getUserAgent();
2224
}
@@ -36,20 +38,23 @@ class Downloader {
3638
}
3739

3840
responseHandler(response) {
39-
if (this.downloadSize == 0) {
40-
let tempSize = response.headers['content-length'];
41-
if (tempSize !== undefined && tempSize > 0) {
42-
this.downloadSize = tempSize;
41+
let tempSize = response.headers['content-length'];
42+
if (tempSize !== undefined && parseInt(tempSize) > 0) {
43+
this.downloadSize += parseInt(tempSize);
44+
45+
if (++this.received == this.totalDownloads && this.progress.totalSize == 0) {
46+
this.progress.setTotalDownloadSize(this.downloadSize);
4347
}
4448
}
45-
this.progress.setTotalDownloadSize(this.downloadSize);
46-
this.lastTime = Date.now();
4749
}
4850

4951
dataHandler(data) {
50-
let current = Date.now();
51-
this.progress.downloaded(data.length, current - this.lastTime);
52-
this.lastTime = current;
52+
this.currentSize += data.length;
53+
54+
if (Date.now() - this.lastTime > 500) {
55+
this.progress.setCurrent(this.currentSize);
56+
this.lastTime = Date.now();
57+
}
5358
}
5459

5560
endHandler(stream) {
@@ -112,6 +117,9 @@ class Downloader {
112117
}
113118

114119
restartDownload() {
120+
this.downloadSize = 0;
121+
this.received = 0;
122+
this.currentSize = 0;
115123
this.progress.setStatus('Downloading');
116124
for (var [key, value] of this.downloads.entries()) {
117125
if (value['failure'] && value.failure) {

browser/model/vagrant.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ class VagrantInstall extends InstallableItem {
114114
if(this.isDownloadRequired() && this.selectedOption === "install") {
115115
// Need to download the file
116116
let writeStream = fs.createWriteStream(this.downloadedFile);
117-
let downloadSize = 199819264;
118-
this.downloader = new Downloader(progress, success, failure, downloadSize);
117+
this.downloader = new Downloader(progress, success, failure);
119118
this.downloader.setWriteStream(writeStream);
120119
this.downloader.download(this.downloadUrl,this.downloadedFile,this.sha256);
121120
} else {

browser/pages/install/controller.js

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class InstallController {
1111

1212
this.data = Object.create(null);
1313
for (var [key, value] of this.installerDataSvc.allInstallables().entries()) {
14-
let itemProgress = new ProgressState(value.getProductName(), value.getProductVersion(), value.getProductDesc(), value.getInstallTime(), this.$scope, this.$timeout);
14+
let itemProgress = new ProgressState(value.getProductName(), value.getProductVersion(), value.getProductDesc(), this.$scope, this.$timeout);
1515
Object.defineProperty(this.data, key, {
1616
enumerable: true,
1717
writable: true,
@@ -67,8 +67,6 @@ class InstallController {
6767
triggerInstall(installableKey, installableValue, progress) {
6868
this.installerDataSvc.startInstall(installableKey);
6969

70-
progress.installTrigger();
71-
7270
installableValue.install(progress,
7371
() => {
7472
this.installerDataSvc.installDone(progress,installableKey);
@@ -109,67 +107,59 @@ class InstallController {
109107
}
110108

111109
class ProgressState {
112-
constructor(productName, productVersion, productDesc, installTime, $scope, $timeout) {
110+
constructor(productName, productVersion, productDesc, $scope, $timeout) {
113111
this.productName = productName;
114112
this.productVersion = productVersion;
115113
this.productDesc = productDesc;
116-
this.installTime = installTime;
117-
this.$scope = $scope;
118114
this.$timeout = $timeout;
115+
this.$scope = $scope;
119116
this.current = 0;
120-
this.totalDownloadSize = 0;
121-
this.downloadedSize = 0;
122-
this.timeSpent = 0;
123-
this.timeSpentInstall = 0;
124-
this.lastInstallTime = 0;
125117
this.label = '';
126118
this.status = '';
127-
128-
}
129-
130-
setTotalDownloadSize(totalSize) {
131-
this.totalDownloadSize = totalSize;
132-
}
133-
134-
downloaded(amt, time) {
135-
this.downloadedSize += amt;
136-
this.timeSpent += time;
137-
if (time == 0) return;
138-
let rate = amt / time;
139-
let remainingDownloadTime = (this.totalDownloadSize - this.downloadedSize) / rate;
140-
this.setCurrent(Math.round((this.timeSpent / (this.timeSpent + (this.installTime * 1000) + remainingDownloadTime)) * 100));
141-
}
142-
143-
installTrigger() {
144-
this.lastInstallTime = Date.now();
145-
this.$timeout(this.installUpdate.bind(this), 10000);
119+
this.currentAmount = 0;
120+
this.totalSize = 0;
146121
}
147122

148-
installUpdate() {
149-
let now = Date.now();
150-
this.timeSpentInstall += (now - this.lastInstallTime);
151-
this.lastInstallTime = now;
152-
this.setCurrent(Math.round(((this.timeSpent + this.timeSpentInstall) / (this.timeSpent + (this.installTime * 1000))) * 100));
153-
154-
this.$timeout(this.installUpdate.bind(this), 5000);
123+
setTotalDownloadSize(size) {
124+
this.totalSize = size;
155125
}
156126

157127
setCurrent(newVal) {
158-
if (newVal > this.current && newVal < 100) {
159-
this.current = newVal;
160-
this.label = newVal + '%';
128+
if (newVal > this.currentAmount && newVal < this.totalSize) {
129+
this.currentAmount = newVal;
130+
this.current = Math.round(this.currentAmount / this.totalSize * 100)
131+
this.label = this.sizeInKB(this.currentAmount) + ' / ' + this.sizeInKB(this.totalSize) + ' KB (' + this.current + '%)';
132+
133+
this.$timeout(this.setCurrent.bind(this), 0);
161134
}
162135
}
163136

164137
setStatus(newStatus) {
138+
if (newStatus !== 'Downloading') {
139+
this.current = 100;
140+
this.label = '';
141+
} else {
142+
this.current = 0;
143+
this.label = 0 + '%';
144+
this.currentAmount = 0;
145+
this.totalSize = 0;
146+
}
165147
this.status = newStatus;
148+
149+
this.$timeout(() => {
150+
this.$scope.$apply();
151+
});
166152
}
167153

168154
setComplete() {
169155
this.current = 100;
170156
this.label = '100%';
171157
this.setStatus('Complete');
172158
}
159+
160+
sizeInKB(amount) {
161+
return Math.round(amount / 1024);
162+
}
173163
}
174164

175165
InstallController.$inject = ['$scope', '$timeout', 'installerDataSvc'];

browser/services/data.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ class InstallerDataService {
158158
}
159159

160160
this.startInstall(key);
161-
progress.installTrigger();
162161

163162
return item.install(progress,
164163
() => {

test/unit/model/helpers/downloader-test.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('Downloader', function() {
1717
setLabel: function (label) {},
1818
setComplete: function() {},
1919
setTotalDownloadSize: function(size) {},
20-
downloaded: function(amt, time) {}
20+
downloaded: function(amt, time) {},
2121
};
2222
let sandbox;
2323
let succ = function() {};
@@ -39,24 +39,38 @@ describe('Downloader', function() {
3939
it('responseHandler should set the total download size', function() {
4040
downloader = new Downloader(fakeProgress, function() {}, function() {});
4141
let response = { headers: { 'content-length': 1024 } };
42-
let spy = sandbox.spy(fakeProgress, 'setTotalDownloadSize');
4342

4443
downloader.responseHandler(response);
4544

4645
expect(downloader.downloadSize).to.equal(1024);
47-
expect(spy).to.have.been.calledOnce;
48-
expect(spy).to.have.been.calledWith(1024);
4946
});
5047

51-
it('dataHandler should update the progress', function() {
48+
it('dataHandler should update the progress once time threshold is reached', function() {
5249
downloader = new Downloader(fakeProgress, function() {}, function() {});
53-
let data = { length: 1024 };
54-
let spy = sandbox.spy(fakeProgress, 'downloaded');
50+
fakeProgress.totalSize = 1024;
51+
52+
let data = { length: 512 };
53+
let spy = sandbox.spy(fakeProgress, 'setCurrent');
5554

55+
downloader.received = 1;
5656
downloader.dataHandler(data);
5757

5858
expect(spy).to.have.been.calledOnce;
59-
expect(spy).to.have.been.calledWith(1024);
59+
expect(spy).to.have.been.calledWith(data.length);
60+
});
61+
62+
it('dataHandler should not update the progress before time threshold is reached', function() {
63+
downloader = new Downloader(fakeProgress, function() {}, function() {});
64+
fakeProgress.totalSize = 1024;
65+
66+
let data = { length: 512 };
67+
let spy = sandbox.spy(fakeProgress, 'setCurrent');
68+
69+
downloader.received = 1;
70+
downloader.lastTime = Date.now() + 9999999999;
71+
downloader.dataHandler(data);
72+
73+
expect(spy).not.called;
6074
});
6175

6276
it('errorHandler should close the stream', function() {
@@ -213,7 +227,7 @@ describe('Downloader', function() {
213227
let error = new Error('something bad happened');
214228

215229
let stream = new Writable();
216-
downloader = new Downloader(fakeProgress, function() {}, function() {}, 1, 2);
230+
downloader = new Downloader(fakeProgress, function() {}, function() {}, 2);
217231
downloader.setWriteStream(stream);
218232
let errorHandler = sandbox.stub(downloader, 'errorHandler');
219233
let successSpy = sandbox.spy(downloader, 'success');
@@ -232,7 +246,7 @@ describe('Downloader', function() {
232246
let error = new Error('something bad happened');
233247

234248
let stream = new Writable();
235-
downloader = new Downloader(fakeProgress, function() {}, function() {}, 1, 2);
249+
downloader = new Downloader(fakeProgress, function() {}, function() {}, 2);
236250
downloader.setWriteStream(stream);
237251
let successHandler = sandbox.stub(downloader, 'success');
238252
downloader.download(options);

0 commit comments

Comments
 (0)