Commit Graph

47 Commits

Author SHA1 Message Date
Jeff Emmett 9d8314096b feat: Add comprehensive PWA offline support
- 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>
2026-01-02 17:04:07 +01:00
Jeff Emmett cf8bd63298 docs: Update backlog tasks with session progress
- task-3 (Push notifications): Marked Done, added implementation notes
- task-4 (PWA offline): Marked In Progress, documented partial impl
- task-6 (c3nav indoor): Added note about removing indoor button
- task-12 (Stale participants): Added greyed-out locations feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 15:30:13 +01:00
Jeff Emmett c34a84672a feat: Bell icon for pings and individual user ping support
- 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>
2026-01-02 13:32:25 +01:00
Jeff Emmett ff45193ba2 feat: Grey out stale locations, remove indoor map, dedupe pings
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>
2026-01-02 13:06:52 +01:00
Jeff Emmett 007a7e877f fix: Add fallback to low-accuracy geolocation when GPS times out
- 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>
2026-01-02 10:23:06 +01:00
Jeff Emmett 2284f94ee3 feat: Auto-load saved user and remember last visited room
- 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>
2025-12-29 21:19:03 +01:00
Jeff Emmett 47dea7c9c3 fix: Deduplicate participants by name across map and list
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>
2025-12-29 20:21:52 +01:00
Jeff Emmett 796fd2c727 feat: Direct room URL navigation + fix c3nav iframe blocking
- 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>
2025-12-29 15:48:30 +01:00
Jeff Emmett 908767be15 feat: Show navigation panel when clicking user from list
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>
2025-12-29 03:03:16 +01:00
Jeff Emmett 40cfea26a2 feat: Zoom to location instead of opening Google Maps
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>
2025-12-29 02:53:16 +01:00
Jeff Emmett 1dddf16c6a fix: Navigation now uses actual current location
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>
2025-12-29 02:46:07 +01:00
Jeff Emmett b8adffc4ad fix: Request notification permission on room join
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>
2025-12-29 02:37:39 +01:00
Jeff Emmett 4f110a7604 feat: Add push notifications for background friend pings
- 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>
2025-12-29 02:33:08 +01:00
Jeff Emmett 7410246a01 feat: Fix navigate button and add PWA install prompt
- 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>
2025-12-29 01:54:25 +01:00
Jeff Emmett d6a20f9500 feat: Add WebSocket-based location refresh for online friends
- 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>
2025-12-29 01:51:09 +01:00
Jeff Emmett aa501b1778 fix: Add Background Sync API type declarations
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 01:43:47 +01:00
Jeff Emmett 9c618cffb7 fix: Cast applicationServerKey to ArrayBuffer for strict TypeScript
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 01:41:36 +01:00
Jeff Emmett 6e360c6b6a fix: Use correct waypoint type 'meetup' instead of 'meeting_point'
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 01:37:50 +01:00
Jeff Emmett 4ab4f28e70 feat: Add refresh locations button to participant list
- 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>
2025-12-29 01:35:32 +01:00
Jeff Emmett 4ee33f4992 feat: Add /push/request-location endpoint for manual location pings
- 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>
2025-12-29 01:30:14 +01:00
Jeff Emmett ca1cd4877d feat: Add automatic periodic location requests via silent push
- 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>
2025-12-29 01:27:00 +01:00
Jeff Emmett 27e8344e7a feat: Add background location sync via service worker
- 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>
2025-12-29 01:15:17 +01:00
Jeff Emmett dcb6657966 feat: Add PWA push notifications for room events
- Add service worker (sw.js) for push notification handling
- Add usePushNotifications hook for subscription management
- Add NotificationToggle component in room header
- Update sync server with web-push for sending notifications
- Add VAPID keys configuration
- Notifications for: friend joins, friend leaves, meeting points set

Push notification events:
- Friend joins room: "Friend Joined! 👋"
- Friend leaves room: "Friend Left"
- Meeting point set: "Meeting Point Set! 📍"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 01:13:16 +01:00
Jeff Emmett 8eed0deadf feat: Update c3nav event from 38c3 to 39c3
- 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>
2025-12-29 01:03:37 +01:00
Jeff Emmett 003d3b0187 feat: Add waypoint modal and preserve offline user locations
- 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>
2025-12-29 00:58:10 +01:00
Jeff Emmett 6294e1de41 feat: Persist location sharing across browser sessions
- 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>
2025-12-28 23:47:44 +01:00
Jeff Emmett 912104f740 feat: Simplify URL structure to rmaps.online/<room>
- 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>
2025-12-28 23:42:20 +01:00
Jeff Emmett 96fea103fd fix: Move share location button to bottom right
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 23:37:41 +01:00
Jeff Emmett e59150a9ce fix: Improve location handling, session persistence, and mobile UI
Location fixes:
- Add coordinate validation to reject invalid (0,0) and out-of-bounds locations
- Clean up stale participants after 15 minutes (was 1 hour)
- Remove invalid locations from localStorage on load
- Use CCH venue center instead of (0,0) for indoor positions without GPS

