/** * ChatPage -- Routable messaging page with header and MessageList. * Parent container must have a definite height (h-full / flex-1). */ import { useEffect, useRef } from 'react' import { useChatChannel } from '../components/messaging/hooks/useChatChannel' import { RecordScope, useReadReceipts, useUser, isWriterRole } from 'deepspace' import type { CollectionSchema } from 'deepspace/schema' import { messagingSchemas } from '../schemas/messaging-schema' import { ChatHeader } from '../components/messaging/chat/ChatHeader' import { MessageList } from '../components/messaging/chat/MessageList' interface ChatPageProps { schemas?: CollectionSchema[] channelName?: string className?: string } export default function ChatPage({ schemas = messagingSchemas, channelName = 'general', className, }: ChatPageProps) { const { channelId, status } = useChatChannel(channelName) const { markAsRead } = useReadReceipts() const { user } = useUser() const lastMarkedRef = useRef(null) const canTrackReadState = isWriterRole(user?.role) useEffect(() => { if (!channelId || !canTrackReadState) return if (lastMarkedRef.current === channelId) return lastMarkedRef.current = channelId markAsRead(channelId) }, [canTrackReadState, channelId, markAsRead]) if (status !== 'ready') { // data-testid lets tests (and humans reading a trace) distinguish "stuck // waiting for the default channel" from "route never mounted". return (
Loading chat...
) } if (!channelId) { return (

No public channel exists yet.

A member or admin can create the first channel.

) } return (
) }