Ezmary commited on
Commit
7d4b9e3
·
verified ·
1 Parent(s): 78aa2a2

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +47 -44
templates/index.html CHANGED
@@ -20,6 +20,8 @@
20
  --accent-primary-hover: #3553D6;
21
  --accent-primary-glow: rgba(74, 108, 250, 0.25);
22
  --accent-secondary: #0FD4A8;
 
 
23
  --success-color: #38A169;
24
  --danger-color: #e53e3e;
25
  --danger-color-hover: #c53030;
@@ -50,6 +52,7 @@
50
  @keyframes background-pan { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
51
  @keyframes igadlmAlphaV2fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
52
  @keyframes fill-progress { from { width: 0%; } to { width: 100%; } }
 
53
 
54
  body { font-family: var(--app-font); background-color: var(--app-bg); color: var(--text-primary); margin: 0; padding: 2.5rem 1rem; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; }
55
  .container { max-width: 820px; width: 100%; }
@@ -68,10 +71,6 @@
68
  h1 { font-size: 2.8rem; font-weight: 800; margin: 0; background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -1px; }
69
  .subtitle { font-size: 1.1rem; color: var(--text-secondary); margin-top: 0.5rem; }
70
  .instruction { font-size: 0.95rem; color: var(--text-tertiary); margin-top: 0.75rem; font-weight: 500; }
71
- /* [جدید] استایل برای متن زیرنویس نسخه */
72
- .header-version-info { margin-top: 1rem; font-size: 0.9rem; color: var(--text-tertiary); }
73
- .header-version-info span { font-weight: 600; color: var(--text-secondary); }
74
-
75
  main { padding: 3rem; background-color: var(--panel-bg); border-radius: var(--radius-card); box-shadow: var(--shadow-xl); border: 1px solid var(--panel-border); animation: fadeIn 0.8s 0.3s ease-out backwards; }
76
  .form-group { margin-bottom: 2.5rem; }
77
  .form-group:last-child { margin-bottom: 0; }
@@ -141,14 +140,16 @@
141
  .gpu-error-actions .action-button.back-button:hover:not(:disabled) { background-color: var(--input-bg); }
142
  .gpu-error-actions .action-button.retry-button { background: linear-gradient(60deg, var(--igadlm-alpha-color-primary) 0%, var(--igadlm-alpha-color-secondary) 100%); color: white; flex-grow: 1; }
143
  .gpu-error-actions .action-button.retry-button:hover:not(:disabled) { background: linear-gradient(60deg, var(--igadlm-alpha-color-primary-darker) 0%, var(--igadlm-alpha-color-secondary-darker) 100%); }
 
 
 
 
 
 
144
  #credit-info-section { margin-top: 1.5rem; margin-bottom: 0.5rem; padding: 1rem; background-color: var(--input-bg); border-radius: var(--radius-input); text-align: center; font-size: 0.95rem; font-weight: 500; color: var(--text-secondary); border: 1px solid var(--input-border); display: none; }
145
  #upgrade-button { margin-top: 1rem; width: 100%; padding: 1rem; font-size: 1.1rem; font-weight: 700; background: linear-gradient(95deg, #FFD54F, #FFC107 100%); color: #212529; border: none; border-radius: var(--radius-btn); cursor: pointer; box-shadow: 0 8px 20px -5px rgba(255, 193, 7, 0.3); display: none; }
146
 
147
- @media (max-width: 768px) {
148
- main { padding: 1.5rem; } h1 { font-size: 2.2rem; }
149
- .generator-container { height: 250px; }
150
- .text-overlay { font-size: 18px; }
151
- }
152
  </style>
153
  </head>
154
  <body>
@@ -169,11 +170,9 @@
169
  </div>
170
  <h1>استودیو ویدیو هوش مصنوعی</h1>
171
  <p class="subtitle">تصاویر خود را با قدرت هوش مصنوعی به ویدیو سینمایی تبدیل کنید</p>
172
- <p class="instruction">ابتدا تصویر خود را با فلاکس پرو تولید کنید و بعد تصویر خود را اینجا آپلود کرده و ویدیوی خود را بسازید</p>
173
- <!-- [جدید] بخش نمایش نسخ�� -->
174
- <div class="header-version-info">
175
- <span>نسخه رایگان</span> و <span>نسخه نامحدود</span>
176
- </div>
177
  </div>
178
  </header>
179
 
@@ -255,7 +254,7 @@
255
  import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
256
 
257
  (function() {
258
- // === START: بخش ارتباط با Iframe و مدیریت اعتبار ===
259
  let userSubscriptionStatus = 'free'; // 'free' or 'paid'
260
  let userFingerprint = null;
261
  let countdownInterval = null;
@@ -287,15 +286,21 @@
287
  const creditInfoDiv = document.getElementById('credit-info-section');
288
  const upgradeBtn = document.getElementById('upgrade-button');
289
  const genBtn = document.getElementById('generateButton');
 
290
 
291
  if (status === 'paid') {
 
 
292
  creditInfoDiv.style.display = 'none';
293
  upgradeBtn.style.display = 'none';
294
  genBtn.disabled = false;
295
  if(countdownInterval) clearInterval(countdownInterval);
296
  } else {
 
 
297
  checkFreeUserCredit();
298
  }
 
299
  }
300
 
301
  async function checkFreeUserCredit() {
@@ -368,7 +373,7 @@
368
  document.getElementById('upgrade-button').addEventListener('click', () => {
369
  parent.postMessage({ type: 'NAVIGATE_TO_PREMIUM' }, '*');
370
  });
371
- // === END: بخش ارتباط و اعتبار ===
372
 
373
 
374
  // DOM Elements
@@ -410,7 +415,6 @@
410
  showCriticalError("اطلاعات کافی برای تلاش مجدد وجود ندارد. لطفاً از نو شروع کنید.");
411
  return;
412
  }
413
- promptInput.value = lastAttemptedVideoPayload.persianPrompt;
414
  generateButton.click();
415
  }
416
 
@@ -513,10 +517,29 @@
513
  return;
514
  }
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  addStatusMessage('ویدیو آماده شد! 🎉', 'success');
517
  const videoUrl = result.data[0].video.url;
