Files
hanzo.ai/app/(app)/chat/_door.tsx
zeekay 6c65e3e941 @hanzo/app 0.2.0: the app SDK, renamed from @hanzo/rooms
Every import, the catalog pin and the docs name @hanzo/app and
github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and
components/rooms.tsx is components/app.tsx.
2026-10-22 19:07:20 -07:00

44 lines
1.6 KiB
TypeScript

'use client'
// /chat, and by the edge every conversation under it (lib/edge.ts `APP`): the
// app in Chat. A conversation is its path, `/chat/<id>` (@hanzo/app lib/host
// `talk`, `place`).
//
// signed in the app (app/_web.tsx), drawn here as on `/`. A conversation
// at the address it had before, `/chat?thread=<id>`, is moved to
// its path first, once, so Back does not land on it (`moved`).
// signed out sign in first (destination.ts `enter`). The address is written
// down on the way out, so the sign-in returns here and the first
// case takes over.
import { useEffect, useState } from 'react'
import dynamic from 'next/dynamic'
import { useIam } from '@hanzo/iam/react'
import { enter } from '@hanzo/app/lib/destination'
import { CHAT, talk } from '@hanzo/app/lib/host'
/** The app, fetched only for a signed-in reader. */
const App = dynamic(() => import('../../_web'), { ssr: false })
/** The path a retired Chat address names; null when it is current. */
export function moved(pathname: string, q: URLSearchParams): string | null {
if (pathname !== CHAT) return null
const thread = q.get('thread')
return thread ? talk(thread) : null
}
export function Door() {
const { isLoading, isAuthenticated } = useIam()
const [ready, setReady] = useState(false)
useEffect(() => {
if (isLoading) return
if (!isAuthenticated) return enter()
const to = moved(window.location.pathname, new URLSearchParams(window.location.search))
if (to) window.history.replaceState(null, '', to)
setReady(true)
}, [isLoading, isAuthenticated])
return ready ? <App /> : null
}