Elias207 commited on
Commit
f23f2c3
·
verified ·
1 Parent(s): b594b50

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +95 -76
index.html CHANGED
@@ -115,52 +115,14 @@
115
  cursor: default;
116
  }
117
 
118
- #upload-content {
119
- display: flex;
120
- flex-direction: column;
121
- align-items: center;
122
- gap: 1rem;
123
- }
124
  #upload-icon svg { width: 48px; height: 48px; color: var(--accent-primary); stroke-width: 1.5; opacity: 0.8; }
125
  #upload-area p { margin: 0; color: var(--text-secondary); font-weight: 500; }
126
-
127
- #preview-image-main {
128
- display: none;
129
- width: 100%;
130
- height: 100%;
131
- object-fit: contain;
132
- position: absolute;
133
- top: 0;
134
- left: 0;
135
- }
136
- #remove-file-btn-main {
137
- display: none;
138
- position: absolute;
139
- top: 12px;
140
- right: 12px;
141
- background-color: rgba(26, 32, 44, 0.6);
142
- color: white;
143
- border: none;
144
- width: 32px;
145
- height: 32px;
146
- border-radius: 50%;
147
- cursor: pointer;
148
- font-size: 1.2rem;
149
- line-height: 1;
150
- z-index: 10;
151
- transition: var(--transition-smooth);
152
- padding: 0;
153
- }
154
- #remove-file-btn-main:hover {
155
- background-color: var(--danger-color);
156
- transform: scale(1.1);
157
- }
158
-
159
  #upload-area.has-file #upload-content { display: none; }
160
- #upload-area.has-file #preview-image-main,
161
- #upload-area.has-file #remove-file-btn-main {
162
- display: block;
163
- }
164
 
165
  textarea { width: 100%; padding: 1rem 1.2rem; border-radius: var(--radius-input); border: 1px solid var(--input-border); background-color: var(--input-bg); color: var(--text-primary); box-shadow: var(--shadow-sm) inset; font-family: var(--app-font); font-size: 1rem; box-sizing: border-box; transition: var(--transition-smooth); min-height: 90px; resize: vertical; }
166
  textarea:focus { outline: none; border-color: var(--accent-primary); box-shadow: 0 0 0 3px var(--accent-primary-glow), var(--shadow-sm) inset; background-color: var(--panel-bg); }
@@ -192,36 +154,21 @@
192
  #clear-history-btn { background: none; border: 1px solid var(--panel-border); color: var(--text-secondary); padding: 0.5rem 1rem; border-radius: var(--radius-btn); cursor: pointer; display: none; align-items: center; gap: 0.5rem; font-family: var(--app-font); font-weight: 500; transition: all 0.2s; }
193
  #clear-history-btn:hover { border-color: var(--danger-color); color: var(--danger-color); }
194
  #clear-history-btn svg { width: 18px; height: 18px; }
195
-
196
- /* --- CHANGE: The grid of history CARDS is now two-column on ALL screen sizes --- */
197
- #history-grid {
198
- display: grid;
199
- grid-template-columns: repeat(2, 1fr);
200
- gap: 1.5rem;
201
- margin-top: 1.5rem;
202
- }
203
-
204
  #history-grid:empty::before { content: 'هنوز تصویری خلق نکرده‌اید. اولین ویرایش شما اینجا ذخیره خواهد شد.'; color: var(--text-secondary); grid-column: 1 / -1; text-align: center; padding: 3rem 1rem; background-color: var(--input-bg); border-radius: var(--radius-card); }
205
  .history-item { position: relative; background-color: var(--input-bg); border-radius: var(--radius-card); border: 1px solid var(--panel-border); padding: 1.5rem; transition: var(--transition-smooth); display: flex; flex-direction: column; }
206
  .history-item:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
207
- .history-item-prompt { font-weight: 600; margin: 0 0 1rem 0; word-break: break-word; padding-left: 30px; }
208
-
209
- .history-item-grid {
210
- display: grid;
211
- grid-template-columns: repeat(2, 1fr);
212
- gap: 0.75rem;
213
- }
214
-
215
  .history-item-grid img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-input); cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; border: 1px solid var(--panel-border); }
216
  .history-item-grid img:hover { transform: scale(1.1); box-shadow: var(--shadow-md); z-index: 5; position: relative; }
217
- .history-delete-btn { position: absolute; top: 1rem; left: 1rem; background: none; border: none; cursor: pointer; padding: 0.5rem; border-radius: 50%; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--text-tertiary); transition: var(--transition-smooth); }
218
  .history-delete-btn:hover { background-color: var(--panel-border); color: var(--danger-color); }
