311 lines
12 KiB
JavaScript
311 lines
12 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
// Détection de l'état de connexion
|
|
function updateOnlineStatus() {
|
|
const offlineIndicator = document.querySelector('.offline-indicator');
|
|
|
|
if (!navigator.onLine) {
|
|
if (!offlineIndicator) {
|
|
const indicator = document.createElement('div');
|
|
indicator.className = 'offline-indicator show';
|
|
indicator.textContent = 'Mode hors ligne - Fonctionnalités limitées';
|
|
document.body.insertBefore(indicator, document.body.firstChild);
|
|
}
|
|
} else {
|
|
if (offlineIndicator) {
|
|
offlineIndicator.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Écouter les changements de connexion
|
|
window.addEventListener('online', updateOnlineStatus);
|
|
window.addEventListener('offline', updateOnlineStatus);
|
|
|
|
// Vérifier l'état initial
|
|
updateOnlineStatus();
|
|
// Gestion du menu mobile
|
|
const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
|
|
const mobileMenu = document.querySelector('.mobile-menu');
|
|
const mobileMenuClose = document.querySelector('.mobile-menu-close');
|
|
|
|
if (mobileMenuToggle) {
|
|
mobileMenuToggle.addEventListener('click', function() {
|
|
mobileMenu.classList.add('active');
|
|
document.body.style.overflow = 'hidden'; // Empêche le défilement de la page
|
|
});
|
|
}
|
|
|
|
if (mobileMenuClose) {
|
|
mobileMenuClose.addEventListener('click', function() {
|
|
mobileMenu.classList.remove('active');
|
|
document.body.style.overflow = ''; // Réactive le défilement
|
|
});
|
|
}
|
|
|
|
// Gestion du theme (mode clair/sombre)
|
|
const themeToggle = document.querySelector('#theme-toggle');
|
|
const html = document.documentElement;
|
|
|
|
// Charger le thème sauvegardé ou détecter la préférence système
|
|
function initTheme() {
|
|
const savedTheme = localStorage.getItem('theme');
|
|
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
|
|
let currentTheme = savedTheme;
|
|
if (!savedTheme) {
|
|
currentTheme = systemPrefersDark ? 'dark' : 'light';
|
|
}
|
|
|
|
applyTheme(currentTheme);
|
|
updateThemeIcon(currentTheme);
|
|
}
|
|
|
|
// Appliquer le thème
|
|
function applyTheme(theme) {
|
|
if (theme === 'dark') {
|
|
html.setAttribute('data-theme', 'dark');
|
|
} else {
|
|
html.removeAttribute('data-theme');
|
|
}
|
|
}
|
|
|
|
// Mettre à jour l'icône du bouton
|
|
function updateThemeIcon(theme) {
|
|
if (themeToggle) {
|
|
const icon = themeToggle.querySelector('i');
|
|
if (theme === 'dark') {
|
|
icon.classList.remove('fa-sun');
|
|
icon.classList.add('fa-moon');
|
|
themeToggle.setAttribute('aria-label', 'Basculer vers le mode clair');
|
|
themeToggle.setAttribute('title', 'Mode clair');
|
|
} else {
|
|
icon.classList.remove('fa-moon');
|
|
icon.classList.add('fa-sun');
|
|
themeToggle.setAttribute('aria-label', 'Basculer vers le mode sombre');
|
|
themeToggle.setAttribute('title', 'Mode sombre');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Basculer le thème
|
|
function toggleTheme() {
|
|
const currentTheme = html.getAttribute('data-theme');
|
|
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
|
|
|
applyTheme(newTheme);
|
|
updateThemeIcon(newTheme);
|
|
localStorage.setItem('theme', newTheme);
|
|
}
|
|
|
|
// Event listener pour le bouton
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', toggleTheme);
|
|
}
|
|
|
|
// Écouter les changements de préférence système
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
|
if (!localStorage.getItem('theme')) {
|
|
const newTheme = e.matches ? 'dark' : 'light';
|
|
applyTheme(newTheme);
|
|
updateThemeIcon(newTheme);
|
|
}
|
|
});
|
|
|
|
// Initialiser le thème
|
|
initTheme();
|
|
|
|
// Gestion des carousels
|
|
const carousels = document.querySelectorAll('.carousel');
|
|
|
|
carousels.forEach(carousel => {
|
|
const container = carousel.querySelector('.carousel-container');
|
|
const dots = carousel.querySelectorAll('.carousel-dot');
|
|
const items = carousel.querySelectorAll('.carousel-item');
|
|
|
|
if (dots.length > 0 && items.length > 0) {
|
|
dots.forEach((dot, index) => {
|
|
dot.addEventListener('click', function() {
|
|
// Calculer la distance à translater
|
|
const itemWidth = items[0].offsetWidth + parseInt(getComputedStyle(items[0]).marginRight);
|
|
const newTransform = -index * itemWidth;
|
|
|
|
// Appliquer la transformation
|
|
container.style.transform = `translateX(${newTransform}px)`;
|
|
|
|
// Mettre à jour les dots
|
|
dots.forEach(d => d.classList.remove('active'));
|
|
dot.classList.add('active');
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
// Gestion des clics sur les vidéos
|
|
function initVideoCardClicks() {
|
|
const videoCards = document.querySelectorAll('.video-card');
|
|
|
|
videoCards.forEach(card => {
|
|
if (!card.hasAttribute('data-click-initialized')) {
|
|
card.setAttribute('data-click-initialized', 'true');
|
|
card.addEventListener('click', function() {
|
|
const videoId = this.dataset.videoId;
|
|
if (videoId) {
|
|
window.location.href = 'video.php?id=' + videoId;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialiser les clics sur les vidéos existantes
|
|
initVideoCardClicks();
|
|
|
|
// Lazy loading des images
|
|
function initLazyLoading() {
|
|
if ('IntersectionObserver' in window) {
|
|
const imageObserver = new IntersectionObserver((entries, observer) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
const img = entry.target;
|
|
const src = img.getAttribute('data-src');
|
|
if (src) {
|
|
img.src = src;
|
|
img.removeAttribute('data-src');
|
|
}
|
|
observer.unobserve(img);
|
|
}
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('img[data-src]').forEach(img => {
|
|
imageObserver.observe(img);
|
|
});
|
|
} else {
|
|
// Fallback pour les navigateurs qui ne supportent pas IntersectionObserver
|
|
document.querySelectorAll('img[data-src]').forEach(img => {
|
|
const src = img.getAttribute('data-src');
|
|
if (src) {
|
|
img.src = src;
|
|
img.removeAttribute('data-src');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Initialiser le lazy loading
|
|
initLazyLoading();
|
|
|
|
// Gestion des boutons "Voir plus"
|
|
const viewMoreButtons = document.querySelectorAll('.view-more');
|
|
|
|
viewMoreButtons.forEach(button => {
|
|
// Déterminer le type de vidéos à charger
|
|
const section = button.closest('.video-section');
|
|
const sectionTitle = section.querySelector('.section-title').textContent.trim().toLowerCase();
|
|
const videoGrid = section.querySelector('.video-grid');
|
|
let videoType = '';
|
|
let categoryId = null;
|
|
|
|
if (sectionTitle.includes('dernières')) {
|
|
videoType = 'recent';
|
|
} else if (sectionTitle.includes('tendances')) {
|
|
videoType = 'trending';
|
|
} else if (sectionTitle.includes('indépendance')) {
|
|
videoType = 'independence';
|
|
} else {
|
|
// Vérifier si c'est une section de catégorie
|
|
const categorySection = section.querySelector('[data-category-id]');
|
|
if (categorySection) {
|
|
videoType = 'category';
|
|
categoryId = categorySection.dataset.categoryId;
|
|
} else if (section.hasAttribute('data-category-id')) {
|
|
videoType = 'category';
|
|
categoryId = section.dataset.categoryId;
|
|
}
|
|
}
|
|
|
|
// Si aucun type reconnu, ne pas configurer l'événement
|
|
if (!videoType) return;
|
|
|
|
// Stocker le numéro de page actuel
|
|
button.dataset.page = '1';
|
|
|
|
button.addEventListener('click', function() {
|
|
const page = parseInt(this.dataset.page);
|
|
|
|
// Changer le texte du bouton pendant le chargement
|
|
button.textContent = 'Chargement...';
|
|
button.disabled = true;
|
|
|
|
// Préparer l'URL avec les paramètres
|
|
let url = `ajax/load-more-videos.php?type=${videoType}&page=${page}`;
|
|
if (videoType === 'category' && categoryId) {
|
|
url += `&category=${categoryId}`;
|
|
}
|
|
|
|
// Préparer les données avec token CSRF
|
|
const formData = new FormData();
|
|
formData.append('csrf_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
|
|
|
|
// Faire la requête AJAX
|
|
fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Ajouter les nouvelles vidéos à la grille
|
|
const tempDiv = document.createElement('div');
|
|
tempDiv.innerHTML = data.html;
|
|
|
|
// Ajouter chaque vidéo à la grille
|
|
while (tempDiv.firstChild) {
|
|
videoGrid.appendChild(tempDiv.firstChild);
|
|
}
|
|
|
|
// Mettre à jour le numéro de page
|
|
this.dataset.page = data.page + 1;
|
|
|
|
// Réinitialiser le texte du bouton
|
|
button.textContent = 'Voir plus';
|
|
button.disabled = false;
|
|
|
|
// Si plus de vidéos à charger, masquer le bouton
|
|
if (!data.hasMore) {
|
|
button.style.display = 'none';
|
|
}
|
|
|
|
// Initialiser les clics sur les nouvelles vidéos
|
|
initVideoCardClicks();
|
|
// Initialiser le lazy loading pour les nouvelles images
|
|
initLazyLoading();
|
|
} else {
|
|
// En cas d'erreur, afficher un message et réactiver le bouton
|
|
console.error('Erreur lors du chargement des vidéos:', data.error);
|
|
button.textContent = 'Voir plus';
|
|
button.disabled = false;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Erreur lors de la requête AJAX:', error);
|
|
button.textContent = 'Voir plus';
|
|
button.disabled = false;
|
|
});
|
|
});
|
|
});
|
|
|
|
// Scroll vers le haut avec effet moderne quand on clique sur le logo du footer
|
|
const footerLogo = document.querySelector('.footer-logo');
|
|
if (footerLogo) {
|
|
footerLogo.addEventListener('click', function() {
|
|
window.scrollTo({
|
|
top: 0,
|
|
behavior: 'smooth'
|
|
});
|
|
});
|
|
}
|
|
});
|