diff --git a/src/routes/blog/[[page]]/+page.svelte b/src/routes/blog/[[page]]/+page.svelte index d7e5d71e4b..0036d90767 100644 --- a/src/routes/blog/[[page]]/+page.svelte +++ b/src/routes/blog/[[page]]/+page.svelte @@ -32,11 +32,18 @@ let articlesHeader: HTMLElement; - let previousPage: number | null = null; + function getBlogPageNumber(pageParam: string | undefined): number { + const pageNumber = parseInt(pageParam ?? '1', 10); + return Number.isNaN(pageNumber) ? 1 : pageNumber; + } + + onNavigate(async ({ from, to, type }) => { + const fromPage = getBlogPageNumber(from?.params?.page); + const toPage = getBlogPageNumber(to?.params?.page); + const isPaginationNavigation = + type === 'link' && fromPage !== toPage && from?.url.search === to?.url.search; - onNavigate(async ({ from, type }) => { - previousPage = type === 'link' ? parseInt(from?.params?.page ?? '1') : null; - if (!articlesHeader || !previousPage) return; + if (!articlesHeader || !isPaginationNavigation) return; await tick(); articlesHeader.scrollIntoView(); @@ -88,6 +95,35 @@ const { debounce, reset } = createDebounce(); + async function handleCategoryClick(event: MouseEvent, category?: string) { + if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + const scrollPosition = { + left: window.scrollX, + top: window.scrollY + }; + + const url = new URL('/blog', page.url); + + if (category) { + url.searchParams.set('category', category); + } + + await goto(url.toString(), { + noScroll: true, + keepFocus: true + }); + + await tick(); + window.scrollTo(scrollPosition); + requestAnimationFrame(() => window.scrollTo(scrollPosition)); + setTimeout(() => window.scrollTo(scrollPosition), 100); + } + const search = (node: HTMLInputElement) => { const inputHandler = () => debounce(() => handleSearch()); const keydownHandler = (event: KeyboardEvent) => { @@ -335,8 +371,10 @@