219
  .history-delete-btn svg { width: 18px; height: 18px; }
220
 
221
  /* --- Lightbox Styles --- */
222
  #lightbox { position: fixed; inset: 0; background-color: rgba(18, 24, 38, 0.6); backdrop-filter: blur(10px) saturate(150%); display: none; align-items: center; justify-content: center; z-index: 1000; opacity: 0; transition: opacity 0.3s; }
223
  #lightbox.visible { display: flex; opacity: 1; }
224
- #lightbox-content { position: relative; animation: fadeIn 0.3s ease; }
225
  #lightbox-img { max-width: 85vw; max-height: 80vh; object-fit: contain; border-radius: var(--radius-card); box-shadow: var(--shadow-xl); }
226
  .lightbox-btn { position: absolute; background-color: rgba(255, 255, 255, 0.1); color: white; border: 1px solid rgba(255,255,255,0.2); width: 44px; height: 44px; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; transition: all 0.2s; text-decoration: none; }
227
  .lightbox-btn:hover { background-color: rgba(255, 255, 255, 0.2); transform: scale(1.1); }
@@ -229,11 +176,27 @@
229
  #lightbox-download { top: -50px; left: 0; }
230
  #lightbox-download svg { width: 22px; height: 22px; }
231
  #lightbox-download .spinner { width: 20px; height: 20px; border: 3px solid rgba(255, 255, 255, 0.4); border-top-color: #fff; border-radius: 50%; animation: spin 0.8s linear infinite; display: none; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
  @media (max-width: 768px) {
234
  main, .gallery-section { padding: 1.5rem; }
235
  h1 { font-size: 2.2rem; }
236
- /* The responsive rule for #history-grid has been REMOVED so it stays 2-column on mobile */
237
  }
238
  </style>
239
  </head>
@@ -306,7 +269,11 @@
306
 
307
  <div id="lightbox">
308
  <div id="lightbox-content">
 
 
309
  <img id="lightbox-img" src="">
 
 
310
  <button id="lightbox-close" class="lightbox-btn">&times;</button>
311
  <button id="lightbox-download" title="دانلود تصویر" class="lightbox-btn">
312
  <svg fill="white" viewBox="0 0 24 24"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg>
@@ -316,7 +283,6 @@
316
  </div>
317
 
318
  <script>
319
- // جاوا اسکریپت بدون تغییر باقی می‌ماند
320
  const API_URL = 'https://alfa-editor-worker.onrender.com/api/edit';
321
 
322
  const uploadArea = document.getElementById('upload-area');
@@ -338,8 +304,12 @@
338
  const historyGrid = document.getElementById('history-grid');
339
  const clearHistoryBtn = document.getElementById('clear-history-btn');
340
 
 
 
 
 
 
341
  let uploadedFile = null;
342
- let currentLightboxUrl = null;
343
 
344
  const resetUploader = () => {
345
  uploadedFile = null;
@@ -419,7 +389,8 @@
419
  const img = document.createElement('img');
420
  img.src = url;
421
  img.alt = 'تصویر ویرایش شده';
422
- img.addEventListener('click', () => openLightbox(url));
 
423
  resultGrid.appendChild(img);
424
  });
425
  resultContainer.classList.add('has-content');
@@ -434,17 +405,47 @@
434
  errorMessage.style.display = 'block';
435
  }
436
 
437
- function openLightbox(url) {
438
- currentLightboxUrl = url;
439
- lightboxImg.src = url;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  lightbox.classList.add('visible');
 
441
  }
 
442
  function closeLightbox() {
443
  lightbox.classList.remove('visible');
444
- currentLightboxUrl = null;
445
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  async function handleDownload() {
447
- if (!currentLightboxUrl) return;
 
448
 
449
  const spinner = lightboxDownload.querySelector('.spinner');
450
  const icon = lightboxDownload.querySelector('svg');
@@ -454,7 +455,7 @@
454
  lightboxDownload.disabled = true;
455
 
456
  try {
457
- const response = await fetch(currentLightboxUrl);
458
  if (!response.ok) throw new Error('Network response was not ok.');
459
  const blob = await response.blob();
460
  const objectUrl = URL.createObjectURL(blob);
@@ -475,7 +476,7 @@
475
  }
476
  }
477
  lightboxClose.addEventListener('click', closeLightbox);
478
- lightbox.addEventListener('click', (e) => { if (e.target === lightbox) closeLightbox(); });
479
  lightboxDownload.addEventListener('click', handleDownload);
480
 
481
  const getHistory = () => JSON.parse(localStorage.getItem('aiPhotoshopHistory') || '[]');
@@ -502,15 +503,33 @@
502
  history.forEach((item, index) => {
503
  const card = document.createElement('div');
504
  card.className = 'history-item';
505
- const imagesHTML = item.urls.map(url => `<img src="${url}" alt="تصویر از تاریخچه" onclick="openLightbox('${url}')">`).join('');
506
- card.innerHTML = `<button class="history-delete-btn" data-index="${index}" title="حذف این مورد"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg></button><p class="history-item-prompt">${item.prompt}</p><div class="history-item-grid">${imagesHTML}</div>`;
 
 
 
 
 
 
507
  historyGrid.appendChild(card);
508
  });
509
  }
