Replace the "QR Coming Soon" placeholder with a real QR code
(qrcode.react) encoding the room URL. Scan to join.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Trigger GeolocateControl on map load so the map flies to the user's
position. Default viewport changed from Hamburg CCH zoom-15 to a
world view, so denied geolocation still looks reasonable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The file: link to ../encryptid-sdk requires the build context to be
the parent directory so Docker can access the SDK as a sibling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Anonymous-first role resolution (PARTICIPANT default for open rooms).
Queries EncryptID server for space-linked rooms with 5-minute cache.
Capability checks for add_markers, share_location, configure_map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Server-side participant dedup on join: remove ghost entries with same name but different ID
- Reduce stale participant threshold from 1hr to 15min to match client-side cleanup
- Refactor push subscriptions from Set to Map keyed by endpoint (prevents duplicate pushes)
- Store participantId with push subscriptions for identity-aware routing
- Exclude joining user from their own "Friend Joined" push notification
- Callout (ping) sends visible push to offline users ("X is looking for you!") instead of silent push
- Return last known locations in callout API response for immediate display
- Service worker: 10s cooldown on location request pushes to prevent burst on app reopen
- Service worker: suppress join/leave notifications when app window is focused
- Pass callerName from ParticipantList so offline callout shows who's looking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace static SVG map with real-time WebSocket connection to the
shared demo community. Alpine route map with interactive markers,
all changes sync across the r* ecosystem in real-time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace duplicated WebAuthn ceremony code with SDK EncryptIDClient.
Add @encryptid/sdk dependency and cookie persistence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Overhaul landing page from login screen to proper hero + features.
Add interactive demo page showing CCC Camp 2026 event with SVG camp
map, animated friend markers, status system, and friend list panel.
Add ecosystem footer to both pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verify JWT tokens on WebSocket connections via query param. Check room
visibility before allowing access. Block writes from read-only connections.
Add room config endpoint. Require auth for creating new rooms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add optional passkey identity (anonymous access remains default):
- Add Zustand auth store with EncryptID login/register/logout
- Add AuthButton component to home page
- Auto-fill name from EncryptID when authenticated
- Use DID as persistent participant ID in rooms when signed in
- Update useRoom hook to accept optional encryptIdDid
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Users can now upload the ZIP file directly from Google Takeout
- No need to extract the ZIP first
- Simplified 3-step instructions with direct link to Takeout
- Added JSZip dependency for ZIP processing
- Auto-detects saved places JSON in various ZIP structures
- Shows loading spinner while processing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add flex-shrink-0 to prevent header from being compressed
- Increase header z-index to z-30 to stay above map elements
- Add relative positioning to header
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows a prominent button at bottom-left (mobile) or top-left (desktop)
to reopen the friends list after closing it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add googleMapsParser.ts utility for parsing Google Takeout GeoJSON
- Add ImportModal component with drag-and-drop file upload
- Three-step wizard: Upload → Preview → Success
- Preview list with checkboxes and select/deselect all
- Add "Import Places" button to ParticipantList footer
- Imported places become waypoints with type "poi"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enhanced service worker with multi-strategy caching:
- App shell precaching for instant loading
- Map tiles cache-first with background refresh (max 500 tiles)
- API requests network-first with cache fallback
- Static assets stale-while-revalidate
- IndexedDB room state persistence for offline access
- Room state sync in useRoom hook:
- Saves state to service worker on changes
- Loads cached state on initial load for offline fallback
- Message handlers for SAVE_ROOM_STATE, GET_ROOM_STATE, CLEAR_CACHES
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed ping button icon from circular arrows to bell with brackets
- Added individual ping button on each participant row
- Server now supports targeting specific participant by ID
- Deduplication still applies (only pings one session per name)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. Stale locations (>5 min old) are now greyed out on the map with
reduced opacity and hover tooltip showing time since last seen
2. Removed indoor map button and related UI elements
3. Location request pings now deduplicate by participant name to
avoid pinging the same user multiple times
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- After 2 consecutive timeouts with high accuracy mode, automatically
switch to low accuracy mode (WiFi/cell-based location)
- Increased maxAge from 5s to 30s to accept older cached positions
- Reduced timeout from 30s to 15s for faster fallback
- Low accuracy mode uses 60s maxAge and 60s timeout for reliability
This helps indoor users who can't get GPS signal.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- JoinForm now pre-populates name/emoji from localStorage and shows
a "Quick Join as [name]" button for returning users
- Home page shows "Rejoin /[room]" button when user has visited before
- Room slug saved to localStorage on every visit for quick rejoin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added useMemo-based deduplication that keeps the most recently seen
participant for each name, preventing duplicate markers on the map
and duplicate entries in the friends list.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add inline JoinForm when navigating directly to room URL
- No longer redirects to home page for new users
- Replace c3nav iframe with fallback UI (c3nav blocks iframe embedding)
- Add 'Open c3nav' button to open indoor map in new tab
- Still shows friend markers with indoor locations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When clicking a user from the participant list:
1. Map zooms to their location
2. Navigation panel appears with "Navigate here" option
3. Clicking "Navigate here" calculates route to that user
The selectedParticipant state is now lifted to the page level and
passed to DualMapView so both components stay in sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace all Google Maps navigation links with in-app zoom functionality.
When clicking on a participant or waypoint to navigate, the map now
smoothly flies to their location at zoom level 17 instead of opening
an external Google Maps link.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pass current location from useLocationSharing hook to navigateTo
instead of using stale data from the Zustand store. This fixes the
"Enable location sharing to get directions" error when already sharing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Request push notification permission automatically when joining a room,
similar to how location permission is requested.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-subscribe to push notifications when location sharing starts
- Use C3NavEmbed (iframe) for faster indoor map loading
- Set event to 39c3 for current congress
- Increase c3nav API cache to 1 hour with stale-while-revalidate
- Add strong vibration pattern and sound for notifications
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Navigate button now opens Google Maps directions to friend's location
- Added PWA install banner for non-installed users
- iOS users get manual instructions for Add to Home Screen
- Banner can be dismissed and stays dismissed for session
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Server sends request_location via WebSocket to connected clients
- Falls back to silent push for offline/background clients
- Client responds with current GPS location when requested
- Refresh button now works for online friends (no push subscription needed)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sends silent push to all friends requesting location updates
- Shows spinner while refreshing
- Displays feedback message with count of pinged friends
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- POST /push/request-location with { roomSlug } triggers silent push
- Returns count of sent/failed notifications
- Useful for on-demand location refresh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Server sends silent push notifications every 60s (configurable)
- Only requests from rooms with active participants
- Cleans up stale push subscriptions automatically
- Interval configurable via LOCATION_REQUEST_INTERVAL env var
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Background Sync API support for location sync when coming back online
- Add silent push notifications for requesting location updates
- Add useServiceWorkerMessages hook for handling SW messages
- Connect service worker to location sharing for background updates
This enables:
- Silent location requests via push without showing notifications
- Automatic location sync when device comes back online
- Service worker communication for background location updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 39c3 to all valid event lists
- Change default event ID from 38c3 to 39c3
- Update examples and placeholders throughout codebase
- Maintain backwards compatibility with 38c3 and older events
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add WaypointModal component with delete and navigate actions
- Navigate button opens Google Maps directions to waypoint
- Delete button removes waypoint with confirmation
- Sync server now preserves offline users' last locations
- Users marked as offline instead of removed when disconnecting
- Stale participant cleanup still runs after 1 hour threshold
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remember location sharing preference per room
- Auto-start sharing when returning to a room
- Restore last known location immediately on page load (if < 1 hour old)
- Location updates are saved to localStorage for faster reload
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move room page from /room/[slug] to /[slug]
- Update all navigation links to use /<slug> format
- Update share URL generation
- Update middleware for subdomain handling
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>