Replace animated background for progress bar on home page
This commit is contained in:
@@ -67,12 +67,12 @@
|
|||||||
.feat_table > div > div.round_br { border-bottom-right-radius: 0.5em; }
|
.feat_table > div > div.round_br { border-bottom-right-radius: 0.5em; }
|
||||||
.feat_table > div > div.round_bl { border-bottom-left-radius: 0.5em; }
|
.feat_table > div > div.round_bl { border-bottom-left-radius: 0.5em; }
|
||||||
|
|
||||||
{{template `modal.css`}}
|
{{ template `modal.css` }}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>window.api_endpoint = '{{.APIEndpoint}}';</script>
|
<script>window.api_endpoint = '{{.APIEndpoint}}';</script>
|
||||||
<link rel='stylesheet' href='/res/svelte/home_page.css'>
|
<link rel='stylesheet' href='/res/svelte/home_page.css?v5'>
|
||||||
<script defer src='/res/svelte/home_page.js'></script>
|
<script defer src='/res/svelte/home_page.js?v5'></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{template "page_top" .}}
|
{{template "page_top" .}}
|
||||||
|
@@ -58,7 +58,6 @@ const upload_files = async (files) => {
|
|||||||
id: "",
|
id: "",
|
||||||
total_size: files[i].size,
|
total_size: files[i].size,
|
||||||
loaded_size: 0,
|
loaded_size: 0,
|
||||||
transfer_rate: 0,
|
|
||||||
on_finished: finish_upload,
|
on_finished: finish_upload,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -98,7 +97,7 @@ const start_upload = () => {
|
|||||||
state = "uploading"
|
state = "uploading"
|
||||||
|
|
||||||
if (stats_interval === null) {
|
if (stats_interval === null) {
|
||||||
stats_interval = setInterval(stats_update, 50)
|
stats_interval = setInterval(stats_update, stats_interval_ms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,12 +108,14 @@ const finish_upload = (file) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let stats_interval = null
|
let stats_interval = null
|
||||||
|
let stats_interval_ms = 500
|
||||||
let progress_bar_outer
|
let progress_bar_outer
|
||||||
let progress_bar_inner
|
let progress_bar_inner
|
||||||
let start_time = 0
|
let start_time = 0
|
||||||
let total_progress = 0
|
let total_progress = 0
|
||||||
let total_size = 0
|
let total_size = 0
|
||||||
let total_loaded = 0
|
let total_loaded = 0
|
||||||
|
let last_total_loaded = 0
|
||||||
let total_rate = 0
|
let total_rate = 0
|
||||||
let remaining_time = 0
|
let remaining_time = 0
|
||||||
const stats_update = () => {
|
const stats_update = () => {
|
||||||
@@ -122,26 +123,31 @@ const stats_update = () => {
|
|||||||
start_time = new Date().getTime()
|
start_time = new Date().getTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get total size of upload queue and size of finished uploads
|
||||||
total_size = 0
|
total_size = 0
|
||||||
total_loaded = 0
|
total_loaded = 0
|
||||||
total_rate = 0
|
|
||||||
for (let i = 0; i < upload_queue.length; i++) {
|
for (let i = 0; i < upload_queue.length; i++) {
|
||||||
total_size += upload_queue[i].total_size
|
total_size += upload_queue[i].total_size
|
||||||
total_loaded += upload_queue[i].loaded_size
|
total_loaded += upload_queue[i].loaded_size
|
||||||
total_rate += upload_queue[i].transfer_rate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
total_progress = total_loaded / total_size
|
total_progress = total_loaded / total_size
|
||||||
|
|
||||||
|
// Calculate ETA by estimating the total time and subtracting the elapsed time
|
||||||
let elapsed_time = new Date().getTime() - start_time
|
let elapsed_time = new Date().getTime() - start_time
|
||||||
remaining_time = (elapsed_time/total_progress) - elapsed_time
|
remaining_time = (elapsed_time/total_progress) - elapsed_time
|
||||||
|
|
||||||
|
// Calculate the rate by comparing the current progress with the last iteration
|
||||||
|
total_rate = (1000 / stats_interval_ms) * (total_loaded - last_total_loaded)
|
||||||
|
last_total_loaded = total_loaded
|
||||||
|
|
||||||
progress_bar_inner.style.width = (total_progress * 100) + "%"
|
progress_bar_inner.style.width = (total_progress * 100) + "%"
|
||||||
}
|
}
|
||||||
|
|
||||||
const stats_finished = () => {
|
const stats_finished = () => {
|
||||||
start_time = 0
|
start_time = 0
|
||||||
total_loaded = total_size
|
total_loaded = total_size
|
||||||
|
total_progress = 1
|
||||||
|
progress_bar_inner.style.width = "100%"
|
||||||
total_rate = 0
|
total_rate = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,10 +414,10 @@ const keydown = (e) => {
|
|||||||
<span class="instruction_text">Wait for the files to finish uploading</span>
|
<span class="instruction_text">Wait for the files to finish uploading</span>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="stats_box">
|
<div class="stats_box">
|
||||||
<div>Size: {formatDataVolume(total_size, 3)}</div>
|
<div>Size {formatDataVolume(total_size, 3)}</div>
|
||||||
<div>Progress: {(total_progress*100).toPrecision(3)}%</div>
|
<div>Progress {(total_progress*100).toPrecision(3)}%</div>
|
||||||
<div>ETA {formatDuration(remaining_time, 0)}</div>
|
<div>ETA {formatDuration(remaining_time, 0)}</div>
|
||||||
<div>Rate: {formatDataVolume(total_rate, 3)}/s</div>
|
<div>Rate {formatDataVolume(total_rate, 3)}/s</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -555,6 +561,8 @@ const keydown = (e) => {
|
|||||||
background-color: var(--highlight_color);
|
background-color: var(--highlight_color);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 0;
|
width: 0;
|
||||||
|
transition: width 0.5s;
|
||||||
|
transition-timing-function: linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
.social_buttons {
|
.social_buttons {
|
||||||
|
@@ -4,47 +4,45 @@ import { formatDataVolume, formatDuration} from "../util/Formatting.svelte"
|
|||||||
|
|
||||||
export let job = {}
|
export let job = {}
|
||||||
let file_button
|
let file_button
|
||||||
|
let progress_bar
|
||||||
let tries = 0
|
let tries = 0
|
||||||
let start_time = 0
|
let start_time = 0
|
||||||
let remaining_time = 0
|
let remaining_time = 0
|
||||||
|
|
||||||
let statsInterval = null
|
let stats_interval = null
|
||||||
|
let stats_interval_ms = 300
|
||||||
let progress = 0
|
let progress = 0
|
||||||
let last_progress_time = 0
|
|
||||||
let last_loaded_size = 0
|
let last_loaded_size = 0
|
||||||
|
let transfer_rate = 0
|
||||||
const on_progress = () => {
|
const on_progress = () => {
|
||||||
if (job.loaded_size === 0 || job.total_size === 0) {
|
if (job.loaded_size === 0 || job.total_size === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let now = new Date().getTime()
|
|
||||||
progress = job.loaded_size / job.total_size
|
progress = job.loaded_size / job.total_size
|
||||||
let elapsed_time = now - start_time
|
let elapsed_time = new Date().getTime() - start_time
|
||||||
remaining_time = (elapsed_time/progress) - elapsed_time
|
remaining_time = (elapsed_time/progress) - elapsed_time
|
||||||
|
|
||||||
// Calculate transfer rate
|
// Calculate transfer rate, apply smoothing by mixing it with the previous
|
||||||
if (last_progress_time != 0) {
|
// rate ten to one
|
||||||
let new_rate = (1000 / (now - last_progress_time)) * (job.loaded_size - last_loaded_size)
|
transfer_rate = Math.floor(
|
||||||
|
(transfer_rate * 0.9) +
|
||||||
|
(((1000 / stats_interval_ms) * (job.loaded_size - last_loaded_size)) * 0.1)
|
||||||
|
)
|
||||||
|
|
||||||
// Apply smoothing by mixing it with the previous number 10:1
|
|
||||||
job.transfer_rate = Math.floor((job.transfer_rate * 0.9) + (new_rate * 0.1))
|
|
||||||
}
|
|
||||||
|
|
||||||
last_progress_time = now
|
|
||||||
last_loaded_size = job.loaded_size
|
last_loaded_size = job.loaded_size
|
||||||
|
|
||||||
file_button.style.background = 'linear-gradient(' +
|
progress_bar.style.width = (progress * 100) + "%"
|
||||||
'to right, ' +
|
|
||||||
'var(--layer_3_color) 0%, ' +
|
|
||||||
'var(--highlight_color) ' + (progress * 100) + '%, ' +
|
|
||||||
'var(--layer_3_color) ' + ((progress * 100) + 1) + '%)'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let href = null
|
let href = null
|
||||||
let target = null
|
let target = null
|
||||||
const on_success = (resp) => {
|
const on_success = (resp) => {
|
||||||
clearInterval(statsInterval)
|
clearInterval(stats_interval)
|
||||||
job.transfer_rate = 0
|
stats_interval = null
|
||||||
|
transfer_rate = 0
|
||||||
|
job.loaded_size = job.total_size
|
||||||
|
job.file = null // Delete reference to file to free memory
|
||||||
|
|
||||||
job.id = resp.id
|
job.id = resp.id
|
||||||
job.status = "finished"
|
job.status = "finished"
|
||||||
@@ -56,27 +54,31 @@ const on_success = (resp) => {
|
|||||||
target = "_blank"
|
target = "_blank"
|
||||||
|
|
||||||
file_button.style.background = 'var(--layer_3_color)'
|
file_button.style.background = 'var(--layer_3_color)'
|
||||||
|
progress_bar.style.width = "100%"
|
||||||
}
|
}
|
||||||
|
|
||||||
let error_id = ""
|
let error_id = ""
|
||||||
let error_reason = ""
|
let error_reason = ""
|
||||||
const on_failure = (status, message) => {
|
const on_failure = (status, message) => {
|
||||||
clearInterval(statsInterval)
|
clearInterval(stats_interval)
|
||||||
job.transfer_rate = 0
|
stats_interval = null
|
||||||
|
transfer_rate = 0
|
||||||
job.loaded_size = job.total_size
|
job.loaded_size = job.total_size
|
||||||
|
job.file = null // Delete reference to file to free memory
|
||||||
|
|
||||||
error_id = status
|
error_id = status
|
||||||
error_reason = message
|
error_reason = message
|
||||||
job.status = "error"
|
job.status = "error"
|
||||||
file_button.style.background = 'var(--danger_color)'
|
file_button.style.background = 'var(--danger_color)'
|
||||||
file_button.style.color = 'var(--highlight_text_color)'
|
file_button.style.color = 'var(--highlight_text_color)'
|
||||||
|
progress_bar.style.width = "0"
|
||||||
|
|
||||||
job.on_finished(job)
|
job.on_finished(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const start = () => {
|
export const start = () => {
|
||||||
start_time = new Date().getTime()
|
start_time = new Date().getTime()
|
||||||
statsInterval = setInterval(on_progress, 50) // 20 FPS, plenty for stats
|
stats_interval = setInterval(on_progress, stats_interval_ms)
|
||||||
|
|
||||||
let form = new FormData();
|
let form = new FormData();
|
||||||
form.append('file', job.file, job.name);
|
form.append('file', job.file, job.name);
|
||||||
@@ -156,6 +158,7 @@ const add_upload_history = id => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a bind:this={file_button} class="upload_task" {href} {target}>
|
<a bind:this={file_button} class="upload_task" {href} {target}>
|
||||||
|
<div class="top_half">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
{#if job.status === "queued"}
|
{#if job.status === "queued"}
|
||||||
<i class="icon">cloud_queue</i>
|
<i class="icon">cloud_queue</i>
|
||||||
@@ -186,7 +189,7 @@ const add_upload_history = id => {
|
|||||||
ETA {formatDuration(remaining_time, 0)}
|
ETA {formatDuration(remaining_time, 0)}
|
||||||
</div>
|
</div>
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
{formatDataVolume(job.transfer_rate, 3)}/s
|
{formatDataVolume(transfer_rate, 3)}/s
|
||||||
</div>
|
</div>
|
||||||
{:else if job.status === "finished"}
|
{:else if job.status === "finished"}
|
||||||
<span class="file_link">
|
<span class="file_link">
|
||||||
@@ -197,6 +200,10 @@ const add_upload_history = id => {
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<div bind:this={progress_bar} class="progress_bar"></div>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -204,9 +211,9 @@ const add_upload_history = id => {
|
|||||||
.upload_task{
|
.upload_task{
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 420px;
|
width: 440px;
|
||||||
max-width: 90%;
|
max-width: 95%;
|
||||||
height: 3.8em;
|
height: 4em;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -218,7 +225,7 @@ const add_upload_history = id => {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 1.2em;
|
line-height: 1.2em;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
transition: box-shadow 0.3s, opacity 2s;
|
transition: box-shadow 0.3s, opacity 2s;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -226,12 +233,18 @@ const add_upload_history = id => {
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.top_half {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
.upload_task:hover {
|
.upload_task:hover {
|
||||||
box-shadow: 0 0 2px 2px var(--highlight_color), inset 0 0 1px 1px var(--highlight_color);
|
box-shadow: 0 0 2px 2px var(--highlight_color), inset 0 0 1px 1px var(--highlight_color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload_task > .thumbnail {
|
.thumbnail {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
width: 3.8em;
|
width: 3.8em;
|
||||||
@@ -239,22 +252,22 @@ const add_upload_history = id => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.upload_task > .thumbnail > img {
|
.thumbnail > img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.upload_task > .thumbnail > i {
|
.thumbnail > i {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
}
|
}
|
||||||
.upload_task > .queue_body {
|
.queue_body {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.upload_task > .queue_body > .title {
|
.queue_body > .title {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.upload_task > .queue_body > .stats {
|
.queue_body > .stats {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -264,11 +277,21 @@ const add_upload_history = id => {
|
|||||||
font-family: sans-serif, monospace;
|
font-family: sans-serif, monospace;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.upload_task > .queue_body > .stats > .stat {
|
.queue_body > .stats > .stat {
|
||||||
flex: 0 1 100%;
|
flex: 0 1 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file_link{
|
.file_link{
|
||||||
color: var(--highlight_color);
|
color: var(--highlight_color);
|
||||||
}
|
}
|
||||||
|
.progress {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
height: 2px;
|
||||||
|
}
|
||||||
|
.progress_bar {
|
||||||
|
background-color: var(--highlight_color);
|
||||||
|
height: 100%;
|
||||||
|
width: 0;
|
||||||
|
transition: width 0.3s;
|
||||||
|
transition-timing-function: linear;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user