Ping notifications now show who pinged: "<Name> pinged you for your
location!" instead of generic "Someone is looking for you". Caller name
flows through WS messages, silent push payloads, SW postMessage, URL
params (?pinger=), and visible push notifications.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes for offline ping gaps:
1. SW silent push fallback: when a manual ping arrives as a silent push
but no app window is open, show a visible notification with vibration
instead of failing silently.
2. SW notificationclick: when opening a fresh window (app was closed),
append ?ping=manual to the URL so the app can detect it was pinged.
3. page.tsx: on mount, detect ?ping=manual param, clean it from the URL,
and auto-fire GPS once the WebSocket connection is established.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Manual "Ping All" now sends `manual: true` flag through WebSocket and
push channels. Receiving clients vibrate and respond with a one-shot
getCurrentPosition() regardless of sharing toggle. Auto-periodic 60s
pings stay silent and only respond if sharing is enabled.
Also fixes: SW cache invalidation (v2→v3), navigation requests now
network-first, sync server lastSeen uses ISO strings, Dockerfile
includes verify-token.js.
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>
- 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>
- 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>
- 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>
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>