518
  const usedSeed = result.data[1];
519
-
520
  setTimeout(() => {
521
  statusSection.classList.remove('active');
522
  outputSection.classList.add('active');
@@ -524,27 +547,6 @@
524
  finalSeedElement.textContent = `Seed: ${usedSeed}`;
525
  prepareCustomDownloadLink(videoUrl);
526
  }, 300);
527
-
528
- // [تغییر اصلی] کسر اعتبار فقط پس از موفقیت
529
- if (userSubscriptionStatus === 'free') {
530
- try {
531
- const response = await fetch('/api/use-credit', {
532
- method: 'POST',
533
- headers: {'Content-Type': 'application/json'},
534
- body: JSON.stringify({ fingerprint: userFingerprint })
535
- });
536
- if (response.ok) {
537
- console.log('Credit used successfully.');
538
- // بروزرسانی نمایش اعتبار باقی‌مانده
539
- checkFreeUserCredit();
540
- } else {
541
- console.warn('Could not use credit after successful generation.');
542
- }
543
- } catch (err) {
544
- console.error('Error while using credit:', err);
545
- }
546
- }
547
-
548
  generateButton.disabled = false;
549
  }
550
 
@@ -615,14 +617,16 @@
615
  negative_prompt: DEFAULT_NEGATIVE_PROMPT, duration_seconds: DEFAULT_VIDEO_DURATION,
616
  guidance_scale: 1, guidance_scale_2: 1, seed: 0, randomize_seed: true
617
  });
618
- handleSuccessfulVideoGeneration(result);
 
 
 
619
  } catch (errorCaught) {
620
  const isTranslationErr = errorCaught.message.toLowerCase().includes("مترجم");
621
  showCriticalError(`خطا: ${errorCaught.message}`, isTranslationErr);
622
  }
623
  };
624
 
625
- // [تغییر اصلی] بازنویسی منطق دکمه ساخت ویدیو
626
  generateButton.addEventListener('click', async () => {
627
  if (generateButton.disabled) return;
628
 
@@ -637,9 +641,8 @@
637
  body: JSON.stringify({ fingerprint: userFingerprint })
638
  });
639
  const result = await response.json();
640
-
641
- if (result.limit_reached) {
642
- checkFreeUserCredit(); // UI را با پیام اتمام اعتبار آپدیت می‌کند
643
  return;
644
  }
645
  // اگر اعتبار داشت، فرآیند ساخت را شروع می‌کنیم
 
20
  --accent-primary-hover: #3553D6;
21
  --accent-primary-glow: rgba(74, 108, 250, 0.25);
22
  --accent-secondary: #0FD4A8;
23
+ --accent-premium: #FFC107;
24
+ --accent-premium-glow: rgba(255, 193, 7, 0.3);
25
  --success-color: #38A169;
