feat: display upload speed and time left (#34)

This commit is contained in:
sigoden 2022-06-11 12:34:03 +08:00 committed by GitHub
parent 99f0de6ca0
commit b3890ea094
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 8 deletions

View file

@ -93,6 +93,11 @@ body {
display: none; display: none;
} }
.upload-status span {
width: 70px;
display: inline-block;
}
.main { .main {
padding: 0 1em; padding: 0 1em;
} }

View file

@ -36,7 +36,7 @@
<thead> <thead>
<tr> <tr>
<th class="cell-name">Name</th> <th class="cell-name">Name</th>
<th class="cell-status">Status</th> <th class="cell-status">Speed - Progress - Time Left</th>
</tr> </tr>
</thead> </thead>
</table> </table>

View file

@ -52,6 +52,14 @@ class Uploader {
* @type Element * @type Element
*/ */
$uploadStatus; $uploadStatus;
/**
* @type number
*/
uploaded = 0;
/**
* @type number
*/
lastUptime = 0;
static globalIdx = 0; static globalIdx = 0;
constructor(file, dirs) { constructor(file, dirs) {
this.name = [...dirs, file.name].join("/"); this.name = [...dirs, file.name].join("/");
@ -68,11 +76,12 @@ class Uploader {
<div>${getSvg("File")}</div> <div>${getSvg("File")}</div>
<a href="${url}">${name}</a> <a href="${url}">${name}</a>
</td> </td>
<td class="cell-status" id="uploadStatus${idx}"></td> <td class="cell-status upload-status" id="uploadStatus${idx}"></td>
</tr>`); </tr>`);
$uploadersTable.classList.remove("hidden"); $uploadersTable.classList.remove("hidden");
$emptyFolder.classList.add("hidden"); $emptyFolder.classList.add("hidden");
this.$uploadStatus = document.getElementById(`uploadStatus${idx}`); this.$uploadStatus = document.getElementById(`uploadStatus${idx}`);
this.lastUptime = Date.now();
const ajax = new XMLHttpRequest(); const ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", e => this.progress(e), false); ajax.upload.addEventListener("progress", e => this.progress(e), false);
@ -92,8 +101,15 @@ class Uploader {
} }
progress(event) { progress(event) {
const percent = (event.loaded / event.total) * 100; let now = Date.now();
this.$uploadStatus.innerHTML = `${percent.toFixed(2)}%`; let speed = (event.loaded - this.uploaded) / (now - this.lastUptime) * 1000;
let [speedValue, speedUnit] = formatSize(speed);
const speedText = `${speedValue}${speedUnit.toLowerCase()}/s`;
const progress = formatPercent((event.loaded / event.total) * 100);
const duration = formatDuration((event.total - event.loaded) / speed)
this.$uploadStatus.innerHTML = `<span>${speedText}</span><span>${progress}</span><span>${duration}</span>`;
this.uploaded = event.loaded;
this.lastUptime = now;
} }
complete() { complete() {
@ -174,7 +190,7 @@ function addPath(file, index) {
<a href="${url}" title="${file.name}">${file.name}</a> <a href="${url}" title="${file.name}">${file.name}</a>
</td> </td>
<td class="cell-mtime">${formatMtime(file.mtime)}</td> <td class="cell-mtime">${formatMtime(file.mtime)}</td>
<td class="cell-size">${formatSize(file.size)}</td> <td class="cell-size">${formatSize(file.size).join(" ")}</td>
${actionCell} ${actionCell}
</tr>`) </tr>`)
} }
@ -284,11 +300,27 @@ function padZero(value, size) {
} }
function formatSize(size) { function formatSize(size) {
if (!size) return "" if (!size) return []
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
if (size == 0) return '0 Byte'; if (size == 0) return [0, "Byte"];
const i = parseInt(Math.floor(Math.log(size) / Math.log(1024))); const i = parseInt(Math.floor(Math.log(size) / Math.log(1024)));
return Math.round(size / Math.pow(1024, i), 2) + ' ' + sizes[i]; return [Math.round(size / Math.pow(1024, i), 2), sizes[i]];
}
function formatDuration(seconds) {
seconds = Math.ceil(seconds);
let h = Math.floor(seconds / 3600);
let m = Math.floor((seconds - h * 3600) / 60);
let s = seconds - h * 3600 - m * 60
return `${padZero(h, 2)}:${padZero(m, 2)}:${padZero(s, 2)}`;
}
function formatPercent(precent) {
if (precent > 10) {
return precent.toFixed(1) + "%";
} else {
return precent.toFixed(2) + "%";
}
} }
function ready() { function ready() {