diff --git a/web_app/static/index.html b/web_app/static/index.html
index 0d56371..645411b 100644
--- a/web_app/static/index.html
+++ b/web_app/static/index.html
@@ -116,7 +116,12 @@
Lyrics
-
+
diff --git a/web_app/static/script.js b/web_app/static/script.js
index 441a4ed..7237237 100644
--- a/web_app/static/script.js
+++ b/web_app/static/script.js
@@ -613,7 +613,18 @@ function handleLyricLineClick(lineNumber) {
async function generatePoster() {
if (!currentMetadata) return;
- loadingOverlay.style.display = 'flex';
+ const btn = document.getElementById('generateBtn');
+ const btnSpinner = btn.querySelector('.btn-spinner');
+
+ const resetButton = () => {
+ btn.disabled = false;
+ btn.classList.remove('loading');
+ btnSpinner.style.display = 'none';
+ };
+
+ btn.disabled = true;
+ btn.classList.add('loading');
+ btnSpinner.style.display = 'inline-block';
const indexingToggle = document.getElementById('indexingToggle');
const accentToggle = document.getElementById('accentToggle');
@@ -628,23 +639,20 @@ async function generatePoster() {
};
if (payload.type === 'track') {
- // Lyrics Logic (Same as before)
const startVal = parseInt(startLineInput.value) || 1;
const endVal = parseInt(endLineInput.value) || 1;
const start = startVal - 1;
const end = endVal;
if (isNaN(start) || isNaN(end) || start >= end) {
- loadingOverlay.style.display = 'none';
showToast("Please enter a valid range (Start must be less than End).", "error");
+ resetButton(); // Reset button on validation fail
return;
}
payload.lyrics_start = start;
payload.lyrics_end = end;
-
} else {
- // Album Logic
payload.indexing = indexingToggle ? indexingToggle.checked : false;
}
@@ -665,17 +673,22 @@ async function generatePoster() {
const img = document.createElement('img');
img.src = imageUrl;
+
img.onload = () => {
posterContainer.innerHTML = '';
posterContainer.appendChild(img);
showDownloadButton(imageUrl, data.filename);
- loadingOverlay.style.display = 'none';
+ resetButton();
};
+ img.onerror = () => {
+ showToast("Error: Failed to load generated poster.", "error");
+ resetButton();
+ };
} catch (error) {
console.error("Generation failed", error);
showToast(`Error: ${error.message}`, "error");
- loadingOverlay.style.display = 'none';
+ resetButton();
}
}
diff --git a/web_app/static/style.css b/web_app/static/style.css
index 468eb76..69b96f7 100644
--- a/web_app/static/style.css
+++ b/web_app/static/style.css
@@ -166,6 +166,27 @@ header p {
transform: translateY(-1px);
}
+.primary-btn:disabled, .primary-btn.loading {
+ background: var(--accent-hover);
+ cursor: not-allowed;
+ transform: none;
+ opacity: 0.7;
+}
+
+.primary-btn.loading .btn-text {
+ display: none;
+}
+
+.primary-btn .btn-spinner {
+ animation: spin 0.8s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
.secondary-btn {
background: transparent;
border-color: var(--border-color);