Sada8888 commited on
Commit
9f8d315
·
verified ·
1 Parent(s): e296870

Update templates/video.html

Browse files
Files changed (1) hide show
  1. templates/video.html +5 -315
templates/video.html CHANGED
@@ -234,106 +234,6 @@
234
  .frame-preview-item span { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }
235
  #frame-loader { border: 4px solid var(--input-border); border-top: 4px solid var(--accent-primary); border-radius: 50%; width: 40px; height: 40px; animation: ring-rotate 1s linear infinite; margin: 2rem auto; }
236
 
237
- /* استایل‌های سابقه تصاویر */
238
- .history-item {
239
- background: var(--panel-bg);
240
- border: 1px solid var(--panel-border);
241
- border-radius: var(--radius-input);
242
- padding: 0.75rem;
243
- box-shadow: var(--shadow-sm);
244
- display: flex;
245
- flex-direction: column;
246
- gap: 0.75rem;
247
- transition: var(--transition-smooth);
248
- }
249
- .history-item:hover {
250
- box-shadow: var(--shadow-md);
251
- border-color: var(--accent-primary);
252
- }
253
- .history-item img {
254
- width: 100%;
255
- height: 160px;
256
- object-fit: cover;
257
- border-radius: 8px;
258
- cursor: pointer;
259
- transition: var(--transition-smooth);
260
- }
261
- .history-item img:hover {
262
- filter: brightness(0.9);
263
- }
264
- .history-item-details {
265
- font-size: 0.85rem;
266
- color: var(--text-secondary);
267
- display: flex;
268
- flex-direction: column;
269
- gap: 0.3rem;
270
- }
271
- .history-item-prompt {
272
- font-weight: 700;
273
- color: var(--text-primary);
274
- white-space: nowrap;
275
- overflow: hidden;
276
- text-overflow: ellipsis;
277
- margin-bottom: 0.2rem;
278
- }
279
- .history-item-meta {
280
- display: flex;
281
- justify-content: space-between;
282
- background: var(--input-bg);
283
- padding: 0.2rem 0.5rem;
284
- border-radius: 4px;
285
- font-size: 0.8rem;
286
- }
287
- .history-item-meta span {
288
- font-weight: 600;
289
- color: var(--accent-primary);
290
- }
291
- .history-delete-btn {
292
- position: absolute;
293
- top: 50%;
294
- left: 50%;
295
- transform: translate(-50%, -50%);
296
- width: 44px;
297
- height: 44px;
298
- background-color: rgba(229, 62, 62, 0.9);
299
- color: white;
300
- border: none;
301
- border-radius: 50%;
302
- display: flex;
303
- align-items: center;
304
- justify-content: center;
305
- cursor: pointer;
306
- opacity: 0;
307
- visibility: hidden;
308
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
309
- box-shadow: 0 4px 12px rgba(0,0,0,0.3);
310
- z-index: 10;
311
- }
312
- .history-delete-btn:hover {
313
- background-color: var(--danger-color-hover);
314
- transform: translate(-50%, -50%) scale(1.15);
315
- }
316
- #clear-history-btn {
317
- display: inline-flex;
318
- align-items: center;
319
- justify-content: center;
320
- padding: 0.5rem 1rem;
321
- border-radius: var(--radius-btn);
322
- border: 1px solid var(--danger-color);
323
- background: transparent;
324
- color: var(--danger-color);
325
- font-family: var(--app-font);
326
- font-weight: 600;
327
- font-size: 0.9rem;
328
- cursor: pointer;
329
- transition: var(--transition-smooth);
330
- }
331
- #clear-history-btn:hover {
332
- background-color: var(--danger-color);
333
- color: white !important;
334
- transform: translateY(-2px);
335
- }
336
-
337
  @media (max-width: 768px) { main { padding: 3rem 1.5rem; } h1 { font-size: 2.2rem; } .generator-container { height: 250px; } .text-overlay { font-size: 18px; } #previous-results-wrapper { grid-template-columns: 1fr; } }
338
  </style>
339
  </head>
@@ -442,23 +342,6 @@
442
  </div>
443
  </div>
444
  </div>
445
-
446
- <!-- بخش جدید سابقه تصاویر ساخته شده -->
447
- <div class="form-group" style="margin-top: 3.5rem;">
448
- <div class="form-label" style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
449
- <div style="display: flex; align-items: center; gap: 0.75rem;">
450
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>
451
- سابقه تصاویر ساخته شده
452
- </div>
453
- <button id="clear-history-btn">
454
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
455
- حذف همه
456
- </button>
457
- </div>
458
- <div id="image-history-container" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; margin-top: 1.5rem;">
459
- <!-- آیتم‌های سابقه از طریق JS لود می‌شوند -->
460
- </div>
461
- </div>
462
 
463
  <div id="restart-section" style="display: none; text-align: center; margin-top: 2rem;">
464
  <button id="btnRestart" class="video-button">
@@ -558,80 +441,10 @@
558
  // --- دیتابیس حافظه مرورگر برای ذخیره سوابق ---
559
  const projectDB = {
560
  db: null,
561
- init() { return new Promise((resolve, reject) => {
562
- const request = indexedDB.open('AIStudioDB_V2', 2);
563
- request.onupgradeneeded = event => {
564
- const db = event.target.result;
565
- if (!db.objectStoreNames.contains('projectState')) {
566
- db.createObjectStore('projectState');
567
- }
568
- if (!db.objectStoreNames.contains('imageHistory')) {
569
- db.createObjectStore('imageHistory', { keyPath: 'id' });
570
- }
571
- };
572
- request.onsuccess = event => { this.db = event.target.result; resolve(); };
573
- request.onerror = event => { console.error('IndexedDB error:', event.target.errorCode); reject(event.target.errorCode); };
574
- }); },
575
  save(key, value) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readwrite'); const store = transaction.objectStore('projectState'); const request = store.put(value, key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); },
576
  get(key) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readonly'); const store = transaction.objectStore('projectState'); const request = store.get(key); request.onsuccess = () => resolve(request.result); request.onerror = (event) => reject(event.target.error); }); },
577
- delete(key) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readwrite'); const store = transaction.objectStore('projectState'); const request = store.delete(key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); },
578
-
579
- // --- بخش توابع سابقه تصاویر ساخته شده ---
580
- saveHistoryImage(item) {
581
- return new Promise(async (resolve, reject) => {
582
- try {
583
- const allItems = await this.getHistoryImages();
584
- const transaction = this.db.transaction(['imageHistory'], 'readwrite');
585
- const store = transaction.objectStore('imageHistory');
586
-
587
- // نگهداری فقط 50 مورد آخر
588
- if (allItems.length >= 50) {
589
- const itemsToDelete = allItems.slice(49);
590
- for (const oldItem of itemsToDelete) {
591
- store.delete(oldItem.id);
592
- }
593
- }
594
-
595
- const request = store.put(item);
596
- request.onsuccess = () => resolve();
597
- request.onerror = (event) => reject(event.target.error);
598
- } catch (err) {
599
- reject(err);
600
- }
601
- });
602
- },
603
- getHistoryImages() {
604
- return new Promise((resolve, reject) => {
605
- if (!this.db) return reject("DB not initialized");
606
- const transaction = this.db.transaction(['imageHistory'], 'readonly');
607
- const store = transaction.objectStore('imageHistory');
608
- const request = store.getAll();
609
- request.onsuccess = () => {
610
- let items = request.result;
611
- items.sort((a, b) => b.timestamp - a.timestamp); // نزولی بر اساس زمان
612
- resolve(items);
613
- };
614
- request.onerror = (event) => reject(event.target.error);
615
- });
616
- },
617
- deleteHistoryImage(id) {
618
- return new Promise((resolve, reject) => {
619
- const transaction = this.db.transaction(['imageHistory'], 'readwrite');
620
- const store = transaction.objectStore('imageHistory');
621
- const request = store.delete(id);
622
- request.onsuccess = () => resolve();
623
- request.onerror = (event) => reject(event.target.error);
624
- });
625
- },
626
- clearAllHistoryImages() {
627
- return new Promise((resolve, reject) => {
628
- const transaction = this.db.transaction(['imageHistory'], 'readwrite');
629
- const store = transaction.objectStore('imageHistory');
630
- const request = store.clear();
631
- request.onsuccess = () => resolve();
632
- request.onerror = (event) => reject(event.target.error);
633
- });
634
- }
635
  };
636
 
637
  // --- سیستم احراز و اعتبار ---
@@ -786,18 +599,6 @@
786
  statusMessagesDiv.innerHTML = '';
787
  clearInterval(fakeProgressInterval);
788
  tvProgressBar.style.width = '0%';
789
-
790
- // بازگردانی استایل‌های تلویزیون به حالت اولیه
791
- const generatorContainer = document.querySelector('.generator-container');
792
- if(generatorContainer) {
793
- generatorContainer.style.animation = 'pulse-loader 5s infinite cubic-bezier(0.4, 0, 0.6, 1)';
794
- generatorContainer.style.boxShadow = '0 0 40px rgba(56, 189, 248, 0.3)';
795
- generatorContainer.style.borderColor = '#38bdf8';
796
- }
797
- const particles = document.querySelector('.particles');
798
- if(particles) particles.style.display = 'block';
799
- loaderTextOverlay.textContent = "در حال پردازش ویدیو...";
800
-
801
  aiLoader.style.display = 'none';
802
  }
