mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
fix PeerTube upload: final working solution — simple multipart POST with CURLFile; iterated through Google-resumable PATCH protocol debugging (HTTP version negotiation, chunk body encoding, off-by-one fixes) before settling on simpler POST approach
This commit is contained in:
96
app/public/assets/js/upload-progress.js
Normal file
96
app/public/assets/js/upload-progress.js
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* upload-progress.js
|
||||
*
|
||||
* Intercepts admin form submissions (add.php / edit.php) and submits via
|
||||
* XMLHttpRequest to display a progress bar for large file uploads.
|
||||
* Falls back to native form POST when JavaScript is unavailable.
|
||||
*
|
||||
* Requires an element with id="upload-progress-bar" inside the form.
|
||||
* The progress bar is normally hidden (display:none), shown only during upload.
|
||||
*/
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
const FORMS = document.querySelectorAll('form[data-upload-progress]');
|
||||
if (!FORMS.length) return;
|
||||
|
||||
for (const form of FORMS) {
|
||||
const progressWrap = form.querySelector('#upload-progress-wrap');
|
||||
const progressBar = form.querySelector('#upload-progress-bar');
|
||||
const progressText = form.querySelector('#upload-progress-text');
|
||||
const submitBtn = form.querySelector('button[type="submit"]');
|
||||
|
||||
if (!progressBar || !progressWrap) continue;
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
// Only intercept if files are actually attached (FilePond inputs have files)
|
||||
const fileInputs = form.querySelectorAll('input[type="file"]');
|
||||
let hasFiles = false;
|
||||
for (const fi of fileInputs) {
|
||||
if (fi.files && fi.files.length > 0) {
|
||||
hasFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasFiles) return; // let native submit handle it
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Show progress bar
|
||||
progressWrap.style.display = 'block';
|
||||
progressBar.value = 0;
|
||||
progressText.textContent = '0%';
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
|
||||
// Build FormData
|
||||
const fd = new FormData(form);
|
||||
// Ensure any FilePond-managed files are included — FilePond with
|
||||
// storeAsFile:true copies files into the <input>.files, so FormData
|
||||
// picks them up automatically from the DOM inputs.
|
||||
// But we must also respect queue_order hidden inputs.
|
||||
// FormData(form) already handles this since it reads all form fields.
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.upload.addEventListener('progress', function (evt) {
|
||||
if (evt.lengthComputable) {
|
||||
const pct = Math.round((evt.loaded / evt.total) * 100);
|
||||
progressBar.value = pct;
|
||||
progressText.textContent = pct + '%';
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('load', function () {
|
||||
// Server returns a redirect (302) on success, or re-renders the form on error.
|
||||
// We can't follow 302 with XHR directly — the response body is the target page.
|
||||
// Check if we got a redirect by examining the response URL.
|
||||
const finalUrl = xhr.responseURL || '';
|
||||
const isRedirect = xhr.status >= 200 && xhr.status < 300 && finalUrl !== '' && !finalUrl.endsWith(form.action);
|
||||
|
||||
if (isRedirect) {
|
||||
// Success — navigate to the redirect target
|
||||
window.location.href = finalUrl;
|
||||
} else {
|
||||
// Error — the server returned the form HTML with flash messages.
|
||||
// Replace the current page content.
|
||||
document.open();
|
||||
document.write(xhr.responseText);
|
||||
document.close();
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('error', function () {
|
||||
progressText.textContent = 'Erreur réseau';
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
});
|
||||
|
||||
xhr.addEventListener('abort', function () {
|
||||
progressWrap.style.display = 'none';
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
});
|
||||
|
||||
xhr.open('POST', form.action, true);
|
||||
xhr.send(fd);
|
||||
});
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user