diff --git a/app/mobile/engagement/page.tsx b/app/mobile/engagement/page.tsx index 80c7093..4170f0c 100644 --- a/app/mobile/engagement/page.tsx +++ b/app/mobile/engagement/page.tsx @@ -205,12 +205,24 @@ export default function MobileEngagementPage() { if (!raw) { restoredScrollRef.current = true; return; } try { const { main: mainTop, win: winTop } = JSON.parse(raw) as { main: number; win: number }; - // Defer one frame so layout has settled with the new rows in place. - requestAnimationFrame(() => { + // Retry across frames until document height supports the target scroll; + // initial render may compute heights lazily and clamp scrollTo to a small + // maxScroll. Cap attempts so we never loop forever. + let attempts = 0; + const tryRestore = () => { const main = document.querySelector('main'); if (main && mainTop) main.scrollTop = mainTop; if (winTop) window.scrollTo(0, winTop); - }); + const winNow = window.scrollY; + const mainNow = main?.scrollTop ?? 0; + const winOk = !winTop || Math.abs(winNow - winTop) <= 4; + const mainOk = !mainTop || Math.abs(mainNow - mainTop) <= 4; + if ((!winOk || !mainOk) && attempts < 30) { + attempts++; + requestAnimationFrame(tryRestore); + } + }; + requestAnimationFrame(tryRestore); } catch { /* corrupt entry — ignore */ }