Skip to content

Commit

Permalink
feat(upload-core): add progress indicator for file scans
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob McGuinness committed Jan 17, 2018
1 parent dae9fd0 commit a84cc85
Showing 1 changed file with 90 additions and 9 deletions.
99 changes: 90 additions & 9 deletions packages/upload-core/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,77 @@ class Upload {
}

this.file = file;
this.percentage = 0;
this.options = Object.assign(options, defaults);
this.completed = false;
this.percentage = 0;
this.onError = [];
this.onSuccess = [];
this.onProgress = [];
this.bytesTotal = 0;
this.bytesSent = 0;
this.bytesScanned = 0;
this.timeoutID = undefined;
}

inStatusCategory(status, category) {
return status >= category && status < category + 100;
}

scan() {
const xhr = new window.XMLHttpRequest();

xhr.open('HEAD', this.upload.url, true);
xhr.setRequestHeader('Tus-Resumable', '1.0.0');
xhr.setRequestHeader('X-Client-ID', this.options.clientId);
xhr.setRequestHeader('X-XSRF-TOKEN', this.getToken());

xhr.onload = () => {
if (!this.inStatusCategory(xhr.status, 200)) {
this.onError.forEach(cb => cb(xhr));
return;
}

this.bytesScanned = parseInt(xhr.getResponseHeader('AV-Scan-Bytes'), 10);
this.percentage = this.getPercentage();
const result = xhr.getResponseHeader('AV-Scan-Result');

this.completed = true;
this.percentage = 100;
this.onSuccess.forEach(cb => cb());

if (result === 'accepted') {
this.completed = true;
this.percentage = 100;
const references = xhr.getResponseHeader('references');
if (references) {
this.references = JSON.parse(references);
}
this.onSuccess.forEach(cb => cb());
return;
}

if (result === 'rejected') {
clearTimeout(this.timeoutId);
this.onError.forEach(cb => cb(new Error('File upload rejected')));
return;
}

this.timeoutId = setTimeout(() => {
this.scan();
}, 50);
};

xhr.onerror = err => {
this.onError.forEach(cb => cb(err));
};

xhr.send(null);
}

getPercentage() {
const processedBytes = this.bytesSent + this.bytesScanned;
const combinedTotalBytes = this.bytesTotal * 2;
return processedBytes / combinedTotalBytes * 100;
}

getToken() {
Expand Down Expand Up @@ -57,20 +122,36 @@ class Upload {
this.onError.forEach(cb => cb(err));
},
onProgress: (bytesSent, bytesTotal) => {
this.percentage = bytesSent / bytesTotal * 100;
this.bytesSent = bytesSent;
this.bytesTotal = bytesTotal;
this.onProgress.forEach(cb => cb(bytesSent, bytesTotal));
this.percentage = this.getPercentage();
this.onProgress.forEach(cb => cb());
},
onSuccess: () => {
const xhr = this.upload._xhr; // eslint-disable-line
this.percentage = 100;
this.completed = true;
const references = xhr.getResponseHeader('references');
if (references) {
this.references = JSON.parse(references);
this.bytesScanned =
parseInt(xhr.getResponseHeader('AV-Scan-Bytes'), 10) || 0;
this.percentage = this.getPercentage();
this.onProgress.forEach(cb => cb());

const result = xhr.getResponseHeader('AV-Scan-Result');
if (result === 'accepted') {
this.completed = true;
this.percentage = 100;
const references = xhr.getResponseHeader('references');
if (references) {
this.references = JSON.parse(references);
}
this.onSuccess.forEach(cb => cb());
return;
}
this.onSuccess.forEach(cb => cb());

if (result === 'rejected') {
this.onError.forEach(cb => cb(new Error('File upload rejected')));
return;
}

this.scan();
},
});

Expand Down

0 comments on commit a84cc85

Please sign in to comment.