From e79af4f11d69a9efe9e8a4b9986f6c274c952fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Sat, 18 Oct 2025 01:20:04 +0400 Subject: [PATCH] fix: short error on click --- css/styles.css | 4 ++ index.php | 2 +- js/main.js | 107 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 108 insertions(+), 5 deletions(-) diff --git a/css/styles.css b/css/styles.css index 99d97e2..52209ab 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1365,6 +1365,10 @@ img { padding-bottom: 10px; cursor: grab; user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + touch-action: pan-y pinch-zoom; /* Permettre le scroll vertical et le zoom */ } .carousel-container:active { diff --git a/index.php b/index.php index 42a6a50..7cfbbc2 100644 --- a/index.php +++ b/index.php @@ -741,7 +741,7 @@ setSecurityHeaders(); - + diff --git a/js/main.js b/js/main.js index c8c9ff2..069bac3 100644 --- a/js/main.js +++ b/js/main.js @@ -125,9 +125,13 @@ document.addEventListener('DOMContentLoaded', function() { if (dots.length > 0 && items.length > 0) { let currentIndex = 0; let startX = 0; + let startY = 0; let currentX = 0; let isDragging = false; let startTransform = 0; + let isTap = true; // Nouveau: détecter si c'est un tap simple + let touchStartTime = 0; + let touchTarget = null; // Stocker la cible du touch function getItemWidth() { return items[0].offsetWidth + parseInt(getComputedStyle(items[0]).marginRight); @@ -155,7 +159,12 @@ document.addEventListener('DOMContentLoaded', function() { container.addEventListener('touchstart', function(e) { isDragging = true; + isTap = true; + touchStartTime = Date.now(); + touchTarget = e.target; // Capturer la cible du touch startX = e.touches[0].clientX; + startY = e.touches[0].clientY; + currentX = startX; // IMPORTANT: initialiser currentX à startX pour éviter les faux swipes const transform = window.getComputedStyle(container).transform; if (transform !== 'none') { @@ -171,6 +180,15 @@ document.addEventListener('DOMContentLoaded', function() { if (!isDragging) return; currentX = e.touches[0].clientX; + const currentY = e.touches[0].clientY; + const diffX = Math.abs(currentX - startX); + const diffY = Math.abs(currentY - startY); + + // Si le mouvement dépasse 10px, ce n'est plus un tap + if (diffX > 10 || diffY > 10) { + isTap = false; + } + const diff = currentX - startX; const newTransform = startTransform + diff; @@ -185,8 +203,39 @@ document.addEventListener('DOMContentLoaded', function() { const diff = currentX - startX; const threshold = 50; // Distance minimale pour considérer un swipe + const tapThreshold = 10; // Distance maximale pour un tap + const tapTimeThreshold = 300; // Temps maximal pour un tap (ms) + const touchDuration = Date.now() - touchStartTime; - // Déterminer la direction du swipe + // Si c'est un tap (mouvement minimal et rapide) + if (isTap && Math.abs(diff) < tapThreshold && touchDuration < tapTimeThreshold) { + // Vérifier si le tap était sur une video-card + let videoCard = touchTarget; + + // Remonter le DOM pour trouver la video-card + while (videoCard && !videoCard.classList.contains('video-card')) { + videoCard = videoCard.parentElement; + // Arrêter si on sort du container + if (videoCard === container || !videoCard) break; + } + + // Si on a trouvé une video-card, naviguer vers la vidéo + if (videoCard && videoCard.classList.contains('video-card')) { + const videoId = videoCard.dataset.videoId; + if (videoId) { + window.location.href = 'video.php?id=' + videoId; + return; + } + } + + // Sinon, juste repositionner le carousel + updateCarousel(currentIndex); + currentX = 0; + isTap = true; // Réinitialiser pour le prochain tap + return; + } + + // Gérer comme un swipe normal if (Math.abs(diff) > threshold) { if (diff > 0 && currentIndex > 0) { // Swipe vers la droite - item précédent @@ -204,12 +253,18 @@ document.addEventListener('DOMContentLoaded', function() { } currentX = 0; + isTap = true; // Réinitialiser pour le prochain tap }, { passive: true }); // Support du drag sur desktop (optionnel) container.addEventListener('mousedown', function(e) { isDragging = true; + isTap = true; + touchStartTime = Date.now(); + touchTarget = e.target; // Capturer la cible startX = e.clientX; + startY = e.clientY; + currentX = startX; // IMPORTANT: initialiser currentX à startX pour éviter les faux swipes const transform = window.getComputedStyle(container).transform; if (transform !== 'none') { const matrix = new DOMMatrix(transform); @@ -226,6 +281,15 @@ document.addEventListener('DOMContentLoaded', function() { if (!isDragging) return; currentX = e.clientX; + const currentY = e.clientY; + const diffX = Math.abs(currentX - startX); + const diffY = Math.abs(currentY - startY); + + // Si le mouvement dépasse 10px, ce n'est plus un clic simple + if (diffX > 10 || diffY > 10) { + isTap = false; + } + const diff = currentX - startX; const newTransform = startTransform + diff; @@ -241,7 +305,37 @@ document.addEventListener('DOMContentLoaded', function() { const diff = currentX - startX; const threshold = 50; + const tapThreshold = 10; + const tapTimeThreshold = 300; + const clickDuration = Date.now() - touchStartTime; + // Si c'est un clic simple (mouvement minimal et rapide) + if (isTap && Math.abs(diff) < tapThreshold && clickDuration < tapTimeThreshold) { + // Vérifier si le clic était sur une video-card + let videoCard = touchTarget; + + // Remonter le DOM pour trouver la video-card + while (videoCard && !videoCard.classList.contains('video-card')) { + videoCard = videoCard.parentElement; + if (videoCard === container || !videoCard) break; + } + + // Si on a trouvé une video-card, naviguer vers la vidéo + if (videoCard && videoCard.classList.contains('video-card')) { + const videoId = videoCard.dataset.videoId; + if (videoId) { + window.location.href = 'video.php?id=' + videoId; + return; + } + } + + updateCarousel(currentIndex); + currentX = 0; + isTap = true; // Réinitialiser pour le prochain tap + return; + } + + // Gérer comme un drag normal if (Math.abs(diff) > threshold) { if (diff > 0 && currentIndex > 0) { updateCarousel(currentIndex - 1); @@ -255,6 +349,7 @@ document.addEventListener('DOMContentLoaded', function() { } currentX = 0; + isTap = true; // Réinitialiser pour le prochain tap }); } }); @@ -262,9 +357,13 @@ document.addEventListener('DOMContentLoaded', function() { // Gestion des clics sur les vidéos function initVideoCardClicks() { const videoCards = document.querySelectorAll('.video-card'); - + videoCards.forEach(card => { - if (!card.hasAttribute('data-click-initialized')) { + // Ne pas ajouter de listener click sur les cartes dans un carousel + // car elles sont déjà gérées par le carousel lui-même + const isInCarousel = card.closest('.carousel-container'); + + if (!isInCarousel && !card.hasAttribute('data-click-initialized')) { card.setAttribute('data-click-initialized', 'true'); card.addEventListener('click', function() { const videoId = this.dataset.videoId; @@ -275,7 +374,7 @@ document.addEventListener('DOMContentLoaded', function() { } }); } - + // Initialiser les clics sur les vidéos existantes initVideoCardClicks();