510
  clearHistoryBtn.addEventListener('click', handleClearHistory);
 
511
  historyGrid.addEventListener('click', (e) => {
512
  const deleteBtn = e.target.closest('.history-delete-btn');
513
- if (deleteBtn) { handleDeleteItem(parseInt(deleteBtn.dataset.index, 10)); }
 
 
 
 
 
 
 
 
 
 
 
514
  });
515
  document.addEventListener('DOMContentLoaded', () => { renderHistory(); checkFormState(); });
516
  </script>
 
115
  cursor: default;
116
  }
117
 
118
+ #upload-content { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
 
 
 
 
 
119
  #upload-icon svg { width: 48px; height: 48px; color: var(--accent-primary); stroke-width: 1.5; opacity: 0.8; }
120
  #upload-area p { margin: 0; color: var(--text-secondary); font-weight: 500; }
121
+ #preview-image-main { display: none; width: 100%; height: 100%; object-fit: contain; position: absolute; top: 0; left: 0; }
122
+ #remove-file-btn-main { display: none; position: absolute; top: 12px; right: 12px; background-color: rgba(26, 32, 44, 0.6); color: white; border: none; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; font-size: 1.2rem; line-height: 1; z-index: 10; transition: var(--transition-smooth); padding: 0; }
123
+ #remove-file-btn-main:hover { background-color: var(--danger-color); transform: scale(1.1); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  #upload-area.has-file #upload-content { display: none; }
125
+ #upload-area.has-file #preview-image-main, #upload-area.has-file #remove-file-btn-main { display: block; }
 
 
 
126
 
127
  textarea { width: 100%; padding: 1rem 1.2rem; border-radius: var(--radius-input); border: 1px solid var(--input-border); background-color: var(--input-bg); color: var(--text-primary); box-shadow: var(--shadow-sm) inset; font-family: var(--app-font); font-size: 1rem; box-sizing: border-box; transition: var(--transition-smooth); min-height: 90px; resize: vertical; }
128
  textarea:focus { outline: none; border-color: var(--accent-primary); box-shadow: 0 0 0 3px var(--accent-primary-glow), var(--shadow-sm) inset; background-color: var(--panel-bg); }
 
154
  #clear-history-btn { background: none; border: 1px solid var(--panel-border); color: var(--text-secondary); padding: 0.5rem 1rem; border-radius: var(--radius-btn); cursor: pointer; display: none; align-items: center; gap: 0.5rem; font-family: var(--app-font); font-weight: 500; transition: all 0.2s; }
155
  #clear-history-btn:hover { border-color: var(--danger-color); color: var(--danger-color); }
156
  #clear-history-btn svg { width: 18px; height: 18px; }
157
+ #history-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; margin-top: 1.5rem; }
 
 
 
 
 
 
 
 
158
  #history-grid:empty::before { content: 'هنوز تصویری خلق نکرده‌اید. اولین ویرایش شما اینجا ذخیره خواهد شد.'; color: var(--text-secondary); grid-column: 1 / -1; text-align: center; padding: 3rem 1rem; background-color: var(--input-bg); border-radius: var(--radius-card); }
159
  .history-item { position: relative; background-color: var(--input-bg); border-radius: var(--radius-card); border: 1px solid var(--panel-border); padding: 1.5rem; transition: var(--transition-smooth); display: flex; flex-direction: column; }
160
  .history-item:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
161
+ .history-item-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
 
 
 
 
 
 
 
162
  .history-item-grid img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-input); cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; border: 1px solid var(--panel-border); }
163
  .history-item-grid img:hover { transform: scale(1.1); box-shadow: var(--shadow-md); z-index: 5; position: relative; }
