diff --git a/src/components/header.tsx b/src/components/header.tsx index e39e84b..431ffb3 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -82,19 +82,29 @@ function Header({ showMenu = false }: HeaderProps) { return; } - router.navigate({ - to: '/', - hash: targetId, - replace: location.pathname === '/', - }); + if (typeof window !== 'undefined') { + window.sessionStorage.setItem('pendingScrollSection', targetId); + window.dispatchEvent(new CustomEvent('pending-scroll-section')); + } + + if (!isOnMainPage) { + router.navigate({ to: '/' }); + } }; const handleMenuClick = (itemId: string) => { if (itemId === 'recipes') { - router.navigate({ - to: '/recipe', - replace: location.pathname === '/recipe', - }); + const isOnRecipePage = location.pathname === '/recipe'; + + if (isOnRecipePage) { + // Already on recipe page, just close drawer + setIsDrawerOpen(false); + return; + } + + // Navigate from main page - force reload to ensure Instagram embeds work + window.location.href = '/recipe'; + return; } else { scrollToSection(itemId); } diff --git a/src/pages/main.tsx b/src/pages/main.tsx index 127dd59..73237a9 100644 --- a/src/pages/main.tsx +++ b/src/pages/main.tsx @@ -17,34 +17,70 @@ function MainPage() { const { location } = useRouterState() useEffect(() => { - if (location.pathname !== '/' || !location.hash) { + if (location.pathname !== '/') { return } - const targetId = location.hash.replace('#', '') let animationFrame = 0 let retryTimeout: number | undefined - const attemptScroll = () => { - const element = document.getElementById(targetId) - if (element) { - element.scrollIntoView({ behavior: 'smooth' }) - } else { - retryTimeout = window.setTimeout(() => { - animationFrame = window.requestAnimationFrame(attemptScroll) - }, 50) + // Replay pending section scroll requests written to sessionStorage + const clearTimers = () => { + if (animationFrame) { + window.cancelAnimationFrame(animationFrame) + animationFrame = 0 } - } - - animationFrame = window.requestAnimationFrame(attemptScroll) - - return () => { - window.cancelAnimationFrame(animationFrame) if (retryTimeout) { window.clearTimeout(retryTimeout) + retryTimeout = undefined } } - }, [location.pathname, location.hash]) + + const attemptScroll = (targetId: string) => { + clearTimers() + + const scrollToTarget = () => { + const element = document.getElementById(targetId) + if (element) { + window.sessionStorage.removeItem('pendingScrollSection') + element.scrollIntoView({ behavior: 'smooth' }) + animationFrame = 0 + retryTimeout = undefined + return + } + + retryTimeout = window.setTimeout(() => { + animationFrame = window.requestAnimationFrame(scrollToTarget) + }, 50) + } + + animationFrame = window.requestAnimationFrame(scrollToTarget) + } + + const runScroll = () => { + if (typeof window === 'undefined') { + return + } + + const targetId = window.sessionStorage.getItem('pendingScrollSection') + if (targetId) { + attemptScroll(targetId) + } + } + + const handlePendingEvent = () => { + runScroll() + } + + runScroll() + + window.addEventListener('pending-scroll-section', handlePendingEvent) + + return () => { + window.removeEventListener('pending-scroll-section', handlePendingEvent) + clearTimers() + } + }, [location.pathname]) return ( <> diff --git a/src/pages/recipe.tsx b/src/pages/recipe.tsx index 416ed35..91d4115 100644 --- a/src/pages/recipe.tsx +++ b/src/pages/recipe.tsx @@ -72,6 +72,73 @@ function Recipe() { }; }, []); + useEffect(() => { + if (typeof window === 'undefined') { + return; + } + + let isCancelled = false; + let retryTimeout: number | undefined; + const scriptId = 'instagram-embed-script'; + const maxRetries = 10; + let retries = 0; + + const clearRetry = () => { + if (retryTimeout) { + window.clearTimeout(retryTimeout); + retryTimeout = undefined; + } + }; + + const scheduleProcess = () => { + if (isCancelled) { + return; + } + + const process = window.instgrm?.Embeds?.process; + if (process) { + process(); + clearRetry(); + return; + } + + if (retries < maxRetries) { + retries += 1; + retryTimeout = window.setTimeout(scheduleProcess, 400); + } + }; + + const ensureScript = () => new Promise((resolve) => { + const existingScript = document.getElementById(scriptId) as HTMLScriptElement | null; + + if (existingScript) { + if (window.instgrm?.Embeds?.process) { + resolve(); + } else { + existingScript.addEventListener('load', () => resolve(), { once: true }); + } + return; + } + + const script = document.createElement('script'); + script.id = scriptId; + script.src = 'https://www.instagram.com/embed.js'; + script.async = true; + script.defer = true; + script.onload = () => resolve(); + script.onerror = () => resolve(); + document.body.appendChild(script); + }); + + ensureScript().then(() => scheduleProcess()); + scheduleProcess(); + + return () => { + isCancelled = true; + clearRetry(); + }; + }, []); + return ( void; }; }; + instgrm?: { + Embeds?: { + process?: () => void; + }; + }; } \ No newline at end of file