# GroupChat2 Client The client is a Riot.js single-page application that handles authentication, room navigation, chat rendering, invite flows, profile editing, and the live chat experience on top of the server's REST and WebSocket APIs. ## Stack - Riot.js components - Vite dev/build pipeline - Vanilla JavaScript - `markdown-it` and `highlight.js` for message rendering ## Responsibilities - Render login and registration flows - Show the room list, active chat, and profile UI - Connect to the server over WebSockets for live updates - Stream AI responses into the message list as they arrive - Support invite links and message permalink navigation - Upload avatars and chat images through the API - Handle token expiry by logging the user out cleanly ## Commands ```bash npm install npm run dev ``` ```bash npm run build ``` ```bash npm run preview ``` By default Vite runs on port `3000`. ## Dev Server Behavior The Vite config proxies these paths to the backend: - `/api` - `/ws` - `/uploads` Relevant runtime vars: - `VITE_PORT`: client port, default `3000` - `VITE_API_PORT`: backend port, default `3001` This lets the frontend use relative paths in development and production. ## App Structure ```text src/ |- components/ Riot UI components for auth, rooms, messages, modals, profile |- services/ API wrapper, WebSocket manager, markdown, avatar, Nostr helpers |- styles/ Global styles |- main.js Component registration and app mount ``` Main UI pieces: - `app.riot`: top-level auth state, room state, modal state, and message link handling - `chat-sidebar.riot`: room list and account actions - `chat-room.riot`: main conversation view and composer - `message-bubble.riot`: message rendering, hashes, metadata, and markdown output - `profile-page.riot`: display name and avatar management ## Runtime Notes - Authentication state is stored in `localStorage`. - Pending invite tokens and message permalinks are staged through `sessionStorage` when needed. - The WebSocket layer automatically reconnects and re-joins subscribed rooms. - AI output is streamed chunk-by-chunk and rendered progressively before the final stored message arrives. - Message links support both `#roomId/messageHash` and older hash-only navigation. ## Integration Contract The client expects the backend to provide: - JWT auth endpoints under `/api/auth/*` - Room, message, invite, upload, and model endpoints under `/api/*` - A WebSocket endpoint at `/ws?token=...` - Uploaded media under `/uploads/*` For backend setup and env configuration, see the [Server README](../server/README.md).