164
+ .history-delete-btn { position: absolute; top: 1rem; right: 1rem; /* CHANGED: Moved to top-right for better alignment without text */ background: none; border: none; cursor: pointer; padding: 0.5rem; border-radius: 50%; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--text-tertiary); transition: var(--transition-smooth); z-index: 5; }
165
  .history-delete-btn:hover { background-color: var(--panel-border); color: var(--danger-color); }
166
  .history-delete-btn svg { width: 18px; height: 18px; }
167
 
168
  /* --- Lightbox Styles --- */
169
  #lightbox { position: fixed; inset: 0; background-color: rgba(18, 24, 38, 0.6); backdrop-filter: blur(10px) saturate(150%); display: none; align-items: center; justify-content: center; z-index: 1000; opacity: 0; transition: opacity 0.3s; }
170
  #lightbox.visible { display: flex; opacity: 1; }
171
+ #lightbox-content { position: relative; animation: fadeIn 0.3s ease; display: flex; align-items: center; justify-content: center; } /* Flex for alignment */
172
  #lightbox-img { max-width: 85vw; max-height: 80vh; object-fit: contain; border-radius: var(--radius-card); box-shadow: var(--shadow-xl); }
173
  .lightbox-btn { position: absolute; background-color: rgba(255, 255, 255, 0.1); color: white; border: 1px solid rgba(255,255,255,0.2); width: 44px; height: 44px; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; transition: all 0.2s; text-decoration: none; }
174
  .lightbox-btn:hover { background-color: rgba(255, 255, 255, 0.2); transform: scale(1.1); }
 
176
  #lightbox-download { top: -50px; left: 0; }
177
  #lightbox-download svg { width: 22px; height: 22px; }
178
  #lightbox-download .spinner { width: 20px; height: 20px; border: 3px solid rgba(255, 255, 255, 0.4); border-top-color: #fff; border-radius: 50%; animation: spin 0.8s linear infinite; display: none; }
179
+
180
+ /* --- CHANGE 1: Styles for new lightbox navigation buttons --- */
181
+ .lightbox-nav {
182
+ top: 50%;
183
+ transform: translateY(-50%);
184
+ font-size: 1.5rem;
185
+ width: 50px;
186
+ height: 50px;
187
+ font-family: monospace;
188
+ z-index: 1001;
189
+ }
190
+ #lightbox-prev { left: 1rem; }
191
+ #lightbox-next { right: 1rem; }
192
+ .lightbox-nav:disabled { opacity: 0.3; cursor: not-allowed; transform: translateY(-50%) scale(1); }
193
+ .lightbox-nav:disabled:hover { background-color: rgba(255, 255, 255, 0.1); }
194
+
195
 
196
  @media (max-width: 768px) {
197
  main, .gallery-section { padding: 1.5rem; }
198
  h1 { font-size: 2.2rem; }
199
+ #history-grid { grid-template-columns: 1fr; }
200
  }
201
  </style>
202
  </head>
 
269
 
270
  <div id="lightbox">
271
  <div id="lightbox-content">
272
+ <!-- --- CHANGE 1: Added navigation buttons --- -->
273
+ <button id="lightbox-prev" class="lightbox-btn lightbox-nav" title="قبلی">&#10094;</button>
274
  <img id="lightbox-img" src="">
275
+ <button id="lightbox-next" class="lightbox-btn lightbox-nav" title="بعدی">&#10095;</button>
276
+
277
  <button id="lightbox-close" class="lightbox-btn">&times;</button>
278
  <button id="lightbox-download" title="دانلود تصویر" class="lightbox-btn">
279
  <svg fill="white" viewBox="0 0 24 24"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg>
 
283
  </div>
284
 
285
  <script>
 
286
  const API_URL = 'https://alfa-editor-worker.onrender.com/api/edit';
287
 
288
  const uploadArea = document.getElementById('upload-area');
 
304
  const historyGrid = document.getElementById('history-grid');
305
  const clearHistoryBtn = document.getElementById('clear-history-btn');
306
 
307
+ // --- CHANGE 1: New elements and variables for lightbox navigation ---
308
+ const lightboxPrevBtn = document.getElementById('lightbox-prev');
309
+ const lightboxNextBtn = document.getElementById('lightbox-next');
310
+ let currentLightboxGallery = [];
311
+ let currentLightboxIndex = 0;
312
  let uploadedFile = null;
 
313
 
314
  const resetUploader = () => {
315
  uploadedFile = null;
 
389
  const img = document.createElement('img');
390
  img.src = url;
391
  img.alt = 'تصویر ویرایش شده';
392
+ // --- CHANGE 1: Pass the whole gallery to the openLightbox function ---
393
+ img.addEventListener('click', () => openLightbox(url, imageUrls));
394
  resultGrid.appendChild(img);
395
  });
