Docfile commited on
Commit
f96a4ec
·
verified ·
1 Parent(s): e6fa8ea

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +94 -30
templates/index.html CHANGED
@@ -192,7 +192,7 @@
192
  object-fit: cover;
193
  }
194
  .preview-item .pdf-icon {
195
- font-size: 3rem; /* Adjust as needed */
196
  color: var(--danger-color);
197
  }
198
  .preview-item span {
@@ -203,7 +203,6 @@
203
  text-align: center;
204
  }
205
 
206
-
207
  .button {
208
  width: 100%;
209
  padding: var(--spacing-unit);
@@ -230,13 +229,12 @@
230
 
231
  .clear-button {
232
  background-color: var(--danger-color);
233
- margin-top: 0; /* No top margin if it follows directly */
234
  }
235
  .clear-button:hover:not(:disabled) {
236
  background-color: var(--danger-hover);
237
  }
238
 
239
-
240
  .copy-button {
241
  background-color: var(--secondary-color);
242
  }
@@ -245,6 +243,23 @@
245
  background-color: var(--secondary-hover);
246
  }
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  #solving-container {
249
  display: none;
250
  background-color: #f9f9f9;
@@ -383,6 +398,10 @@
383
  </div>
384
  </div>
385
 
 
 
 
 
386
  <div id="upload-section" class="upload-section">
387
  <div class="upload-icon">📤</div>
388
  <p>Cliquez ou glissez-déposez vos images et/ou 1 fichier PDF ici</p>
@@ -422,13 +441,66 @@
422
  const copyButton = document.getElementById('copy-button');
423
  const statusElement = document.getElementById('status');
424
  const loadingText = document.getElementById('loading-text');
 
 
425
 
426
- let selectedFiles = []; // Tableau pour stocker les fichiers sélectionnés
 
 
 
 
 
427
 
428
  window.selectStyle = function(style) {
429
  document.getElementById(`style-${style}`).checked = true;
430
  };
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  uploadSection.addEventListener('click', () => fileInput.click());
433
 
