From fcca0688689aa124ec07109b06e9e38bff386883 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 19 Mar 2026 07:36:43 +0100 Subject: [PATCH] Fix: navigation sous-pages blog/white-papers + singleSlug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - App.svelte : flèches clavier bloquées sur sous-page (ArrowLeft → history.back()) - Blog/WhitePapers : reset de articleData/itemData après 1100ms (post-transition) pour éviter le flash pendant l'animation de changement de slide - WhitePapers : singleSlug jamais resetté (pré-affiché à l'arrivée sur la slide) - WhitePapers : $effect sur isActive pour replaceState + openItem si itemData null - WhitePapers/Blog : handlePopState ignore les popstate hors de la page courante Co-Authored-By: Claude Sonnet 4.6 --- src/App.svelte | 14 +++++++++++++- src/views/Blog.svelte | 5 +++-- src/views/WhitePapers.svelte | 23 ++++++++++++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 9595968..719d74d 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -58,10 +58,22 @@ window.addEventListener('resize', handleResize) const handleKeydown = (e) => { + if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return + + // Si on est sur une sous-page (ex: /livres-blancs/slug), ne pas changer de slide + const activePath = slides.active?.path ?? '' + const currentPath = window.location.pathname.replace(/^\/en/, '') || '/' + const isSubPage = activePath && currentPath.startsWith(activePath + '/') + + if (isSubPage) { + if (e.key === 'ArrowLeft') history.back() + return + } + if (e.key === 'ArrowRight') { const next = slides.all[slides.activeIndex + 1] if (next) slideTo(next.path) - } else if (e.key === 'ArrowLeft') { + } else { const prev = slides.all[slides.activeIndex - 1] if (prev) slideTo(prev.path) } diff --git a/src/views/Blog.svelte b/src/views/Blog.svelte index 9dd0b1f..aeb0029 100644 --- a/src/views/Blog.svelte +++ b/src/views/Blog.svelte @@ -95,10 +95,11 @@ } }) - // Reset article view when leaving the blog slide + // Reset après la fin de la transition de slide (1100ms) pour éviter le flash $effect(() => { if (!isActive && articleData) { - articleData = null + const timer = setTimeout(() => { articleData = null }, 1100) + return () => clearTimeout(timer) } }) diff --git a/src/views/WhitePapers.svelte b/src/views/WhitePapers.svelte index ead76fa..e0cbfba 100644 --- a/src/views/WhitePapers.svelte +++ b/src/views/WhitePapers.svelte @@ -63,6 +63,9 @@ function handlePopState() { if (!isActive) return + // Si l'URL n'appartient plus à ce slide, le router gère — on ne touche à rien + const onThisPage = window.location.pathname.replace(/^\/en/, '').startsWith(`/${pageUri}`) + if (!onThisPage) return const slug = getSlugFromUrl() if (slug && (!itemData || itemData.uri !== `${pageUri}/${slug}`)) { openItem(slug) @@ -80,8 +83,26 @@ return () => window.removeEventListener('popstate', handlePopState) }) + // Quand le slide devient actif avec un seul livre blanc : + // - remplace l'URL /parent par /parent/slug (back saute le parent) + // - ré-ouvre l'item si itemData a été vidé $effect(() => { - if (!isActive && itemData) itemData = null + if (isActive && data?.singleSlug) { + if (!getSlugFromUrl()) { + const prefix = locale.current === 'en' ? '/en' : '' + history.replaceState({}, '', `${prefix}/${pageUri}/${data.singleSlug}`) + } + if (!itemData) openItem(data.singleSlug) + } + }) + + // Reset après la fin de la transition de slide (1100ms) pour éviter le flash + // Pas de reset pour singleSlug : le contenu reste en mémoire et est pré-affiché à l'arrivée + $effect(() => { + if (!isActive && itemData && !data?.singleSlug) { + const timer = setTimeout(() => { itemData = null }, 1100) + return () => clearTimeout(timer) + } })