Session persistence:
- Remember user name and emoji across sessions on home page
- Pre-fill profile form with saved user info

Mobile UI improvements:
- Add floating location share button inside the map
- Visible on all screen sizes with responsive text
- Prominent styling: white when inactive, green when sharing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 23:34:00 +01:00
Jeff Emmett a6c124c14c feat: Add navigation routes feature with indoor/outdoor routing
- Add /api/routing endpoint for route calculation
- Support OSRM for outdoor walking/driving routes
- Support c3nav API for indoor routes at CCC events
- Add RouteOverlay component for map route visualization
- Add NavigationPanel for participant/waypoint navigation UI
- Integrate route state management into Zustand store
- Display route line on outdoor map with distance/time estimates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 23:24:42 +01:00
Jeff Emmett 2d960a53f2 fix: Send join message after WebSocket connects
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>
2025-12-26 20:39:44 -05:00
Jeff Emmett 8554a4cb1a feat: Add WebSocket sync server for real-time location sharing
- Add sync-server/ with Node.js WebSocket relay server
- Server handles join/leave/location/waypoint messages
- Auto-cleans stale participants (1hr) and empty rooms (24hr)
- Dockerized with Traefik labels for easy deployment
- Update .env.example with NEXT_PUBLIC_SYNC_URL
- Mark task-5 as Done in backlog

Deployed to https://sync.rmaps.online

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 22:00:55 -05:00
Jeff Emmett 39f8c83ba9 fix: Add coordinate validation to prevent Invalid LngLat errors
- Add isValidCoordinate() helper to validate lat/lng ranges
- Validate viewport center on map initialization
- Skip participants and waypoints with invalid coordinates
- Add validation to auto-center and fitToParticipants

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 21:28:34 -05:00
Jeff Emmett eeab19ceac fix: Clean up stale participant sessions from map
- 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>
2025-12-19 13:28:35 -05:00
Jeff Emmett 760e27564c feat: Add c3nav indoor map integration with floor selector
- 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>
2025-12-16 19:44:33 -05:00
Jeff Emmett 50e1feb62c Improve Meeting Point UX: add address search, fix Indoor Map
- Indoor Map now opens c3nav in new tab (iframe blocked by X-Frame-Options)
- Meeting Point modal now has:
  - "Use My Location" button that fetches GPS position on demand
  - Address search using OpenStreetMap Nominatim API
  - Search results dropdown with clickable options
  - Manual coordinates entry (hidden by default)
  - Selected location preview with coordinates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 16:38:14 -05:00
Jeff Emmett 0a234f902a Fix Indoor Map button, add Meeting Point functionality, render waypoints
- Fix Indoor Map button being covered by participant panel (z-30)
- Implement Set Meeting Point modal with emoji selection
- Add waypoint markers rendering on the map
- Pass waypoints from room through DualMapView to MapView
- Fix TypeScript types for WaypointType

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 16:31:19 -05:00
Jeff Emmett 1a996931b5 Fix location sharing: opt-in by default, stop button clears location from map 2025-12-15 15:47:31 -05:00
Jeff Emmett 6d55e1c5a9 Reduce maxAge to 5 seconds for fresher location updates 2025-12-15 15:45:09 -05:00
Jeff Emmett d8e21b8cdf Fix location sharing: increase timeout, prevent auto-start cycling, graceful error handling 2025-12-15 15:44:34 -05:00
Jeff Emmett 45c4ebc602 Add auto-center on user location when first acquired 2025-12-15 14:44:40 -05:00
Jeff Emmett 3e5437fb14 Fix stale closure in location update callback + add debug logging 2025-12-15 14:42:32 -05:00
Jeff Emmett ff8dead7f2 Initialize backlog with feature tasks 2025-12-15 14:38:46 -05:00
Jeff Emmett 0a74de533d Simplify Traefik labels for compatibility 2025-12-15 14:33:28 -05:00
Jeff Emmett 23cbe6caa8 Replace Automerge with simple WebSocket sync
- 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>
2025-12-15 12:59:22 -05:00
Jeff Emmett 530979978d Add real-time sync, c3nav integration, and PWA icons
Features:
- Automerge-based real-time room sync with CRDT
- c3nav indoor map integration for CCC events
- DualMapView component (auto-switches indoor/outdoor)
- useRoom hook for room state management
- PWA icons and manifest

Infrastructure:
- DNS configured for rmaps.online, www, and *.rmaps.online
- Cloudflare tunnel updated for wildcard subdomains
- Fixed Next.js security update to 14.2.28

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 12:50:28 -05:00
Jeff Emmett dc0661d58a Initial scaffold for rMaps.online
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>
2025-12-15 12:23:13 -05:00