803
 
@@ -1109,18 +910,8 @@
1109
 
1110
  setTimeout(() => {
1111
  gallerySeparator.style.display = 'none';
1112
-
1113
- // جلوگیری از محو شدن تلویزیون و نمایش موفقیت
1114
- loaderTextOverlay.textContent = "ویدیوی شما آماده است!";
1115
- const generatorContainer = document.querySelector('.generator-container');
1116
- if(generatorContainer) {
1117
- generatorContainer.style.animation = 'none';
1118
- generatorContainer.style.boxShadow = '0 0 30px rgba(15, 212, 168, 0.4)';
1119
- generatorContainer.style.borderColor = 'var(--success-color)';
1120
- }
1121
- const particles = document.querySelector('.particles');
1122
- if(particles) particles.style.display = 'none';
1123
-
1124
  restartSection.style.display = 'block';
1125
  setUiLock(false);
1126
  setGenerateButtonState("ساخت ویدیو جادویی", false);
@@ -1330,111 +1121,10 @@
1330
  } catch(error) { console.error("Could not load project from DB:", error); }
1331
  }
1332
 
1333
- // --- توابع رابط کاربری سابقه تصاویر ---
1334
- async function loadHistoryImages() {
1335
- try {
1336
- const images = await projectDB.getHistoryImages();
1337
- const container = document.getElementById('image-history-container');
1338
- container.innerHTML = '';
1339
-
1340
- if (images.length === 0) {
1341
- container.innerHTML = '<p style="grid-column: 1 / -1; text-align: center; color: var(--text-tertiary); background: var(--input-bg); padding: 2rem; border-radius: var(--radius-card); border: 2px dashed var(--input-border);">سابقه‌ای وجود ندارد</p>';
1342
- return;
1343
- }
1344
-
1345
- images.forEach(item => {
1346
- const div = document.createElement('div');
1347
- div.className = 'history-item';
1348
-
1349
- const objectURL = URL.createObjectURL(item.blob);
1350
-
1351
- div.innerHTML = `
1352
- <div style="position: relative;">
1353
- <img src="${objectURL}" alt="Generated Image" onclick="toggleDeleteBtn(this)">
1354
- <button class="history-delete-btn" title="حذف تصویر" onclick="deleteHistoryItem(${item.id}, this)">
1355
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 20px; height: 20px;"><path d="M3 6h18"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
1356
- </button>
1357
- </div>
1358
- <div class="history-item-details">
1359
- <div class="history-item-prompt" title="${item.prompt || ''}">${item.prompt || 'بدون متن'}</div>
1360
- <div class="history-item-meta">مدل: <span>${item.model || 'نامشخص'}</span></div>
1361
- <div class="history-item-meta">اندازه: <span>${item.size || 'نامشخص'}</span></div>
1362
- </div>
1363
- `;
1364
- container.appendChild(div);
1365
- });
1366
- } catch (err) {
1367
- console.error('Error loading history:', err);
1368
- }
1369
- }
1370
-
1371
- window.toggleDeleteBtn = function(imgElement) {
1372
- const btn = imgElement.nextElementSibling;
1373
- const allBtns = document.querySelectorAll('.history-delete-btn');
1374
-
1375
- allBtns.forEach(b => {
1376
- if (b !== btn) {
1377
- b.style.opacity = '0';
1378
- b.style.visibility = 'hidden';
1379
- }
1380
- });
1381
-
1382
- if (btn.style.opacity === '1') {
1383
- btn.style.opacity = '0';
1384
- btn.style.visibility = 'hidden';
1385
- } else {
1386
- btn.style.opacity = '1';
1387
- btn.style.visibility = 'visible';
1388
- }
1389
- };
1390
-
1391
- window.deleteHistoryItem = async function(id, btnElement) {
1392
- try {
1393
- await projectDB.deleteHistoryImage(id);
1394
- await loadHistoryImages();
1395
- } catch (err) {
1396
- console.error('Error deleting item:', err);
1397
- }
1398
- };
1399
-
1400
- document.getElementById('clear-history-btn').addEventListener('click', async () => {
1401
- if (confirm('آیا از حذف تمام تصاویر سابقه اطمینان دارید؟')) {
1402
- try {
1403
- await projectDB.clearAllHistoryImages();
1404
- await loadHistoryImages();
1405
- } catch (err) {
1406
- console.error('Error clearing history:', err);
1407
- }
1408
- }
1409
- });
1410
-
1411
- // این تابع به صورت گلوبال در دسترس است تا از سایر بخش‌ها بتوان تصاویر جدید را به سابقه اضافه کرد
1412
- window.addGeneratedImageToHistory = async function(blob, prompt, model, size) {
1413
- const item = {
1414
- id: Date.now(),
1415
- timestamp: Date.now(),
1416
- blob: blob,
1417
- prompt: prompt || 'بدون متن',
1418
- model: model || 'نامشخص',
1419
- size: size || 'نامشخص'
1420
- };
1421
- try {
1422
- await projectDB.saveHistoryImage(item);
1423
- await loadHistoryImages();
1424
- } catch (e) {
1425
- console.error("Error saving image to history:", e);
1426
- }
1427
- };
1428
-
1429
  document.addEventListener('DOMContentLoaded', async () => {
1430
  userFingerprint = await getBrowserFingerprint();
1431
  parent.postMessage({ type: 'REQUEST_USER_DATA' }, '*');
1432
- try {
1433
- await projectDB.init();
1434
- await initializeForm();
1435
- await loadStoredProject();
1436
- await loadHistoryImages();
1437
- }
1438
  catch (error) { console.error("Failed to init DB or load project:", error); }
1439
  });
