Ezmary commited on
Commit
e9f4bec
·
verified ·
1 Parent(s): 7282bd8

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +47 -37
templates/index.html CHANGED
@@ -351,7 +351,9 @@
351
 
352
  (function() {
353
  let isProcessing = false;
 
354
 
 
355
  let userSubscriptionStatus = 'free';
356
  let userFingerprint = null;
357
  let countdownInterval = null;
@@ -470,7 +472,6 @@
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');
@@ -499,8 +500,8 @@
499
  const DEFAULT_PROMPT_TEXT = "";
500
  const TRANSPARENT_PIXEL_SRC = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
501
  const DEFAULT_VIDEO_DURATION = 4.3;
502
- const GLOBAL_TIMEOUT = 150000; // 2.5 دقیقه
503
- const QUEUE_TIMEOUT = 45000; // 45 ثانیه
504
 
505
  let lastAttemptedVideoPayload = null;
506
 
@@ -586,6 +587,10 @@
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,63 +721,68 @@
716
 
717
  lastAttemptedVideoPayload = { persianPrompt, imageSourceFile: imageFile, duration };
718
 
 
 
719
  try {
720
  const englishPrompt = await translatePersianToEnglish(persianPrompt);
721
  addStatusMessage(`ترجمه: ${englishPrompt}`, 'info');
722
 
723
- // --- START: NEW ROBUST LOGIC ---
724
  const client = await Client.connect(VIDEO_SPACE_NAME);
 
 
 
 
725
 
726
- const videoGenerationPromise = new Promise((resolve, reject) => {
727
  let hasStartedProcessing = false;
728
- let job;
729
 
730
- const queueTimeout = setTimeout(() => {
731
  if (!hasStartedProcessing) {
732
- job?.cancel();
733
- reject(new Error("Server is busy or no GPU available (Queue Timeout). لطفا مجددا تلاش کنید."));
734
  }
735
  }, QUEUE_TIMEOUT);
736
 
737
- job = client.submit(0, [
738
- imageFile, englishPrompt, 6, DEFAULT_NEGATIVE_PROMPT,
739
- duration, 1, 1, 0, true
740
- ]);
741
-
742
- job.on("status", (status) => {
743
- if (status.stage === "pending" || status.stage === "queued") {
744
- setAiLoaderText(`در صف پردازش... (نفر ${status.queue_position || '?'})`);
745
- } else if (status.stage === "generating" || status.stage === "iterating") {
746
- hasStartedProcessing = true;
747
- setAiLoaderText("در حال ساخت فریم‌های ویدیو...");
748
- } else if (status.stage === "error") {
749
- clearTimeout(queueTimeout);
750
- reject(new Error(status.message || "خطای نامشخص در سرور"));
 
 
751
  }
752
- });
 
 
 
 
753
 
754
- job.on("data", (data) => {
755
- clearTimeout(queueTimeout);
756
- resolve(data);
757
- });
758
- });
759
 
760
- const globalTimeoutPromise = new Promise((_, reject) => {
761
- setTimeout(() => {
762
- reject(new Error('پردازش بیش از حد طولانی شد (Global Timeout).'));
763
- }, GLOBAL_TIMEOUT);
764
- });
765
 
766
- const result = await Promise.race([videoGenerationPromise, globalTimeoutPromise]);
767
- // --- END: NEW ROBUST LOGIC ---
768
-
769
  await handleSuccessfulVideoGeneration(result);
770
 
771
  } catch (errorCaught) {
 
772
  const isTranslationErr = errorCaught.message.toLowerCase().includes("مترجم");
773
  showCriticalError(`خطا: ${errorCaught.message}`, isTranslationErr);
774
  } finally {
775
  isProcessing = false;
 
776
  if (!document.getElementById('upgrade-button').style.display || document.getElementById('upgrade-button').style.display === 'none') {
777
  generateButton.disabled = false;
778
  }
 
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
  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');
 
500
  const DEFAULT_PROMPT_TEXT = "";
501
  const TRANSPARENT_PIXEL_SRC = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
502
  const DEFAULT_VIDEO_DURATION = 4.3;
503
+ const GLOBAL_TIMEOUT = 150000;
504
+ const QUEUE_TIMEOUT = 45000;
505
 
506
  let lastAttemptedVideoPayload = null;
507
 
 
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
 
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
+ currentJob = client.submit(0, [
732
+ imageFile, englishPrompt, 6, DEFAULT_NEGATIVE_PROMPT,
733
+ duration, 1, 1, 0, true
734
+ ]);
735
 
736
+ const videoGenerationPromise = (async () => {
737
  let hasStartedProcessing = false;
738
+ let queueTimeout;
739
 
740
+ queueTimeout = setTimeout(() => {
741
  if (!hasStartedProcessing) {
742
+ currentJob?.cancel();
743
+ throw new Error("Server is busy or no GPU available (Queue Timeout). لطفا مجددا تلاش کنید.");
744
  }
745
  }, QUEUE_TIMEOUT);
746
 
747
+ let finalResult = null;
748
+ for await (const status of currentJob) {
749
+ if (status.type === "status") {
750
+ if (status.stage === "pending" || status.stage === "queued") {
751
+ setAiLoaderText(`در صف پردازش... (نفر ${status.queue_position || '?'})`);
752
+ } else if (status.stage === "generating" || status.stage === "iterating") {
753
+ if (!hasStartedProcessing) {
754
+ hasStartedProcessing = true;
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
+ globalTimeout = setTimeout(() => {
771
+ currentJob?.cancel();
772
+ }, GLOBAL_TIMEOUT);
 
 
773
 
774
+ const result = await videoGenerationPromise;
775
+ clearTimeout(globalTimeout);
 
 
 
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
  }