fix recipe ig post can't load problem
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
animationFrame = window.requestAnimationFrame(attemptScroll)
|
||||
|
||||
return () => {
|
||||
// Replay pending section scroll requests written to sessionStorage
|
||||
const clearTimers = () => {
|
||||
if (animationFrame) {
|
||||
window.cancelAnimationFrame(animationFrame)
|
||||
animationFrame = 0
|
||||
}
|
||||
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 (
|
||||
<>
|
||||
|
||||
@@ -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<void>((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 (
|
||||
<Box
|
||||
@@ -105,6 +172,7 @@ function Recipe() {
|
||||
|
||||
|
||||
<Box
|
||||
key={post.id}
|
||||
justifyItems={'center'}
|
||||
alignItems={'center'}
|
||||
width={325}
|
||||
|
||||
5
src/types/global.d.ts
vendored
5
src/types/global.d.ts
vendored
@@ -4,4 +4,9 @@ interface Window {
|
||||
parse: (element?: Element) => void;
|
||||
};
|
||||
};
|
||||
instgrm?: {
|
||||
Embeds?: {
|
||||
process?: () => void;
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user