Files
thalim-theme/js/agendaView.js
T
valentin_le_moignandClaude Opus 5 167950c627 Loader de scroll infini : styles réactivés, sans décalage de mise en page
Les règles `.scroll-spinner` et leurs keyframes étaient enfermées dans le
bloc `/* … */` legacy de `_category.scss` : Sass recopie ces commentaires
verbatim, les trois points n'avaient donc aucun style et restaient
invisibles pendant le chargement AJAX. Bloc sorti du commentaire (le
legacy reste en place), points allégés (5 px, gris) et marge haute
élargie.

Le modifieur `--reserve` réserve la place en permanence et n'anime que
l'opacité, au lieu de basculer `display` : plus de saut de mise en page
ni à l'apparition ni à la disparition. `infiniteScroll.js` bascule
désormais la classe `is-loading`.

Le `rootMargin` de l'observer passe à 700 px pour que la requête parte
plus tôt, et le loader de l'agenda est supprimé (markup + JS).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQLwtNFa1LNaN7QTAbYkZx
2026-09-10 01:16:20 +02:00

143 lines
5.9 KiB
JavaScript

(function () {
'use strict';
document.addEventListener('DOMContentLoaded', function () {
var toggleBtn = document.querySelector('.agenda-toggle-btn');
var gridSections = document.getElementById('grid-sections');
var agendaEl = document.getElementById('agenda-view');
if (!toggleBtn || !agendaEl) return;
var swiper = null;
var agendaPage = 0;
var agendaDone = false;
var agendaLoading = false;
var swiperWrapper = document.getElementById('agenda-swiper-wrapper');
var categoryId = agendaEl.dataset.category || '';
var includeChildren = agendaEl.dataset.includeChildren || '0';
var axe = agendaEl.dataset.axe || '';
var dateFrom = agendaEl.dataset.dateFrom || '';
var dateTo = agendaEl.dataset.dateTo || '';
function showAgenda() {
if (gridSections) gridSections.style.display = 'none';
agendaEl.classList.add('is-active');
toggleBtn.innerHTML =
'<i class="iconoir-view-grid"></i>' +
(agendaViewData.lang === 'en' ? 'Switch to grid view' : 'Passer à la vue grille');
if (!swiper) {
loadMoreAgenda(function (data) {
var todayOffset = Math.max(0, ((data && data.today_offset) || 0) - 1);
var anchorPage = Math.ceil((todayOffset + 1) / 12);
if (anchorPage > 1) {
chainLoadPages(2, anchorPage, function () {
initSwiper(todayOffset);
});
} else {
initSwiper(todayOffset);
}
});
}
}
function showGrid() {
agendaEl.classList.remove('is-active');
if (gridSections) gridSections.style.display = '';
toggleBtn.innerHTML =
'<i class="iconoir-calendar"></i>' +
(agendaViewData.lang === 'en' ? 'Switch to agenda view' : 'Passer à la vue agenda');
}
function initSwiper(initialSlide) {
swiper = new Swiper(agendaEl.querySelector('.agenda-swiper'), {
slidesPerView: 1.2,
spaceBetween: 20,
initialSlide: initialSlide || 0,
navigation: {
nextEl: agendaEl.querySelector('.agenda-swiper-prev'),
prevEl: agendaEl.querySelector('.agenda-swiper-next'),
},
breakpoints: {
640: { slidesPerView: 2, spaceBetween: 24 },
1024: { slidesPerView: 3, spaceBetween: 32 },
},
on: {
reachEnd: function () {
if (!agendaDone) loadMoreAgenda();
},
},
});
swiper.changeLanguageDirection('rtl');
}
function chainLoadPages(fromPage, toPage, callback) {
if (fromPage > toPage) { callback(); return; }
loadMoreAgenda(function () {
chainLoadPages(fromPage + 1, toPage, callback);
});
}
function loadMoreAgenda(callback) {
if (agendaLoading || agendaDone) return;
agendaLoading = true;
agendaPage++;
var data = new FormData();
data.append('action', 'load_more_agenda');
data.append('page', agendaPage);
data.append('nonce', agendaViewData.nonce);
data.append('lang', agendaViewData.lang);
if (categoryId) data.append('category', categoryId);
if (includeChildren==='1') data.append('include_children', '1');
if (axe) data.append('axe', axe);
if (dateFrom) data.append('date_from', dateFrom);
if (dateTo) data.append('date_to', dateTo);
fetch(agendaViewData.ajaxUrl, { method: 'POST', body: data })
.then(function (r) { return r.json(); })
.then(function (result) {
agendaLoading = false;
if (result.success && result.data.html) {
var tmp = document.createElement('div');
tmp.innerHTML = result.data.html;
Array.from(tmp.children).forEach(function (slide) {
if (swiper) {
swiper.appendSlide(slide.outerHTML);
} else {
swiperWrapper.appendChild(slide);
}
});
if (swiper) swiper.update();
if (callback) callback(result.data);
} else {
agendaDone = true;
if (callback) callback(result.data);
}
})
.catch(function () {
agendaLoading = false;
});
}
toggleBtn.addEventListener('click', function (e) {
e.preventDefault();
if (agendaEl.classList.contains('is-active')) {
var url = new URL(window.location.href);
url.searchParams.delete('view');
history.pushState({}, '', url.toString());
showGrid();
} else {
var url = new URL(window.location.href);
url.searchParams.set('view', 'agenda');
history.pushState({}, '', url.toString());
showAgenda();
}
});
// Initial state driven by server-side class
if (agendaEl.classList.contains('is-active')) {
showAgenda();
}
});
}());