Update templates/index.html
Browse files- templates/index.html +31 -45
templates/index.html
CHANGED
|
@@ -351,9 +351,7 @@
|
|
| 351 |
|
| 352 |
(function() {
|
| 353 |
let isProcessing = false;
|
| 354 |
-
let currentJob = null; // --- NEW: To hold the current job for cancellation
|
| 355 |
|
| 356 |
-
// ... (بقیه کدهای کمکی مثل getBrowserFingerprint و مدیریت اعتبار اینجا بدون تغییر قرار میگیرند) ...
|
| 357 |
let userSubscriptionStatus = 'free';
|
| 358 |
let userFingerprint = null;
|
| 359 |
let countdownInterval = null;
|
|
@@ -472,6 +470,7 @@
|
|
| 472 |
document.getElementById('upgrade-button').addEventListener('click', () => {
|
| 473 |
parent.postMessage({ type: 'NAVIGATE_TO_PREMIUM' }, '*');
|
| 474 |
});
|
|
|
|
| 475 |
const resultContainer = document.getElementById('result-container');
|
| 476 |
const imageFileInput = document.getElementById('imageFile');
|
| 477 |
const imagePreview = document.getElementById('imagePreview');
|
|
@@ -587,10 +586,6 @@
|
|
| 587 |
imageDropZone.classList.remove('has-image');
|
| 588 |
promptInput.value = DEFAULT_PROMPT_TEXT;
|
| 589 |
isProcessing = false;
|
| 590 |
-
if(currentJob) {
|
| 591 |
-
currentJob.cancel();
|
| 592 |
-
currentJob = null;
|
| 593 |
-
}
|
| 594 |
generateButton.disabled = false;
|
| 595 |
durationSlider.value = DEFAULT_VIDEO_DURATION;
|
| 596 |
durationValueDisplay.textContent = `${parseFloat(DEFAULT_VIDEO_DURATION).toFixed(1)} ثانیه`;
|
|
@@ -721,68 +716,59 @@
|
|
| 721 |
|
| 722 |
lastAttemptedVideoPayload = { persianPrompt, imageSourceFile: imageFile, duration };
|
| 723 |
|
| 724 |
-
let globalTimeout;
|
| 725 |
-
|
| 726 |
try {
|
| 727 |
const englishPrompt = await translatePersianToEnglish(persianPrompt);
|
| 728 |
addStatusMessage(`ترجمه: ${englishPrompt}`, 'info');
|
| 729 |
|
| 730 |
const client = await Client.connect(VIDEO_SPACE_NAME);
|
| 731 |
-
|
| 732 |
imageFile, englishPrompt, 6, DEFAULT_NEGATIVE_PROMPT,
|
| 733 |
duration, 1, 1, 0, true
|
| 734 |
]);
|
| 735 |
|
| 736 |
-
const videoGenerationPromise = (async () => {
|
| 737 |
let hasStartedProcessing = false;
|
| 738 |
-
|
|
|
|
|
|
|
|
|
|
| 739 |
|
| 740 |
-
|
| 741 |
-
|
| 742 |
-
currentJob?.cancel();
|
| 743 |
-
throw new Error("Server is busy or no GPU available (Queue Timeout). لطفا مجددا تلاش کنید.");
|
| 744 |
}
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
|
| 754 |
-
|
| 755 |
-
clearTimeout(queueTimeout);
|
| 756 |
-
}
|
| 757 |
-
setAiLoaderText("در حال ساخت فریمهای ویدیو...");
|
| 758 |
-
} else if (status.stage === "error") {
|
| 759 |
-
throw new Error(status.message || "خطای نامشخص در سرور");
|
| 760 |
-
}
|
| 761 |
-
} else if (status.type === "data") {
|
| 762 |
-
finalResult = status;
|
| 763 |
}
|
| 764 |
-
}
|
| 765 |
-
|
| 766 |
-
clearTimeout(queueTimeout);
|
| 767 |
-
return finalResult;
|
| 768 |
-
})();
|
| 769 |
|
| 770 |
-
|
| 771 |
-
|
| 772 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 773 |
|
| 774 |
const result = await videoGenerationPromise;
|
| 775 |
-
|
| 776 |
-
|
| 777 |
await handleSuccessfulVideoGeneration(result);
|
| 778 |
|
| 779 |
} catch (errorCaught) {
|
| 780 |
-
clearTimeout(globalTimeout);
|
| 781 |
const isTranslationErr = errorCaught.message.toLowerCase().includes("مترجم");
|
| 782 |
showCriticalError(`خطا: ${errorCaught.message}`, isTranslationErr);
|
| 783 |
} finally {
|
| 784 |
isProcessing = false;
|
| 785 |
-
currentJob = null;
|
| 786 |
if (!document.getElementById('upgrade-button').style.display || document.getElementById('upgrade-button').style.display === 'none') {
|
| 787 |
generateButton.disabled = false;
|
| 788 |
}
|
|
|
|
| 351 |
|
| 352 |
(function() {
|
| 353 |
let isProcessing = false;
|
|
|
|
| 354 |
|
|
|
|
| 355 |
let userSubscriptionStatus = 'free';
|
| 356 |
let userFingerprint = null;
|
| 357 |
let countdownInterval = null;
|
|
|
|
| 470 |
document.getElementById('upgrade-button').addEventListener('click', () => {
|
| 471 |
parent.postMessage({ type: 'NAVIGATE_TO_PREMIUM' }, '*');
|
| 472 |
});
|
| 473 |
+
|
| 474 |
const resultContainer = document.getElementById('result-container');
|
| 475 |
const imageFileInput = document.getElementById('imageFile');
|
| 476 |
const imagePreview = document.getElementById('imagePreview');
|
|
|
|
| 586 |
imageDropZone.classList.remove('has-image');
|
| 587 |
promptInput.value = DEFAULT_PROMPT_TEXT;
|
| 588 |
isProcessing = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
generateButton.disabled = false;
|
| 590 |
durationSlider.value = DEFAULT_VIDEO_DURATION;
|
| 591 |
durationValueDisplay.textContent = `${parseFloat(DEFAULT_VIDEO_DURATION).toFixed(1)} ثانیه`;
|
|
|
|
| 716 |
|
| 717 |
lastAttemptedVideoPayload = { persianPrompt, imageSourceFile: imageFile, duration };
|
| 718 |
|
|
|
|
|
|
|
| 719 |
try {
|
| 720 |
const englishPrompt = await translatePersianToEnglish(persianPrompt);
|
| 721 |
addStatusMessage(`ترجمه: ${englishPrompt}`, 'info');
|
| 722 |
|
| 723 |
const client = await Client.connect(VIDEO_SPACE_NAME);
|
| 724 |
+
const job = client.submit(0, [
|
| 725 |
imageFile, englishPrompt, 6, DEFAULT_NEGATIVE_PROMPT,
|
| 726 |
duration, 1, 1, 0, true
|
| 727 |
]);
|
| 728 |
|
| 729 |
+
const videoGenerationPromise = new Promise(async (resolve, reject) => {
|
| 730 |
let hasStartedProcessing = false;
|
| 731 |
+
const startTime = Date.now();
|
| 732 |
+
|
| 733 |
+
while (true) {
|
| 734 |
+
const status = await job.status();
|
| 735 |
|
| 736 |
+
if (status.stage === "error") {
|
| 737 |
+
return reject(new Error(status.message || "خطای نامشخص در سرور"));
|
|
|
|
|
|
|
| 738 |
}
|
| 739 |
+
|
| 740 |
+
if (status.stage === "completed") {
|
| 741 |
+
return resolve(status);
|
| 742 |
+
}
|
| 743 |
+
|
| 744 |
+
if (status.stage === "pending" || status.stage === "queued") {
|
| 745 |
+
setAiLoaderText(`در صف پردازش... (نفر ${status.queue_position || '?'})`);
|
| 746 |
+
} else if (status.stage === "generating" || status.stage === "iterating") {
|
| 747 |
+
if (!hasStartedProcessing) hasStartedProcessing = true;
|
| 748 |
+
setAiLoaderText("در حال ساخت فریمهای ویدیو...");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 749 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 750 |
|
| 751 |
+
if (!hasStartedProcessing && Date.now() - startTime > QUEUE_TIMEOUT) {
|
| 752 |
+
return reject(new Error("Server is busy. لطفا مجددا تلاش کنید. (Queue Timeout)"));
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
if (Date.now() - startTime > GLOBAL_TIMEOUT) {
|
| 756 |
+
return reject(new Error('پردازش بیش از حد طولانی شد. (Global Timeout)'));
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
await new Promise(r => setTimeout(r, 2000)); // 2 ثانیه صبر
|
| 760 |
+
}
|
| 761 |
+
});
|
| 762 |
|
| 763 |
const result = await videoGenerationPromise;
|
| 764 |
+
|
|
|
|
| 765 |
await handleSuccessfulVideoGeneration(result);
|
| 766 |
|
| 767 |
} catch (errorCaught) {
|
|
|
|
| 768 |
const isTranslationErr = errorCaught.message.toLowerCase().includes("مترجم");
|
| 769 |
showCriticalError(`خطا: ${errorCaught.message}`, isTranslationErr);
|
| 770 |
} finally {
|
| 771 |
isProcessing = false;
|
|
|
|
| 772 |
if (!document.getElementById('upgrade-button').style.display || document.getElementById('upgrade-button').style.display === 'none') {
|
| 773 |
generateButton.disabled = false;
|
| 774 |
}
|