434
  uploadSection.addEventListener('dragover', (e) => {
@@ -464,15 +536,14 @@
464
 
465
  newFiles.forEach(file => {
466
  if (file.type.startsWith('image/')) {
467
- if (!selectedFiles.some(sf => sf.name === file.name && sf.size === file.size)) { // Évite les doublons
468
  selectedFiles.push(file);
469
  }
470
  } else if (file.type === 'application/pdf') {
471
  if (!pdfAlreadySelected) {
472
- // Supprimer tout PDF existant avant d'ajouter le nouveau
473
  selectedFiles = selectedFiles.filter(f => f.type !== 'application/pdf');
474
  selectedFiles.push(file);
475
- pdfAlreadySelected = true; // Marquer qu'un PDF est maintenant sélectionné
476
  } else {
477
  alert('Vous ne pouvez sélectionner qu\'un seul fichier PDF.');
478
  }
@@ -489,7 +560,7 @@
489
  }
490
 
491
  function updateFilePreviews() {
492
- filePreviewArea.innerHTML = ''; // Clear previous previews
493
 
494
  if (selectedFiles.length === 0) {
495
  filePreviewArea.style.display = 'none';
@@ -504,7 +575,6 @@
504
  const fileNameSpan = document.createElement('span');
505
  fileNameSpan.textContent = file.name.length > 15 ? file.name.substring(0,12) + "..." : file.name;
506
 
507
-
508
  if (file.type.startsWith('image/')) {
509
  const img = document.createElement('img');
510
  const reader = new FileReader();
@@ -516,7 +586,7 @@
516
  } else if (file.type === 'application/pdf') {
517
  const pdfIcon = document.createElement('div');
518
  pdfIcon.classList.add('pdf-icon');
519
- pdfIcon.textContent = '📄'; // Ou une icône SVG/FontAwesome
520
  previewItem.appendChild(pdfIcon);
521
  }
522
  previewItem.appendChild(fileNameSpan);
@@ -525,10 +595,14 @@
525
  }
526
 
527
  function updateButtonsState() {
528
- if (selectedFiles.length > 0) {
529
  solveButton.disabled = false;
530
  solveButton.textContent = `🔍 Résoudre (${selectedFiles.length} fichier(s))`;
531
  clearFilesButton.style.display = 'block';
 
 
 
 
532
  } else {
533
  solveButton.disabled = true;
534
  solveButton.textContent = '🔍 Résoudre';
@@ -538,7 +612,7 @@
538
 
539
  clearFilesButton.addEventListener('click', () => {
540
  selectedFiles = [];
541
- fileInput.value = ''; // Important pour permettre de re-sélectionner les mêmes fichiers
542
  updateFilePreviews();
543
  updateButtonsState();
544
  solvingContainer.style.display = 'none';
@@ -546,10 +620,13 @@
546
  });
547
 
548
  solveButton.addEventListener('click', () => {
549
- if (selectedFiles.length === 0) return;
550
 
551
  const selectedStyle = document.querySelector('input[name="resolution-style"]:checked').value;
552
 
 
 
 
553
  solveButton.disabled = true;
554
  solveButton.textContent = '⏳ Traitement...';
555
  solvingContainer.style.display = 'block';
@@ -561,14 +638,9 @@
561
 
562
  const formData = new FormData();
563
  selectedFiles.forEach(file => {
564
- formData.append('user_files', file); // Envoyer chaque fichier sous la clé 'user_files'
565
  });
566
  formData.append('style', selectedStyle);
567
-
568
- // Pour le débogage : afficher le contenu de FormData
569
- // for (let [key, value] of formData.entries()) {
570
- // console.log(`${key}: ${value.name || value}`);
571
- // }
572
 
573
  fetch('/solve', {
574
  method: 'POST',
@@ -595,7 +667,7 @@
595
 
596
  if (data.error) {
597
  handleError(data.error);
598
- eventSource.close(); // Important de fermer en cas d'erreur finale
599
  return;
600
  }
601
 
@@ -633,8 +705,7 @@
633
  case 'completed':
634
  statusElement.className = 'status completed';
635
  statusElement.textContent = 'Traitement terminé avec succès ! 🎉';
636
- responseDiv.innerHTML = data.response;
637
- renderMathInElement(responseDiv);
638
  showResponse();
639
  break;
640
  case 'error':
@@ -646,14 +717,9 @@
646
  function showResponse() {
647
  responseContainer.style.display = 'block';
648
  loadingText.style.display = 'none';
649
- // Ne pas réactiver le bouton ici si on veut attendre que l'utilisateur efface les fichiers
650
- // solveButton.disabled = false;
651
- // solveButton.textContent = `🔍 Résoudre (${selectedFiles.length} fichier(s))`;
652
- // Laisser le bouton "Effacer les fichiers" comme principal moyen de recommencer
653
  }
654
 
655
  function handleEventSourceError(taskId) {
656
- // Essayer de récupérer l'état final de la tâche
657
  fetch('/task/' + taskId)
658
  .then(response => {
659
  if (!response.ok) {
@@ -670,7 +736,6 @@
670
  } else if (taskData.status === 'error' || taskData.error) {
671
  handleError(taskData.error || 'Une erreur est survenue lors du traitement de la tâche.');
672
  } else {
673
- // Si la tâche n'est pas terminée ou en erreur, mais que le flux est perdu.
674
  handleError('La connexion au flux a été perdue. Vérifiez Telegram ou réessayez plus tard.');
675
  }
676
  })
@@ -690,7 +755,6 @@
690
  }, 2000);
691
  })
692
  .catch(() => {
693
- // Fallback pour les anciens navigateurs
694
  const range = document.createRange();
695
  range.selectNode(responseDiv);
696
  window.getSelection().removeAllRanges();
 
192
  object-fit: cover;
193
  }
194
  .preview-item .pdf-icon {
195
+ font-size: 3rem;
196
  color: var(--danger-color);
197
  }
198
  .preview-item span {
 
203
  text-align: center;
204
  }
205
 
 
206
  .button {
207
  width: 100%;
208
  padding: var(--spacing-unit);
 
229
 
230
  .clear-button {
231
  background-color: var(--danger-color);
232
+ margin-top: 0;
233
  }
234
  .clear-button:hover:not(:disabled) {
235
  background-color: var(--danger-hover);
236
  }
237
 
 
238
  .copy-button {
239
  background-color: var(--secondary-color);
240
  }
 
243
  background-color: var(--secondary-hover);
244
  }
245
 
246
+ .cooldown-notice {
247
+ background-color: #fff3cd;
248
+ border: 1px solid #ffeaa7;
249
+ border-radius: 0.5rem;
250
+ padding: var(--spacing-unit);
251
+ margin: var(--spacing-unit) 0;
252
+ text-align: center;
253
+ color: #856404;
254
+ font-weight: 500;
255
+ }
256
+
257
+ .cooldown-timer {
258
+ font-size: 1.2rem;
259
+ color: #d63031;
260
+ font-weight: bold;
261
+ }
262
+
263
  #solving-container {
264
  display: none;
265
  background-color: #f9f9f9;
 
398
  </div>
399
  </div>
400
 
401
+ <div id="cooldown-notice" class="cooldown-notice" style="display: none;">
402
+ ⏰ Veuillez attendre <span id="cooldown-timer" class="cooldown-timer">2:00</span> avant de pouvoir soumettre à nouveau.
403
+ </div>
404
+
405
  <div id="upload-section" class="upload-section">
406
  <div class="upload-icon">📤</div>
407
  <p>Cliquez ou glissez-déposez vos images et/ou 1 fichier PDF ici</p>
 
441
  const copyButton = document.getElementById('copy-button');
442
  const statusElement = document.getElementById('status');
443
  const loadingText = document.getElementById('loading-text');
444
+ const cooldownNotice = document.getElementById('cooldown-notice');
445
+ const cooldownTimer = document.getElementById('cooldown-timer');
446
 
447
+ let selectedFiles = [];
448
+ let cooldownEndTime = 0;
449
+ let cooldownInterval = null;
450
+
451
+ // Vérifier le cooldown au chargement de la page
452
+ checkCooldownOnLoad();
453
 
454
  window.selectStyle = function(style) {
455
  document.getElementById(`style-${style}`).checked = true;
456
  };
457
 
458
+ function checkCooldownOnLoad() {
459
+ const savedCooldownEndTime = localStorage.getItem('mariamCooldownEndTime');
460
+ if (savedCooldownEndTime) {
461
+ const endTime = parseInt(savedCooldownEndTime);
462
+ const now = Date.now();
463
+ if (now < endTime) {
464
+ cooldownEndTime = endTime;
465
+ startCooldownTimer();
466
+ } else {
467
+ localStorage.removeItem('mariamCooldownEndTime');
468
+ }
469
+ }
470
+ }
471
+
472
+ function startCooldown() {
473
+ cooldownEndTime = Date.now() + (2 * 60 * 1000); // 2 minutes
474
+ localStorage.setItem('mariamCooldownEndTime', cooldownEndTime.toString());
475
+ startCooldownTimer();
476
+ }
477
+
478
+ function startCooldownTimer() {
479
+ cooldownNotice.style.display = 'block';
480
+ solveButton.disabled = true;
481
+
482
+ cooldownInterval = setInterval(() => {
483
+ const now = Date.now();
484
+ const remainingTime = Math.max(0, cooldownEndTime - now);
485
+
486
+ if (remainingTime <= 0) {
487
+ clearInterval(cooldownInterval);
488
+ cooldownNotice.style.display = 'none';
489
+ localStorage.removeItem('mariamCooldownEndTime');
490
+ updateButtonsState(); // Réactiver le bouton si des fichiers sont sélectionnés
491
+ return;
492
+ }
493
+
494
+ const minutes = Math.floor(remainingTime / 60000);
495
+ const seconds = Math.floor((remainingTime % 60000) / 1000);
496
+ cooldownTimer.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
497
+ }, 1000);
498
+ }
499
+
500
+ function isCooldownActive() {
501
+ return Date.now() < cooldownEndTime;
502
+ }
503
+
504
  uploadSection.addEventListener('click', () => fileInput.click());
505
 
506
  uploadSection.addEventListener('dragover', (e) => {
 
536
 
537
  newFiles.forEach(file => {
538
  if (file.type.startsWith('image/')) {
539
+ if (!selectedFiles.some(sf => sf.name === file.name && sf.size === file.size)) {
540
  selectedFiles.push(file);
541
  }
542
  } else if (file.type === 'application/pdf') {
543
  if (!pdfAlreadySelected) {
 
544
  selectedFiles = selectedFiles.filter(f => f.type !== 'application/pdf');
545
  selectedFiles.push(file);
546
+ pdfAlreadySelected = true;
547
  } else {
548
  alert('Vous ne pouvez sélectionner qu\'un seul fichier PDF.');
549
  }
 
560
  }
561
 
562
  function updateFilePreviews() {
563
+ filePreviewArea.innerHTML = '';
564
 
565
  if (selectedFiles.length === 0) {
566
  filePreviewArea.style.display = 'none';
 
575
  const fileNameSpan = document.createElement('span');
576
  fileNameSpan.textContent = file.name.length > 15 ? file.name.substring(0,12) + "..." : file.name;
577
 
 
578
  if (file.type.startsWith('image/')) {
579
  const img = document.createElement('img');
580
  const reader = new FileReader();
 
586
  } else if (file.type === 'application/pdf') {
587
  const pdfIcon = document.createElement('div');
588
  pdfIcon.classList.add('pdf-icon');
589
+ pdfIcon.textContent = '📄';
590
  previewItem.appendChild(pdfIcon);
591
  }
592
  previewItem.appendChild(fileNameSpan);
 
595
  }
596
 
597
  function updateButtonsState() {
598
+ if (selectedFiles.length > 0 && !isCooldownActive()) {
599
  solveButton.disabled = false;
600
  solveButton.textContent = `🔍 Résoudre (${selectedFiles.length} fichier(s))`;
601
  clearFilesButton.style.display = 'block';
602
+ } else if (selectedFiles.length > 0 && isCooldownActive()) {
603
+ solveButton.disabled = true;
604
+ solveButton.textContent = `🔍 Résoudre (${selectedFiles.length} fichier(s))`;
605
+ clearFilesButton.style.display = 'block';
606
  } else {
607
  solveButton.disabled = true;
608
  solveButton.textContent = '🔍 Résoudre';
 
612
 
613
  clearFilesButton.addEventListener('click', () => {
614
  selectedFiles = [];
615
+ fileInput.value = '';
616
  updateFilePreviews();
617
  updateButtonsState();
618
  solvingContainer.style.display = 'none';
 
620
  });
621
 
622
  solveButton.addEventListener('click', () => {
623
+ if (selectedFiles.length === 0 || isCooldownActive()) return;
624
 
625
  const selectedStyle = document.querySelector('input[name="resolution-style"]:checked').value;
626
 
627
+ // Démarrer le cooldown immédiatement
628
+ startCooldown();
629
+
630
  solveButton.disabled = true;
631
  solveButton.textContent = '⏳ Traitement...';
632
  solvingContainer.style.display = 'block';
 
638
 
639
  const formData = new FormData();
640
  selectedFiles.forEach(file => {
641
+ formData.append('user_files', file);
642
  });
643
  formData.append('style', selectedStyle);
 
 
 
 
 
644
 
645
  fetch('/solve', {
646
  method: 'POST',
 
667
 
668
  if (data.error) {
669
  handleError(data.error);
670
+ eventSource.close();
671
  return;
672
  }
673
 
 
705
  case 'completed':
706
  statusElement.className = 'status completed';
707
  statusElement.textContent = 'Traitement terminé avec succès ! 🎉';
708
+ responseDiv.innerHTML = '<p style="color: #2ecc71; font-size: 1.2rem; text-align: center; font-weight: bold;">📄 Votre PDF est disponible sur Telegram</p>';
 
709
  showResponse();
710
  break;
711
  case 'error':
 
717
  function showResponse() {
718
  responseContainer.style.display = 'block';
719
  loadingText.style.display = 'none';
 
 
 
 
720
  }
721
 
722
  function handleEventSourceError(taskId) {
 
723
  fetch('/task/' + taskId)
724
  .then(response => {
725
  if (!response.ok) {
 
736
  } else if (taskData.status === 'error' || taskData.error) {
737
  handleError(taskData.error || 'Une erreur est survenue lors du traitement de la tâche.');
738
  } else {
 
739
  handleError('La connexion au flux a été perdue. Vérifiez Telegram ou réessayez plus tard.');
740
  }
741
  })
 
755
  }, 2000);
756
  })
757
  .catch(() => {
 
758
  const range = document.createRange();
759
  range.selectNode(responseDiv);
760
  window.getSelection().removeAllRanges();