26
  --danger-color: #e53e3e;
27
  --danger-color-hover: #c53030;
 
52
  @keyframes background-pan { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
53
  @keyframes igadlmAlphaV2fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
54
  @keyframes fill-progress { from { width: 0%; } to { width: 100%; } }
55
+ @keyframes badge-fade-in { from { opacity: 0; transform: translateY(-10px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } }
56
 
57
  body { font-family: var(--app-font); background-color: var(--app-bg); color: var(--text-primary); margin: 0; padding: 2.5rem 1rem; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; }
58
  .container { max-width: 820px; width: 100%; }
 
71
  h1 { font-size: 2.8rem; font-weight: 800; margin: 0; background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -1px; }
72
  .subtitle { font-size: 1.1rem; color: var(--text-secondary); margin-top: 0.5rem; }
73
  .instruction { font-size: 0.95rem; color: var(--text-tertiary); margin-top: 0.75rem; font-weight: 500; }
 
 
 
 
74
  main { padding: 3rem; background-color: var(--panel-bg); border-radius: var(--radius-card); box-shadow: var(--shadow-xl); border: 1px solid var(--panel-border); animation: fadeIn 0.8s 0.3s ease-out backwards; }
75
  .form-group { margin-bottom: 2.5rem; }
76
  .form-group:last-child { margin-bottom: 0; }
 
140
  .gpu-error-actions .action-button.back-button:hover:not(:disabled) { background-color: var(--input-bg); }
141
  .gpu-error-actions .action-button.retry-button { background: linear-gradient(60deg, var(--igadlm-alpha-color-primary) 0%, var(--igadlm-alpha-color-secondary) 100%); color: white; flex-grow: 1; }
142
  .gpu-error-actions .action-button.retry-button:hover:not(:disabled) { background: linear-gradient(60deg, var(--igadlm-alpha-color-primary-darker) 0%, var(--igadlm-alpha-color-secondary-darker) 100%); }
143
+
144
+ /* بخش جدید: استایل‌های مربوط به اعتبار و اشتراک */
145
+ #subscription-status-badge { display: none; padding: 6px 16px; border-radius: 20px; font-size: 0.9em; font-weight: 700; margin-top: 1.25rem; letter-spacing: 0.5px; animation: badge-fade-in 0.6s 0.5s ease-out backwards; }
146
+ #subscription-status-badge.free-badge { background: linear-gradient(45deg, #6c757d, #495057); color: white; box-shadow: 0 4px 10px rgba(108, 117, 125, 0.3); }
147
+ #subscription-status-badge.paid-badge { background: linear-gradient(45deg, var(--accent-premium), #ffca2c); color: #333; box-shadow: 0 4px 10px var(--accent-premium-glow); }
148
+
149
  #credit-info-section { margin-top: 1.5rem; margin-bottom: 0.5rem; padding: 1rem; background-color: var(--input-bg); border-radius: var(--radius-input); text-align: center; font-size: 0.95rem; font-weight: 500; color: var(--text-secondary); border: 1px solid var(--input-border); display: none; }
150
  #upgrade-button { margin-top: 1rem; width: 100%; padding: 1rem; font-size: 1.1rem; font-weight: 700; background: linear-gradient(95deg, #FFD54F, #FFC107 100%); color: #212529; border: none; border-radius: var(--radius-btn); cursor: pointer; box-shadow: 0 8px 20px -5px rgba(255, 193, 7, 0.3); display: none; }
151
 
152
+ @media (max-width: 768px) { main { padding: 1.5rem; } h1 { font-size: 2.2rem; } .generator-container { height: 250px; } .text-overlay { font-size: 18px; } }
 
 
 
 
153
  </style>
154
  </head>
155
  <body>
 
170
  </div>
171
  <h1>استودیو ویدیو هوش مصنوعی</h1>
172
  <p class="subtitle">تصاویر خود را با قدرت هوش مصنوعی به ویدیو سینمایی تبدیل کنید</p>
173
+ <!-- بخش جدید: متن راهنما و بج وضعیت اشتراک -->
174
+ <p class="instruction">ابتدا تصویر خود را با فلاکس پرو تولید کنید و بعد تصویر خود را اینجا آپلود کرده و ویدیوی خود را بسازید.</p>
175
+ <div id="subscription-status-badge" style="display:inline-block;"></div>
 
 
176
  </div>
177
  </header>
178
 
 
254
  import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
255
 
256
  (function() {
257
+ // === START: بخش مدیریت اعتبار و ارتباط با والد ===
258
  let userSubscriptionStatus = 'free'; // 'free' or 'paid'
259
  let userFingerprint = null;
260
  let countdownInterval = null;
 
286
  const creditInfoDiv = document.getElementById('credit-info-section');
287
  const upgradeBtn = document.getElementById('upgrade-button');
288
  const genBtn = document.getElementById('generateButton');
289
+ const subscriptionBadge = document.getElementById('subscription-status-badge');
290
 
291
  if (status === 'paid') {
292
+ subscriptionBadge.textContent = 'نسخه نامحدود';
293
+ subscriptionBadge.className = 'paid-badge';
294
  creditInfoDiv.style.display = 'none';
295
  upgradeBtn.style.display = 'none';
296
  genBtn.disabled = false;
297
  if(countdownInterval) clearInterval(countdownInterval);
298
  } else {
299
+ subscriptionBadge.textContent = 'نسخه رایگان';
300
+ subscriptionBadge.className = 'free-badge';
301
  checkFreeUserCredit();
302
  }
303
+ subscriptionBadge.style.display = 'inline-block';
304
  }
305
 
306
  async function checkFreeUserCredit() {
 
373
  document.getElementById('upgrade-button').addEventListener('click', () => {
374
  parent.postMessage({ type: 'NAVIGATE_TO_PREMIUM' }, '*');
375
  });
376
+ // === END: بخش مدیریت اعتبار ===
377
 
378
 
379
  // DOM Elements
 
415
  showCriticalError("اطلاعات کافی برای تلاش مجدد وجود ندارد. لطفاً از نو شروع کنید.");
416
  return;
417
  }
 
418
  generateButton.click();
419
  }
420
 
 
517
  return;
518
  }
519
 
520
+ // === تغییر اصلی: کسر اعتبار بعد از موفقیت ===
521
+ if (userSubscriptionStatus === 'free') {
522
+ try {
523
+ addStatusMessage('ویدیو ساخته شد، در حال ثبت اعتبار...', 'info');
524
+ const creditResponse = await fetch('/api/use-credit', {
525
+ method: 'POST',
526
+ headers: {'Content-Type': 'application/json'},
527
+ body: JSON.stringify({ fingerprint: userFingerprint })
528
+ });
529
+ if (!creditResponse.ok) {
530
+ console.warn("Credit deduction failed AFTER video generation.");
531
+ }
532
+ // UI را با تعداد اعتبار جدید بروزرسانی می‌کنیم
533
+ checkFreeUserCredit();
534
+ } catch (creditError) {
535
+ console.error("Critical error deducting credit:", creditError);
536
+ }
537
+ }
538
+ // === پایان تغییر ===
539
+
540
  addStatusMessage('ویدیو آماده شد! 🎉', 'success');
541
  const videoUrl = result.data[0].video.url;
542
  const usedSeed = result.data[1];
 
543
  setTimeout(() => {
544
  statusSection.classList.remove('active');
545
  outputSection.classList.add('active');
 
547
  finalSeedElement.textContent = `Seed: ${usedSeed}`;
548
  prepareCustomDownloadLink(videoUrl);
549
  }, 300);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  generateButton.disabled = false;
551
  }
552
 
 
617
  negative_prompt: DEFAULT_NEGATIVE_PROMPT, duration_seconds: DEFAULT_VIDEO_DURATION,
618
  guidance_scale: 1, guidance_scale_2: 1, seed: 0, randomize_seed: true
619
  });
620
+
621
+ // حالا این تابع مسئول کسر اعتبار هم هست
622
+ await handleSuccessfulVideoGeneration(result);
623
+
624
  } catch (errorCaught) {
625
  const isTranslationErr = errorCaught.message.toLowerCase().includes("مترجم");
626
  showCriticalError(`خطا: ${errorCaught.message}`, isTranslationErr);
627
  }
628
  };
629
 
 
630
  generateButton.addEventListener('click', async () => {
631
  if (generateButton.disabled) return;
632
 
 
641
  body: JSON.stringify({ fingerprint: userFingerprint })
642
  });
643
  const result = await response.json();
644
+ if(result.limit_reached) {
645
+ updateUIForSubscriptionStatus('free'); // UI را با پیام اتمام اعتبار آپدیت می‌کند
 
646
  return;
647
  }
648
  // اگر اعتبار داشت، فرآیند ساخت را شروع می‌کنیم