Listen for hnf:viewport postMessage — resize iframe to 1280px for desktop-forced pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9e5c415685
commit
de49df70b0
1 changed files with 17 additions and 3 deletions
|
|
@ -9,6 +9,7 @@ export function AppFrame({ user }: { user: User }) {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const app = user.apps.find(a => a.slug === slug)
|
const app = user.apps.find(a => a.slug === slug)
|
||||||
const [menuOpen, setMenuOpen] = useState(false)
|
const [menuOpen, setMenuOpen] = useState(false)
|
||||||
|
const [desktopFrame, setDesktopFrame] = useState(false)
|
||||||
const iframeRef = useRef<HTMLIFrameElement>(null)
|
const iframeRef = useRef<HTMLIFrameElement>(null)
|
||||||
|
|
||||||
// Capture hash once at mount — before iframe navigation overwrites it
|
// 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}/`
|
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(() => {
|
useEffect(() => {
|
||||||
|
setDesktopFrame(false)
|
||||||
return () => { history.replaceState(null, '', window.location.pathname) }
|
return () => { history.replaceState(null, '', window.location.pathname) }
|
||||||
}, [slug])
|
}, [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
|
// Auto-close when user clicks into / navigates within the iframe
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!menuOpen) return
|
if (!menuOpen) return
|
||||||
|
|
@ -32,6 +44,8 @@ export function AppFrame({ user }: { user: User }) {
|
||||||
}, [menuOpen])
|
}, [menuOpen])
|
||||||
|
|
||||||
function handleIframeLoad() {
|
function handleIframeLoad() {
|
||||||
|
// Each page declares its own viewport preference on mount; reset between navigations
|
||||||
|
setDesktopFrame(false)
|
||||||
try {
|
try {
|
||||||
const iframePath = iframeRef.current?.contentWindow?.location.pathname ?? ''
|
const iframePath = iframeRef.current?.contentWindow?.location.pathname ?? ''
|
||||||
const relative = iframePath.replace(app!.base_path, '') || '/'
|
const relative = iframePath.replace(app!.base_path, '') || '/'
|
||||||
|
|
@ -97,13 +111,13 @@ export function AppFrame({ user }: { user: User }) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* App iframe */}
|
{/* App iframe */}
|
||||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflowX: desktopFrame ? 'auto' : 'hidden', overflowY: 'hidden' }}>
|
||||||
<div style={{ height: '3px', background: app.theme_color, flexShrink: 0 }} />
|
<div style={{ height: '3px', background: app.theme_color, flexShrink: 0 }} />
|
||||||
<iframe
|
<iframe
|
||||||
ref={iframeRef}
|
ref={iframeRef}
|
||||||
src={initialSrc}
|
src={initialSrc}
|
||||||
title={app.name}
|
title={app.name}
|
||||||
style={{ flex: 1, border: 'none', width: '100%' }}
|
style={{ flex: 1, border: 'none', width: desktopFrame ? '1280px' : '100%', minWidth: desktopFrame ? '1280px' : undefined }}
|
||||||
allow="clipboard-read; clipboard-write"
|
allow="clipboard-read; clipboard-write"
|
||||||
onLoad={handleIframeLoad}
|
onLoad={handleIframeLoad}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue