diff --git a/src/pages/AppFrame.tsx b/src/pages/AppFrame.tsx index c99704c..43288b6 100644 --- a/src/pages/AppFrame.tsx +++ b/src/pages/AppFrame.tsx @@ -9,6 +9,7 @@ export function AppFrame({ user }: { user: User }) { const navigate = useNavigate() const app = user.apps.find(a => a.slug === slug) const [menuOpen, setMenuOpen] = useState(false) + const [desktopFrame, setDesktopFrame] = useState(false) const iframeRef = useRef(null) // Capture hash once at mount — before iframe navigation overwrites it @@ -18,11 +19,22 @@ export function AppFrame({ user }: { user: User }) { return sub && sub !== '/' ? `${app.base_path}${sub}` : `${app.base_path}/` }) - // Clear hash when switching apps + // Clear hash and reset desktop frame when switching apps useEffect(() => { + setDesktopFrame(false) return () => { history.replaceState(null, '', window.location.pathname) } }, [slug]) + // Listen for viewport mode requests from embedded apps + useEffect(() => { + function handleMessage(e: MessageEvent) { + if (e.data?.type !== 'hnf:viewport') return + setDesktopFrame(e.data.mode === 'desktop') + } + window.addEventListener('message', handleMessage) + return () => window.removeEventListener('message', handleMessage) + }, []) + // Auto-close when user clicks into / navigates within the iframe useEffect(() => { if (!menuOpen) return @@ -32,6 +44,8 @@ export function AppFrame({ user }: { user: User }) { }, [menuOpen]) function handleIframeLoad() { + // Each page declares its own viewport preference on mount; reset between navigations + setDesktopFrame(false) try { const iframePath = iframeRef.current?.contentWindow?.location.pathname ?? '' const relative = iframePath.replace(app!.base_path, '') || '/' @@ -97,13 +111,13 @@ export function AppFrame({ user }: { user: User }) { )} {/* App iframe */} -
+