Restructure upload widget
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { add_upload_history, domain_url } from "../util/Util.svelte"
|
import { add_upload_history, domain_url } from "../util/Util.svelte"
|
||||||
import { formatDataVolume, formatDuration} from "../util/Formatting.svelte"
|
import { formatDataVolume, formatDuration } from "../util/Formatting.svelte"
|
||||||
import Spinner from "../util/Spinner.svelte";
|
import Spinner from "../util/Spinner.svelte";
|
||||||
|
|
||||||
export let job = {}
|
export let job = {}
|
||||||
let file_button
|
let file_button
|
||||||
@@ -10,29 +10,29 @@ let tries = 0
|
|||||||
let start_time = 0
|
let start_time = 0
|
||||||
let remaining_time = 0
|
let remaining_time = 0
|
||||||
|
|
||||||
let stats_interval = null
|
let last_update_time = 0
|
||||||
let stats_interval_ms = 250
|
|
||||||
let progress = 0
|
let progress = 0
|
||||||
let last_loaded_size = 0
|
|
||||||
let transfer_rate = 0
|
let transfer_rate = 0
|
||||||
const on_progress = () => {
|
const on_progress = (loaded, total) => {
|
||||||
if (job.loaded_size === 0 || job.total_size === 0) {
|
job.loaded_size = loaded
|
||||||
|
job.total_size = total
|
||||||
|
|
||||||
|
if (last_update_time === 0) {
|
||||||
|
last_update_time = new Date().getTime()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
progress = job.loaded_size / job.total_size
|
let current_time = new Date().getTime()
|
||||||
let elapsed_time = new Date().getTime() - start_time
|
last_update_time = current_time
|
||||||
|
|
||||||
|
let elapsed_time = current_time - start_time
|
||||||
remaining_time = (elapsed_time/progress) - elapsed_time
|
remaining_time = (elapsed_time/progress) - elapsed_time
|
||||||
|
|
||||||
// Calculate transfer rate, apply smoothing by mixing it with the previous
|
progress = job.loaded_size / job.total_size
|
||||||
// rate ten to one
|
|
||||||
transfer_rate = Math.floor(
|
|
||||||
(transfer_rate * 0.9) +
|
|
||||||
(((1000 / stats_interval_ms) * (job.loaded_size - last_loaded_size)) * 0.1)
|
|
||||||
)
|
|
||||||
|
|
||||||
last_loaded_size = job.loaded_size
|
|
||||||
|
|
||||||
|
// Calculate transfer rate by dividing the total uploaded size by the total
|
||||||
|
// running time
|
||||||
|
transfer_rate = Math.floor(job.loaded_size / ((current_time - start_time) / 1000))
|
||||||
progress_bar.style.width = (progress * 100) + "%"
|
progress_bar.style.width = (progress * 100) + "%"
|
||||||
|
|
||||||
if (progress >= 1) {
|
if (progress >= 1) {
|
||||||
@@ -46,8 +46,6 @@ const on_progress = () => {
|
|||||||
let href = null
|
let href = null
|
||||||
let target = null
|
let target = null
|
||||||
const on_success = (resp) => {
|
const on_success = (resp) => {
|
||||||
clearInterval(stats_interval)
|
|
||||||
stats_interval = null
|
|
||||||
transfer_rate = 0
|
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
|
job.file = null // Delete reference to file to free memory
|
||||||
@@ -68,8 +66,6 @@ const on_success = (resp) => {
|
|||||||
let error_id = ""
|
let error_id = ""
|
||||||
let error_reason = ""
|
let error_reason = ""
|
||||||
const on_failure = (status, message) => {
|
const on_failure = (status, message) => {
|
||||||
clearInterval(stats_interval)
|
|
||||||
stats_interval = null
|
|
||||||
transfer_rate = 0
|
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
|
job.file = null // Delete reference to file to free memory
|
||||||
@@ -100,9 +96,6 @@ export const start = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
start_time = new Date().getTime()
|
start_time = new Date().getTime()
|
||||||
if (stats_interval === null) {
|
|
||||||
stats_interval = setInterval(on_progress, stats_interval_ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.open("PUT", window.api_endpoint+"/file/"+encodeURIComponent(job.name), true);
|
xhr.open("PUT", window.api_endpoint+"/file/"+encodeURIComponent(job.name), true);
|
||||||
@@ -110,8 +103,7 @@ export const start = () => {
|
|||||||
|
|
||||||
xhr.upload.addEventListener("progress", evt => {
|
xhr.upload.addEventListener("progress", evt => {
|
||||||
if (evt.lengthComputable) {
|
if (evt.lengthComputable) {
|
||||||
job.loaded_size = evt.loaded
|
on_progress(evt.loaded, evt.total)
|
||||||
job.total_size = evt.total
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
118
svelte/src/home_page/UploadStats.svelte
Normal file
118
svelte/src/home_page/UploadStats.svelte
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<script>
|
||||||
|
import { formatDataVolume, formatDuration } from "../util/Formatting.svelte";
|
||||||
|
import ProgressBar from "../util/ProgressBar.svelte";
|
||||||
|
|
||||||
|
export let upload_queue = []
|
||||||
|
|
||||||
|
let stats_interval = null
|
||||||
|
let stats_interval_ms = 1000
|
||||||
|
let finished = false
|
||||||
|
|
||||||
|
export const start = () => {
|
||||||
|
if (stats_interval === null) {
|
||||||
|
start_time = new Date().getTime()
|
||||||
|
stats_interval = setInterval(stats_update, stats_interval_ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
finished = false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const finish = () => {
|
||||||
|
if (stats_interval !== null) {
|
||||||
|
clearInterval(stats_interval)
|
||||||
|
stats_interval = null
|
||||||
|
}
|
||||||
|
|
||||||
|
finished = true
|
||||||
|
start_time = 0
|
||||||
|
total_loaded = total_size
|
||||||
|
previously_loaded = total_size
|
||||||
|
total_progress = 1
|
||||||
|
total_rate = 0
|
||||||
|
|
||||||
|
document.title = "Finished! ~ pixeldrain"
|
||||||
|
}
|
||||||
|
|
||||||
|
let start_time = 0
|
||||||
|
let total_progress = 0
|
||||||
|
let total_size = 0
|
||||||
|
let total_loaded = 0
|
||||||
|
let previously_loaded = 0
|
||||||
|
let last_total_loaded = 0
|
||||||
|
let total_rate = 0
|
||||||
|
let elapsed_time = 0
|
||||||
|
let remaining_time = 0
|
||||||
|
|
||||||
|
const stats_update = () => {
|
||||||
|
if (start_time === 0) {
|
||||||
|
start_time = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total size of upload queue and size of finished uploads
|
||||||
|
total_size = 0
|
||||||
|
total_loaded = 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_progress = (total_loaded - previously_loaded) / (total_size - previously_loaded)
|
||||||
|
|
||||||
|
// Calculate ETA by estimating the total time and subtracting the elapsed time
|
||||||
|
elapsed_time = new Date().getTime() - start_time
|
||||||
|
remaining_time = (elapsed_time/total_progress) - elapsed_time
|
||||||
|
|
||||||
|
// Calculate the rate by comparing the current progress with the last iteration
|
||||||
|
total_rate = Math.floor(
|
||||||
|
(total_rate * 0.8) +
|
||||||
|
(((1000 / stats_interval_ms) * (total_loaded - last_total_loaded)) * 0.2)
|
||||||
|
)
|
||||||
|
last_total_loaded = total_loaded
|
||||||
|
|
||||||
|
document.title = (total_progress*100).toFixed(0) + "% ~ " +
|
||||||
|
formatDuration(remaining_time, 0) +
|
||||||
|
" ~ uploading to pixeldrain"
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="stats_box">
|
||||||
|
<div>
|
||||||
|
Size {formatDataVolume(total_size, 3)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Progress {(total_progress*100).toPrecision(3)}%
|
||||||
|
</div>
|
||||||
|
{#if finished}
|
||||||
|
<div>
|
||||||
|
Time {formatDuration(elapsed_time, 0)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Rate {formatDataVolume(total_loaded / (elapsed_time/1000), 3)}/s
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div>
|
||||||
|
ETA {formatDuration(remaining_time, 0)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Rate {formatDataVolume(total_rate, 3)}/s
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ProgressBar total={total_size} used={total_loaded} animation="linear" speed={stats_interval_ms}/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -6,10 +6,9 @@ import Facebook from "../icons/Facebook.svelte"
|
|||||||
import Reddit from "../icons/Reddit.svelte"
|
import Reddit from "../icons/Reddit.svelte"
|
||||||
import Twitter from "../icons/Twitter.svelte"
|
import Twitter from "../icons/Twitter.svelte"
|
||||||
import Tumblr from "../icons/Tumblr.svelte"
|
import Tumblr from "../icons/Tumblr.svelte"
|
||||||
import { formatDataVolume, formatDuration } from "../util/Formatting.svelte";
|
|
||||||
import StorageProgressBar from "../user_home/StorageProgressBar.svelte"
|
import StorageProgressBar from "../user_home/StorageProgressBar.svelte"
|
||||||
import Konami from "../util/Konami.svelte"
|
import Konami from "../util/Konami.svelte"
|
||||||
import ProgressBar from "../util/ProgressBar.svelte"
|
import UploadStats from "./UploadStats.svelte";
|
||||||
|
|
||||||
// === UPLOAD LOGIC ===
|
// === UPLOAD LOGIC ===
|
||||||
|
|
||||||
@@ -41,6 +40,7 @@ const paste = (e) => {
|
|||||||
let active_uploads = 0
|
let active_uploads = 0
|
||||||
let upload_queue = []
|
let upload_queue = []
|
||||||
let state = "idle" // idle, uploading, finished
|
let state = "idle" // idle, uploading, finished
|
||||||
|
let upload_stats
|
||||||
|
|
||||||
const upload_files = async (files) => {
|
const upload_files = async (files) => {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
@@ -90,20 +90,11 @@ const start_upload = () => {
|
|||||||
|
|
||||||
if (active_uploads === 0 && finished_count != 0) {
|
if (active_uploads === 0 && finished_count != 0) {
|
||||||
state = "finished"
|
state = "finished"
|
||||||
|
upload_stats.finish()
|
||||||
if (stats_interval !== null) {
|
|
||||||
clearInterval(stats_interval)
|
|
||||||
stats_interval = null
|
|
||||||
stats_finished()
|
|
||||||
}
|
|
||||||
|
|
||||||
uploads_finished()
|
uploads_finished()
|
||||||
} else {
|
} else {
|
||||||
state = "uploading"
|
state = "uploading"
|
||||||
|
upload_stats.start()
|
||||||
if (stats_interval === null) {
|
|
||||||
stats_interval = setInterval(stats_update, stats_interval_ms)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,54 +103,6 @@ const finish_upload = (file) => {
|
|||||||
start_upload()
|
start_upload()
|
||||||
}
|
}
|
||||||
|
|
||||||
let stats_interval = null
|
|
||||||
let stats_interval_ms = 500
|
|
||||||
let start_time = 0
|
|
||||||
let total_progress = 0
|
|
||||||
let total_size = 0
|
|
||||||
let total_loaded = 0
|
|
||||||
let last_total_loaded = 0
|
|
||||||
let total_rate = 0
|
|
||||||
let remaining_time = 0
|
|
||||||
const stats_update = () => {
|
|
||||||
if (start_time === 0) {
|
|
||||||
start_time = new Date().getTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total size of upload queue and size of finished uploads
|
|
||||||
total_size = 0
|
|
||||||
total_loaded = 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_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
|
|
||||||
remaining_time = (elapsed_time/total_progress) - elapsed_time
|
|
||||||
|
|
||||||
// Calculate the rate by comparing the current progress with the last iteration
|
|
||||||
total_rate = Math.floor(
|
|
||||||
(total_rate * 0.8) +
|
|
||||||
(((1000 / stats_interval_ms) * (total_loaded - last_total_loaded)) * 0.2)
|
|
||||||
)
|
|
||||||
last_total_loaded = total_loaded
|
|
||||||
|
|
||||||
document.title = (total_progress*100).toFixed(0) + "% ~ " +
|
|
||||||
formatDuration(remaining_time, 0) +
|
|
||||||
" ~ uploading to pixeldrain"
|
|
||||||
}
|
|
||||||
const stats_finished = () => {
|
|
||||||
start_time = 0
|
|
||||||
total_loaded = total_size
|
|
||||||
total_progress = 1
|
|
||||||
total_rate = 0
|
|
||||||
|
|
||||||
document.title = "Finished! ~ pixeldrain"
|
|
||||||
}
|
|
||||||
|
|
||||||
const leave_confirmation = e => {
|
const leave_confirmation = e => {
|
||||||
if (state === "uploading") {
|
if (state === "uploading") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -425,14 +368,8 @@ const keydown = (e) => {
|
|||||||
<span class="big_number">2</span>
|
<span class="big_number">2</span>
|
||||||
<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>Size {formatDataVolume(total_size, 3)}</div>
|
|
||||||
<div>Progress {(total_progress*100).toPrecision(3)}%</div>
|
|
||||||
<div>ETA {formatDuration(remaining_time, 0)}</div>
|
|
||||||
<div>Rate {formatDataVolume(total_rate, 3)}/s</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ProgressBar total={total_size} used={total_loaded} animation="linear" speed={stats_interval_ms}/>
|
<UploadStats bind:this={upload_stats} upload_queue={upload_queue}/>
|
||||||
|
|
||||||
<div id="file_drop_highlight" class="highlight_green" class:hide={!dragging}>
|
<div id="file_drop_highlight" class="highlight_green" class:hide={!dragging}>
|
||||||
Gimme gimme gimme!<br/>
|
Gimme gimme gimme!<br/>
|
||||||
@@ -589,18 +526,6 @@ const keydown = (e) => {
|
|||||||
display: inline;
|
display: inline;
|
||||||
vertical-align: middle;
|
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%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.album_name_form {
|
.album_name_form {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
Reference in New Issue
Block a user