From 96fa273229e9857571700c9cff13790fd49818ce Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Mon, 28 Jun 2021 12:01:18 +0200 Subject: [PATCH] Show global progress while uploading --- svelte/src/admin_panel/Home.svelte | 6 +- svelte/src/home_page/HomePage.svelte | 85 ++++++++++++++++++- svelte/src/home_page/UploadProgressBar.svelte | 44 ++++++---- 3 files changed, 114 insertions(+), 21 deletions(-) diff --git a/svelte/src/admin_panel/Home.svelte b/svelte/src/admin_panel/Home.svelte index d8b40fa..fce2a78 100644 --- a/svelte/src/admin_panel/Home.svelte +++ b/svelte/src/admin_panel/Home.svelte @@ -184,7 +184,7 @@ onDestroy(() => { {peer.load_1_min} {peer.load_5_min} {peer.load_15_min} - {formatDuration(peer.latency)} + {formatDuration(peer.latency, 3)} {formatDataVolume(peer.free_space, 3)} {formatDataVolume(peer.min_free_space, 3)} @@ -251,8 +251,8 @@ onDestroy(() => { {q.query_name} {q.calls} - {formatDuration(q.average_duration)} - {formatDuration(q.total_duration)} + {formatDuration(q.average_duration, 3)} + {formatDuration(q.total_duration, 3)} {#each q.callers as caller} {caller.count}x {caller.name}
diff --git a/svelte/src/home_page/HomePage.svelte b/svelte/src/home_page/HomePage.svelte index 82acf3a..6f5d77c 100644 --- a/svelte/src/home_page/HomePage.svelte +++ b/svelte/src/home_page/HomePage.svelte @@ -6,6 +6,7 @@ import Facebook from "../icons/Facebook.svelte" import Reddit from "../icons/Reddit.svelte" import Twitter from "../icons/Twitter.svelte" import Tumblr from "../icons/Tumblr.svelte" +import { formatDataVolume, formatDuration } from "../util/Formatting.svelte"; // === UPLOAD LOGIC === @@ -55,6 +56,9 @@ const upload_files = async (files) => { status: "queued", component: null, id: "", + total_size: files[i].size, + loaded_size: 0, + transfer_rate: 0, on_finished: finish_upload, }) } @@ -82,9 +86,20 @@ const start_upload = () => { if (active_uploads === 0 && finished_count != 0) { state = "finished" + + if (stats_interval !== null) { + clearInterval(stats_interval) + stats_interval = null + stats_finished() + } + uploads_finished() } else { state = "uploading" + + if (stats_interval === null) { + stats_interval = setInterval(stats_update, 50) + } } } @@ -93,6 +108,43 @@ const finish_upload = (file) => { start_upload() } +let stats_interval = null +let progress_bar_outer +let progress_bar_inner +let start_time = 0 +let total_progress = 0 +let total_size = 0 +let total_loaded = 0 +let total_rate = 0 +let remaining_time = 0 +const stats_update = () => { + if (start_time === 0) { + start_time = new Date().getTime() + } + + total_size = 0 + total_loaded = 0 + total_rate = 0 + for (let i = 0; i < upload_queue.length; i++) { + total_size += upload_queue[i].total_size + total_loaded += upload_queue[i].loaded_size + total_rate += upload_queue[i].transfer_rate + } + + total_progress = total_loaded / total_size + + let elapsed_time = new Date().getTime() - start_time + remaining_time = (elapsed_time/total_progress) - elapsed_time + + progress_bar_inner.style.width = (total_progress * 100) + "%" +} + +const stats_finished = () => { + start_time = 0 + total_loaded = total_size + total_rate = 0 +} + // === SHARING BUTTONS === let navigator_share = !!(window.navigator && window.navigator.share) @@ -350,12 +402,22 @@ const keydown = (e) => { content policy.

-

+
2 Wait for the files to finish uploading +
+
+
Size: {formatDataVolume(total_size, 3)}
+
Progress: {(total_progress*100).toPrecision(3)}%
+
ETA {formatDuration(remaining_time, 0)}
+
Rate: {formatDataVolume(total_rate, 3)}/s
+
+
+
+
Gimme gimme gimme!
@@ -473,6 +535,27 @@ const keydown = (e) => { box-sizing: border-box; vertical-align: middle; } +.stats_box { + display: inline-grid; + grid-template-columns: 25% 25% 25% 25%; + width: 100%; + text-align: center; + font-family: sans-serif, monospace; +} +@media (max-width: 1000px) { + .stats_box { + grid-template-columns: 50% 50%; + } +} +.progress_bar_outer { + width: 100%; + height: 3px; +} +.progress_bar_inner { + background-color: var(--highlight_color); + height: 100%; + width: 0; +} .social_buttons { margin: 5px; diff --git a/svelte/src/home_page/UploadProgressBar.svelte b/svelte/src/home_page/UploadProgressBar.svelte index 747ca9c..2bf6e9c 100644 --- a/svelte/src/home_page/UploadProgressBar.svelte +++ b/svelte/src/home_page/UploadProgressBar.svelte @@ -3,44 +3,49 @@ import { domain_url } from "../util/Util.svelte" import { formatDataVolume, formatDuration} from "../util/Formatting.svelte" export let job = {} -let loaded_size -let total_size let file_button let tries = 0 let start_time = 0 let remaining_time = 0 +let statsInterval = null +let progress = 0 let last_progress_time = 0 let last_loaded_size = 0 -let transfer_rate = 0 const on_progress = () => { - let now = new Date().getTime() + if (job.loaded_size === 0 || job.total_size === 0) { + return + } - let prog = loaded_size / total_size + let now = new Date().getTime() + progress = job.loaded_size / job.total_size let elapsed_time = now - start_time - remaining_time = (elapsed_time/prog) - elapsed_time + remaining_time = (elapsed_time/progress) - elapsed_time // Calculate transfer rate if (last_progress_time != 0) { - let new_rate = (1000 / (now - last_progress_time)) * (loaded_size - last_loaded_size) + let new_rate = (1000 / (now - last_progress_time)) * (job.loaded_size - last_loaded_size) // Apply smoothing by mixing it with the previous number 10:1 - transfer_rate = (transfer_rate * 0.9) + (new_rate * 0.1) + job.transfer_rate = Math.floor((job.transfer_rate * 0.9) + (new_rate * 0.1)) } last_progress_time = now - last_loaded_size = loaded_size + last_loaded_size = job.loaded_size file_button.style.background = 'linear-gradient(' + 'to right, ' + 'var(--layer_3_color) 0%, ' + - 'var(--highlight_color) ' + (prog * 100) + '%, ' + - 'var(--layer_3_color) ' + ((prog * 100) + 1) + '%)' + 'var(--highlight_color) ' + (progress * 100) + '%, ' + + 'var(--layer_3_color) ' + ((progress * 100) + 1) + '%)' } let href = null let target = null const on_success = (resp) => { + clearInterval(statsInterval) + job.transfer_rate = 0 + job.id = resp.id job.status = "finished" job.on_finished(job) @@ -56,6 +61,10 @@ const on_success = (resp) => { let error_id = "" let error_reason = "" const on_failure = (status, message) => { + clearInterval(statsInterval) + job.transfer_rate = 0 + job.loaded_size = job.total_size + error_id = status error_reason = message job.status = "error" @@ -67,6 +76,7 @@ const on_failure = (status, message) => { export const start = () => { start_time = new Date().getTime() + statsInterval = setInterval(on_progress, 50) // 20 FPS, plenty for stats let form = new FormData(); form.append('file', job.file, job.name); @@ -77,9 +87,8 @@ export const start = () => { xhr.upload.addEventListener("progress", evt => { if (evt.lengthComputable) { - loaded_size = evt.loaded - total_size = evt.total - on_progress() + job.loaded_size = evt.loaded + job.total_size = evt.total } }); @@ -171,13 +180,13 @@ const add_upload_history = id => { Queued... {:else if job.status === "uploading"}
- {((loaded_size/total_size)*100).toPrecision(3)}% + {(progress*100).toPrecision(3)}%
ETA {formatDuration(remaining_time, 0)}
- {formatDataVolume(transfer_rate, 3)}/s + {formatDataVolume(job.transfer_rate, 3)}/s
{:else if job.status === "finished"} @@ -243,6 +252,7 @@ const add_upload_history = id => { } .upload_task > .queue_body > .title { flex: 1 1 auto; + overflow: hidden; } .upload_task > .queue_body > .stats { flex: 0 0 auto; @@ -251,7 +261,7 @@ const add_upload_history = id => { height: 1.4em; border-top: 1px solid var(--layer_3_color_border); text-align: center; - font-family: 'monospace', sans-serif; + font-family: sans-serif, monospace; font-size: 0.9em; } .upload_task > .queue_body > .stats > .stat {