Files
ai.allucanget.biz/frontend/app/static/app.js
T

109 lines
4.1 KiB
JavaScript

document.addEventListener("DOMContentLoaded", () => {
// ── Loading overlay ────────────────────────────────────
const overlay = document.getElementById("loading-overlay");
document.querySelectorAll("form").forEach((form) => {
form.addEventListener("submit", () => {
if (overlay) overlay.classList.add("active");
});
});
// ── Hamburger menu ─────────────────────────────────────
const hamburger = document.querySelector(".hamburger");
const navLinks = document.querySelector(".nav-links");
if (hamburger && navLinks) {
hamburger.addEventListener("click", () => {
navLinks.classList.toggle("open");
});
}
// ── Image upload preview ───────────────────────────────
const imageInput = document.getElementById("reference_image");
const imagePreviewWrap = document.getElementById("image-upload-preview");
const imagePreview = document.getElementById("image-upload-preview-img");
const imageFilename = document.getElementById("image-upload-filename");
if (imageInput && imagePreviewWrap && imagePreview && imageFilename) {
imageInput.addEventListener("change", () => {
const file = imageInput.files && imageInput.files[0];
if (!file) {
imagePreviewWrap.hidden = true;
imagePreview.removeAttribute("src");
imageFilename.textContent = "";
return;
}
imagePreview.src = URL.createObjectURL(file);
imageFilename.textContent = file.name;
imagePreviewWrap.hidden = false;
});
}
// ── Generate dropdown tabs ─────────────────────────────
document.querySelectorAll(".tab-btn").forEach((btn) => {
btn.addEventListener("click", () => {
const target = btn.dataset.tab;
const container = btn.closest(".tabs-container");
if (!container) return;
container
.querySelectorAll(".tab-btn")
.forEach((b) => b.classList.remove("active"));
container
.querySelectorAll(".tab-panel")
.forEach((p) => p.classList.remove("active"));
btn.classList.add("active");
const panel = container.querySelector(`#tab-${target}`);
if (panel) panel.classList.add("active");
});
});
// ── Video status polling ───────────────────────────────
const pollDiv = document.getElementById("video-poll-status");
if (pollDiv) {
const videoId = pollDiv.dataset.videoId;
const statusText = document.getElementById("poll-status-text");
const videoContainer = document.getElementById("poll-video-container");
const interval = setInterval(async () => {
try {
const resp = await fetch(
"/generate/video/" + encodeURIComponent(videoId) + "/status",
);
if (!resp.ok) return;
const data = await resp.json();
if (statusText) {
statusText.innerHTML = "Status: <strong>" + data.status + "</strong>";
}
if (data.status === "completed") {
clearInterval(interval);
if (data.video_url) {
if (videoContainer) {
const vid = document.createElement("video");
vid.src = data.video_url;
vid.controls = true;
vid.className = "generated-video";
videoContainer.appendChild(vid);
const msg = pollDiv.querySelector("p");
if (msg) msg.textContent = "Video ready!";
} else {
// video_detail page: reload to show the video element
window.location.reload();
}
}
} else if (data.status === "failed" || data.status === "cancelled") {
clearInterval(interval);
pollDiv.innerHTML =
'<div class="alert alert-error">Generation failed or was cancelled.</div>';
}
} catch (e) {
console.error("Video polling error:", e);
}
}, 5000);
}
});