396
  resultContainer.classList.add('has-content');
 
405
  errorMessage.style.display = 'block';
406
  }
407
 
408
+ // --- CHANGE 1: Updated lightbox functions to handle navigation ---
409
+ function updateLightboxNavButtons() {
410
+ lightboxPrevBtn.disabled = currentLightboxIndex === 0;
411
+ lightboxNextBtn.disabled = currentLightboxIndex === currentLightboxGallery.length - 1;
412
+ }
413
+
414
+ function showImageAtIndex(index) {
415
+ currentLightboxIndex = index;
416
+ const newUrl = currentLightboxGallery[currentLightboxIndex];
417
+ lightboxImg.src = newUrl;
418
+ lightboxDownload.dataset.url = newUrl; // Keep track for download
419
+ updateLightboxNavButtons();
420
+ }
421
+
422
+ function openLightbox(clickedUrl, galleryUrls) {
423
+ currentLightboxGallery = galleryUrls;
424
+ const clickedIndex = galleryUrls.findIndex(url => url === clickedUrl);
425
  lightbox.classList.add('visible');
426
+ showImageAtIndex(clickedIndex !== -1 ? clickedIndex : 0);
427
  }
428
+
429
  function closeLightbox() {
430
  lightbox.classList.remove('visible');
431
+ currentLightboxGallery = [];
432
  }
433
+
434
+ lightboxPrevBtn.addEventListener('click', () => {
435
+ if (currentLightboxIndex > 0) {
436
+ showImageAtIndex(currentLightboxIndex - 1);
437
+ }
438
+ });
439
+
440
+ lightboxNextBtn.addEventListener('click', () => {
441
+ if (currentLightboxIndex < currentLightboxGallery.length - 1) {
442
+ showImageAtIndex(currentLightboxIndex + 1);
443
+ }
444
+ });
445
+
446
  async function handleDownload() {
447
+ const urlToDownload = lightboxDownload.dataset.url;
448
+ if (!urlToDownload) return;
449
 
450
  const spinner = lightboxDownload.querySelector('.spinner');
451
  const icon = lightboxDownload.querySelector('svg');
 
455
  lightboxDownload.disabled = true;
456
 
457
  try {
458
+ const response = await fetch(urlToDownload);
459
  if (!response.ok) throw new Error('Network response was not ok.');
460
  const blob = await response.blob();
461
  const objectUrl = URL.createObjectURL(blob);
 
476
  }
477
  }
478
  lightboxClose.addEventListener('click', closeLightbox);
479
+ lightbox.addEventListener('click', (e) => { if (e.target === lightbox || e.target === lightboxImg) closeLightbox(); });
480
  lightboxDownload.addEventListener('click', handleDownload);
481
 
482
  const getHistory = () => JSON.parse(localStorage.getItem('aiPhotoshopHistory') || '[]');
 
503
  history.forEach((item, index) => {
504
  const card = document.createElement('div');
505
  card.className = 'history-item';
506
+ const imagesHTML = item.urls.map(url => `<img src="${url}" alt="تصویر از تاریخچه">`).join('');
507
+
508
+ // --- CHANGE 2: Removed prompt paragraph from the card ---
509
+ card.innerHTML = `
510
+ <button class="history-delete-btn" data-index="${index}" title="حذف این مورد">
511
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
512
+ </button>
513
+ <div class="history-item-grid">${imagesHTML}</div>`;
514
  historyGrid.appendChild(card);
515
  });
516
  }
517
  clearHistoryBtn.addEventListener('click', handleClearHistory);
518
+ // --- CHANGE 1: Combined event listener for history grid ---
519
  historyGrid.addEventListener('click', (e) => {
520
  const deleteBtn = e.target.closest('.history-delete-btn');
521
+ if (deleteBtn) {
522
+ handleDeleteItem(parseInt(deleteBtn.dataset.index, 10));
523
+ return;
524
+ }
525
+
526
+ if (e.target.tagName === 'IMG') {
527
+ const clickedUrl = e.target.src;
528
+ const grid = e.target.closest('.history-item-grid');
529
+ const allImages = Array.from(grid.querySelectorAll('img'));
530
+ const galleryUrls = allImages.map(img => img.src);
531
+ openLightbox(clickedUrl, galleryUrls);
532
+ }
533
  });
534
  document.addEventListener('DOMContentLoaded', () => { renderHistory(); checkFormState(); });
535
  </script>