The join() was called before connect(), so the join message was never
sent to the server. Now we store the participant and send the join
message in the WebSocket onopen handler.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add cleanupStaleParticipants() to remove participants not seen in last hour
- Use persistent participant ID per browser/room to prevent ghost duplicates
- Fixes issue where old versions of yourself appeared on map reload
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add c3nav tile proxy API route with session handling
- Add c3nav data API proxy for locations/bounds
- Create IndoorMapView component with MapLibre GL
- Add floor level selector (Level 0-4)
- Tap-to-set-position on indoor map
- Sync indoor positions between participants
- Easter egg: Triple-click Level 0 for "The Underground of the Underground"
- Fix race condition in useRoom when no user data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove Automerge dependencies (WASM incompatible with Next.js)
- Add lightweight WebSocket-based sync layer
- Works in local-only mode until sync server deployed
- State persisted in localStorage for reconnection
Ready for deployment - sync server can be added later.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Collaborative real-time friend-finding navigation for events:
- Next.js 14 with TypeScript and Tailwind CSS
- MapLibre GL for outdoor OpenStreetMap rendering
- c3nav API client for CCC indoor navigation
- Zustand for state management
- Location sharing hook with privacy controls
- Room system with subdomain routing middleware
- Docker + docker-compose with Traefik labels
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>