From e356e9377d936fa56dddd37668083b9bed643a1d Mon Sep 17 00:00:00 2001 From: G2-Games Date: Wed, 23 Oct 2024 23:27:26 -0500 Subject: [PATCH] Added ability to upload multiple files at the same time and see progress --- src/main.rs | 5 +++-- src/static/main.css | 33 +++++++++++++++++++++++++--- src/static/request.js | 51 +++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/main.rs b/src/main.rs index 231ad7a..7ad4b3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,7 @@ fn favicon() -> (ContentType, &'static str) { #[get("/")] fn home(settings: &State) -> Markup { + dbg!(settings.duration.default); html! { (head("Confetti-Box")) @@ -69,7 +70,7 @@ fn home(settings: &State) -> Markup { input id="fileInput" type="file" name="fileUpload" onchange="formSubmit(this.parentNode)" data-max-filesize=(settings.max_filesize) style="display:none;"; input id="fileDuration" type="text" name="duration" minlength="2" - maxlength="7" value=(settings.duration.default) style="display:none;"; + maxlength="7" value=(settings.duration.default.num_seconds().to_string() + "s") style="display:none;"; } button.main_file_upload onclick="document.getElementById('fileInput').click()" { h4 { "Upload File" } @@ -79,7 +80,7 @@ fn home(settings: &State) -> Markup { h3 { "Uploaded Files" } div #uploadedFilesDisplay { - div { p {"File Name Here"} span {" "} div {p {"File Link Here"} button {"copy"}} } + } hr; diff --git a/src/static/main.css b/src/static/main.css index 33454e0..fb6a3ba 100644 --- a/src/static/main.css +++ b/src/static/main.css @@ -116,10 +116,9 @@ button.main_file_upload { gap: 10px; } -#uploadedFilesDisplay > div > span { +#uploadedFilesDisplay > div > progress { flex-grow: 2; - border-top: 2px dotted grey; - height: 0px; + height: 20px; margin: auto; } @@ -127,3 +126,31 @@ button.main_file_upload { height: 50px; width: 50px; } + +progress[value] { + --color: #84FFAE; /* the progress color */ + --background: lightgrey; /* the background color */ + + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: var(--background); +} + +progress[value]::-moz-progress-bar { + background-color: var(--color); + border-radius: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset; +} + +progress[value]::-webkit-progress-bar { + background-color: var(--background); + border-radius: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset; +} + +progress[value]::-webkit-progress-value { + border-radius: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset; + background-color: var(--color); +} diff --git a/src/static/request.js b/src/static/request.js index 93833bc..665bc45 100644 --- a/src/static/request.js +++ b/src/static/request.js @@ -1,5 +1,3 @@ -let progressBar; -let progressValue; let statusNotifier; let uploadedFilesDisplay; let durationBox; @@ -9,8 +7,6 @@ let uploadInProgress = false; const TOO_LARGE_TEXT = "File is too large!"; const ERROR_TEXT = "An error occured!"; -let CAPABILITIES; - async function formSubmit(form) { if (uploadInProgress) { return; // TODO: REMOVE THIS ONCE MULTIPLE CAN WORK! @@ -19,7 +15,7 @@ async function formSubmit(form) { // Get file size and don't upload if it's too large let file_upload = document.getElementById("fileInput"); let file = file_upload.files[0]; - if (file.size > CAPABILITIES.max_filesize) { + if (file.size > file_upload.dataset.maxFilesize) { progressValue.textContent = TOO_LARGE_TEXT; console.error( "Provided file is too large", file.size, "bytes; max", @@ -28,14 +24,16 @@ async function formSubmit(form) { return; } + let [progressBar, progressText] = addNewToList(file.name); + let url = "/upload"; let request = new XMLHttpRequest(); request.open('POST', url, true); - // Set up the listeners - request.addEventListener('load', uploadComplete, false); + // Set up event listeners + request.upload.addEventListener('progress', (p) => {uploadProgress(p, progressBar, progressText)}, false); + request.addEventListener('load', (c) => {uploadComplete(c, progressBar, progressText)}, false); request.addEventListener('error', networkErrorHandler, false); - request.upload.addEventListener('progress', uploadProgress, false); uploadInProgress = true; // Create and send FormData @@ -55,42 +53,47 @@ function networkErrorHandler(_err) { progressValue.textContent = "A network error occured!"; } -function uploadComplete(response) { +function uploadComplete(response, _progressBar, progressText) { let target = response.target; - progressBar.value = 0; if (target.status === 200) { const response = JSON.parse(target.responseText); if (response.status) { - progressValue.textContent = "Success"; - addToList(response.name, response.url); + progressText.textContent = "Success"; } else { console.error("Error uploading", response) - progressValue.textContent = response.response; + progressText.textContent = response.response; } } else if (target.status === 413) { - progressValue.textContent = TOO_LARGE_TEXT; + progressText.textContent = TOO_LARGE_TEXT; } else { - progressValue.textContent = ERROR_TEXT; + progressText.textContent = ERROR_TEXT; } uploadInProgress = false; } -function addToList(filename, link) { - const link_row = uploadedFilesDisplay.appendChild(document.createElement("p")); - const new_link = link_row.appendChild(document.createElement("a")); +function addNewToList(origFileName) { + const linkRow = uploadedFilesDisplay.appendChild(document.createElement("div")); + const fileName = linkRow.appendChild(document.createElement("p")); + const progressBar = linkRow.appendChild(document.createElement("progress")); + const progressTxt = linkRow.appendChild(document.createElement("p")); - new_link.href = link; - new_link.textContent = filename; + fileName.textContent = origFileName; + progressBar.max="100"; + progressBar.value="0"; + + return [progressBar, progressTxt]; } -function uploadProgress(progress) { +function uploadProgress(progress, progressBar, progressText) { + console.log(progress); if (progress.lengthComputable) { const progressPercent = Math.floor((progress.loaded / progress.total) * 100); progressBar.value = progressPercent; - progressValue.textContent = progressPercent + "%"; + console.log(progressBar.value); + progressText.textContent = progressPercent + "%"; } } @@ -119,8 +122,6 @@ function toPrettyTime(seconds) { } async function getServerCapabilities() { - let file_duration = document.getElementById("fileDuration"); - const durationButtons = durationBox.getElementsByTagName("button"); for (const b of durationButtons) { b.addEventListener("click", function (_e) { @@ -129,8 +130,6 @@ async function getServerCapabilities() { } let selected = this.parentNode.getElementsByClassName("selected"); selected[0].classList.remove("selected"); - - file_duration.value = this.dataset.durationSeconds + "s"; this.classList.add("selected"); }); }