/**
* file-upload-queue.js
*
* Provides single-file previews for file inputs with the data-preview attribute
* (couverture, note_intention, annexes, etc.).
*
* The multi-file TFE queue is rendered server-side via HTMX fragments
* (upload-tfe-file.php / remove-tfe-file.php).
*
* Exposes window.XamxamInitFileUploads() so HTMX fragments can re-bind
* after swap without a global event listener.
*/
window.XamxamInitFileUploads = function () {
console.log("[file-upload-queue] XamxamInitFileUploads called");
var ICON = {
pdf: "\uD83D\uDCC4",
video: "\uD83C\uDFAC",
audio: "\uD83D\uDD0A",
zip: "\uD83D\uDDDC\uFE0F",
vtt: "\uD83D\uDCAC",
image: "\uD83D\uDDBC\uFE0F",
other: "\uD83D\uDCCE",
};
function iconFor(file) {
var t = file.type || "",
n = file.name.toLowerCase();
if (/^image\//.test(t)) return ICON.image;
if (t === "application/pdf" || /\.pdf$/.test(n)) return ICON.pdf;
if (/^video\//.test(t) || /\.(mp4|webm|mov|ogv)$/.test(n))
return ICON.video;
if (/^audio\//.test(t) || /\.(mp3|ogg|oga|wav|flac|aac|m4a)$/.test(n))
return ICON.audio;
if (/\.(zip|tar|gz|tgz)$/.test(n)) return ICON.zip;
if (/\.vtt$/.test(n)) return ICON.vtt;
return ICON.other;
}
function humanSize(b) {
return b >= 1073741824
? (b / 1073741824).toFixed(2) + " GB"
: b >= 1048576
? (b / 1048576).toFixed(2) + " MB"
: b >= 1024
? (b / 1024).toFixed(1) + " KB"
: b + " B";
}
function esc(s) {
return s.replace(/[&<>"]/g, function (c) {
return { "&": "&", "<": "<", ">": ">", '"': """ }[c];
});
}
// ── Single-file previews (data-preview attribute) ────────────────────
document
.querySelectorAll('input[type="file"][data-preview]')
.forEach(function (input) {
if (input.id === "tfe-files-input") return;
console.log(
"[file-upload-queue] binding preview for",
input.id,
"multiple=",
input.multiple,
);
var container = document.getElementById(
input.getAttribute("data-preview"),
);
if (!container) return;
input.onchange = function () {
container.innerHTML = "";
Array.from(input.files).forEach(function (file) {
var item = document.createElement("div");
item.className = "fp-item";
if (/^image\//.test(file.type)) {
var img = document.createElement("img");
img.className = "fp-thumb";
img.alt = file.name;
var reader = new FileReader();
reader.onload = function (e) {
img.src = e.target.result;
};
reader.readAsDataURL(file);
item.appendChild(img);
} else {
var ic = document.createElement("span");
ic.className = "fp-icon";
ic.textContent = iconFor(file);
item.appendChild(ic);
}
var meta = document.createElement("span");
meta.className = "fp-meta";
meta.innerHTML =
'' +
esc(file.name) +
'' +
humanSize(file.size) +
"";
item.appendChild(meta);
container.appendChild(item);
});
};
});
};
// Bootstrap on page load
if (document.readyState === "loading")
document.addEventListener("DOMContentLoaded", window.XamxamInitFileUploads);
else window.XamxamInitFileUploads();