1440
 
 
234
  .frame-preview-item span { font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }
235
  #frame-loader { border: 4px solid var(--input-border); border-top: 4px solid var(--accent-primary); border-radius: 50%; width: 40px; height: 40px; animation: ring-rotate 1s linear infinite; margin: 2rem auto; }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  @media (max-width: 768px) { main { padding: 3rem 1.5rem; } h1 { font-size: 2.2rem; } .generator-container { height: 250px; } .text-overlay { font-size: 18px; } #previous-results-wrapper { grid-template-columns: 1fr; } }
238
  </style>
239
  </head>
 
342
  </div>
343
  </div>
344
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
 
346
  <div id="restart-section" style="display: none; text-align: center; margin-top: 2rem;">
347
  <button id="btnRestart" class="video-button">
 
441
  // --- دیتابیس حافظه مرورگر برای ذخیره سوابق ---
442
  const projectDB = {
443
  db: null,
444
+ init() { return new Promise((resolve, reject) => { const request = indexedDB.open('AIStudioDB_V2', 1); request.onupgradeneeded = event => { const db = event.target.result; if (!db.objectStoreNames.contains('projectState')) { db.createObjectStore('projectState'); } }; request.onsuccess = event => { this.db = event.target.result; resolve(); }; request.onerror = event => { console.error('IndexedDB error:', event.target.errorCode); reject(event.target.errorCode); }; }); },
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  save(key, value) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readwrite'); const store = transaction.objectStore('projectState'); const request = store.put(value, key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); },
446
  get(key) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readonly'); const store = transaction.objectStore('projectState'); const request = store.get(key); request.onsuccess = () => resolve(request.result); request.onerror = (event) => reject(event.target.error); }); },
447
+ delete(key) { return new Promise((resolve, reject) => { if (!this.db) return reject("DB not initialized"); const transaction = this.db.transaction(['projectState'], 'readwrite'); const store = transaction.objectStore('projectState'); const request = store.delete(key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
448
  };
449
 
450
  // --- سیستم احراز و اعتبار ---
 
599
  statusMessagesDiv.innerHTML = '';
600
  clearInterval(fakeProgressInterval);
601
  tvProgressBar.style.width = '0%';
 
 
 
 
 
 
 
 
 
 
 
 
602
  aiLoader.style.display = 'none';
603
  }
604
 
 
910
 
911
  setTimeout(() => {
912
  gallerySeparator.style.display = 'none';
913
+ statusSection.classList.remove('active');
914
+ aiLoader.style.display = 'none';
 
 
 
 
 
 
 
 
 
 
915
  restartSection.style.display = 'block';
916
  setUiLock(false);
917
  setGenerateButtonState("ساخت ویدیو جادویی", false);
 
1121
  } catch(error) { console.error("Could not load project from DB:", error); }
1122
  }
1123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1124
  document.addEventListener('DOMContentLoaded', async () => {
1125
  userFingerprint = await getBrowserFingerprint();
1126
  parent.postMessage({ type: 'REQUEST_USER_DATA' }, '*');
1127
+ try { await projectDB.init(); await initializeForm(); await loadStoredProject(); }
 
 
 
 
 
1128
  catch (error) { console.error("Failed to init DB or load project:", error); }
1129
  });
1130