From 17f015b6869cfbc128a86e184ccfeb6bdcb33ca4 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Wed, 29 Apr 2026 10:52:07 +0200 Subject: [PATCH] fix(notes): wait for stacked note element before scrolling on mobile A single nextTick is not enough for a freshly added stacked note to be in the DOM, so the mobile scroll target was computed against a null element. Poll with requestAnimationFrame (mirroring scrollToHashInNote) and use offsetTop, with an (index + 1) * height fallback. --- src/hooks/useRouteQueryStackedNotes.hook.ts | 32 ++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/hooks/useRouteQueryStackedNotes.hook.ts b/src/hooks/useRouteQueryStackedNotes.hook.ts index b4a7e3f..b5b1292 100644 --- a/src/hooks/useRouteQueryStackedNotes.hook.ts +++ b/src/hooks/useRouteQueryStackedNotes.hook.ts @@ -47,6 +47,30 @@ export const useRouteQueryStackedNotes = () => { }) } + const scrollToNoteElement = ( + cleanNoteId: string, + index: number, + attempts = 30 + ) => { + if (attempts <= 0) { + scrollToNote((index + 1) * height.value) + return + } + + const element = document.querySelector( + `.note-${cleanNoteId}` + ) as HTMLElement | null + + if (element) { + scrollToNote(element.offsetTop) + return + } + + requestAnimationFrame(() => { + scrollToNoteElement(cleanNoteId, index, attempts - 1) + }) + } + type ScrollToFocusedNoteOptions = { noteId?: string | null notes?: string[] @@ -65,13 +89,7 @@ export const useRouteQueryStackedNotes = () => { if (isMobile.value) { if (noteId) { - const cleanNoteId = noteId.replaceAll(":", "-") - const element = document.querySelector( - `.note-${cleanNoteId}` - ) as HTMLElement - - const top = (index + 1) * (element?.clientHeight ?? height.value) - scrollToNote(top) + scrollToNoteElement(noteId.replaceAll(":", "-"), index) } else { scrollToNote(0) }