Refactor Nginx configuration and update project dependencies
- Cleaned up the Nginx configuration for the Coolify deployment, ensuring proper formatting and organization. - Updated the `pyproject.toml` file to maintain consistent formatting. - Reformatted the `requirements.txt` file for better readability while keeping the dependencies unchanged.
This commit is contained in:
1 parent
3b8c30c289
commit
a4b874598d
88 files changed
+9766
-9766
No files matched your search
+174
-174
@@ -1,174 +1,174 @@
|
||||
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 cancelBtn = document.getElementById("cancel-video-btn");
|
||||
const cancelMsg = document.getElementById("cancel-msg");
|
||||
const MAX_POLLS = 120; // ~10 minutes at 5s interval
|
||||
let pollCount = 0;
|
||||
let interval = null;
|
||||
|
||||
const stopPolling = () => {
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
}
|
||||
};
|
||||
|
||||
if (cancelBtn) {
|
||||
cancelBtn.addEventListener("click", async () => {
|
||||
cancelBtn.disabled = true;
|
||||
cancelBtn.textContent = "Cancelling…";
|
||||
try {
|
||||
const resp = await fetch(
|
||||
"/generate/video/" + encodeURIComponent(videoId) + "/cancel",
|
||||
{ method: "POST" },
|
||||
);
|
||||
if (resp.ok) {
|
||||
stopPolling();
|
||||
cancelBtn.classList.add("hidden");
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = "Job cancelled.";
|
||||
cancelMsg.classList.remove("hidden", "text-red-500");
|
||||
cancelMsg.classList.add("text-gray-300");
|
||||
}
|
||||
if (statusText) {
|
||||
statusText.innerHTML = "Status: <strong>cancelled</strong>";
|
||||
}
|
||||
} else {
|
||||
const data = await resp.json().catch(() => ({}));
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.textContent = "Cancel Job";
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = data.detail || "Cancel failed.";
|
||||
cancelMsg.classList.remove("hidden");
|
||||
cancelMsg.classList.add("text-red-500");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.textContent = "Cancel Job";
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = "Network error.";
|
||||
cancelMsg.classList.remove("hidden");
|
||||
cancelMsg.classList.add("text-red-500");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interval = setInterval(async () => {
|
||||
try {
|
||||
pollCount++;
|
||||
if (pollCount > MAX_POLLS) {
|
||||
stopPolling();
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-warning">Polling timed out. Please refresh the page to check status.</div>';
|
||||
return;
|
||||
}
|
||||
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") {
|
||||
stopPolling();
|
||||
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") {
|
||||
stopPolling();
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-error">Generation failed.</div>';
|
||||
} else if (data.status === "cancelled") {
|
||||
stopPolling();
|
||||
if (cancelBtn) cancelBtn.classList.add("hidden");
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-info">Job was cancelled.</div>';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Video polling error:", e);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
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 cancelBtn = document.getElementById("cancel-video-btn");
|
||||
const cancelMsg = document.getElementById("cancel-msg");
|
||||
const MAX_POLLS = 120; // ~10 minutes at 5s interval
|
||||
let pollCount = 0;
|
||||
let interval = null;
|
||||
|
||||
const stopPolling = () => {
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
}
|
||||
};
|
||||
|
||||
if (cancelBtn) {
|
||||
cancelBtn.addEventListener("click", async () => {
|
||||
cancelBtn.disabled = true;
|
||||
cancelBtn.textContent = "Cancelling…";
|
||||
try {
|
||||
const resp = await fetch(
|
||||
"/generate/video/" + encodeURIComponent(videoId) + "/cancel",
|
||||
{ method: "POST" },
|
||||
);
|
||||
if (resp.ok) {
|
||||
stopPolling();
|
||||
cancelBtn.classList.add("hidden");
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = "Job cancelled.";
|
||||
cancelMsg.classList.remove("hidden", "text-red-500");
|
||||
cancelMsg.classList.add("text-gray-300");
|
||||
}
|
||||
if (statusText) {
|
||||
statusText.innerHTML = "Status: <strong>cancelled</strong>";
|
||||
}
|
||||
} else {
|
||||
const data = await resp.json().catch(() => ({}));
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.textContent = "Cancel Job";
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = data.detail || "Cancel failed.";
|
||||
cancelMsg.classList.remove("hidden");
|
||||
cancelMsg.classList.add("text-red-500");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.textContent = "Cancel Job";
|
||||
if (cancelMsg) {
|
||||
cancelMsg.textContent = "Network error.";
|
||||
cancelMsg.classList.remove("hidden");
|
||||
cancelMsg.classList.add("text-red-500");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interval = setInterval(async () => {
|
||||
try {
|
||||
pollCount++;
|
||||
if (pollCount > MAX_POLLS) {
|
||||
stopPolling();
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-warning">Polling timed out. Please refresh the page to check status.</div>';
|
||||
return;
|
||||
}
|
||||
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") {
|
||||
stopPolling();
|
||||
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") {
|
||||
stopPolling();
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-error">Generation failed.</div>';
|
||||
} else if (data.status === "cancelled") {
|
||||
stopPolling();
|
||||
if (cancelBtn) cancelBtn.classList.add("hidden");
|
||||
pollDiv.innerHTML =
|
||||
'<div class="alert alert-info">Job was cancelled.</div>';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Video polling error:", e);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
+817
-817
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user