Commit Graph

55 Commits

Author SHA1 Message Date
Jeff Emmett 63473187a8 feat: add InfoPopup with landing page content on first visit
Shows an informational popup with rich landing page content on first
visit, re-openable via a fixed info button (bottom-right corner).
Dismissible via X button, overlay click, or Escape key. Uses
localStorage to track first-visit state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 04:53:41 +00:00
Jeff Emmett 720f0ecf1b fix: replace placeholder Umami website ID with real registered UUID
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:26:00 -07:00
Jeff Emmett 33e7a955be brand: add (you)r* prefix to landing page title
Reinforces the r-suite "your tools" philosophy across all rApp landing pages.
Also normalizes title separators to em-dash for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 04:24:04 +00:00
Jeff Emmett 8078f70955 feat: standardize header, categories, cross-app spaces
- AppSwitcher: rTube/rSwag → Creating, rSocials → Sharing, rData → Observing
- EcosystemFooter: updated link order to match new categories
- UserMenu: 🔑 Sign In button, 🔐 lock when logged in
- SpaceSwitcher: reads EncryptID token, sends Bearer header
- /api/spaces proxy: forwards to rspace.online (canonical spaces)
- /api/me: verifies EncryptID token for auth status
- Header.tsx: standardized bg-slate-900/85 across all apps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:16:55 -08:00
Jeff Emmett 460dc5045f feat: redesign landing page with full feature showcase
Replace minimal 3-card landing page with comprehensive feature
presentation matching the rApp ecosystem style:

- Hero with ecosystem badge and gradient accents
- 4 core feature cards (GPS, navigation, meeting points, privacy)
- 6 differentiator cards (c3nav, pinging, Google import, PWA, QR, CRDT)
- How It Works steps
- Use case cards (festivals, city exploration, group coordination)
- Technical highlights grid (MapLibre, OSRM, c3nav, Automerge, etc.)
- Preserved existing Get Started form and room join flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:09:55 -08:00
Jeff Emmett 56901d8e45 feat: add space subdomain routing and ownership support
- Traefik wildcard HostRegexp for <space>.r*.online subdomains
- Middleware subdomain extraction and path rewriting
- Provision endpoint with owner_did acknowledgement
- Registry enforces space ownership via EncryptID JWT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:19:57 -08:00
Jeff Emmett fe9abcc197 Add internal provision endpoint for rSpace Registry
Simple acknowledge endpoint — room created on first user join.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:30:17 -08:00
Jeff Emmett 0801c8ed70 feat: add rData analytics and move Header to layout
Remove auto-redirect from landing page, move Header from page.tsx
to layout.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:04:38 -08:00
Jeff Emmett 108ac3e0a9 fix: landing page improvements and SpaceSwitcher domain support
- SpaceSwitcher auto-derives domain from window.location
- Fix landing page issues (redirect bug, duplicate footers,
  broken links, missing content)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:32:44 -08:00
Jeff Emmett 5018426380 feat: standardize header with AppSwitcher, SpaceSwitcher, and UserMenu
- Replace inline nav/Navbar with shared Header component
- Header pattern: AppSwitcher dropdown / SpaceSwitcher / actions / Sign In
- SpaceSwitcher and UserMenu work without SDK dependency
- Consistent across all r*Apps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:03:05 -08:00
Jeff Emmett dc83da4909 feat: standardize AppSwitcher and EcosystemFooter across all rApps
- Update AppSwitcher with all 26 r*Apps in 8 categories
- Add EcosystemFooter component with consistent ecosystem links
- Categories: Creating, Planning, Communicating, Deciding,
  Funding & Commerce, Social & Media, Work & Productivity,
  Identity & Infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:47:58 -08:00
Jeff Emmett 0de217d5f5 fix: dark background + emoji favicon for rStack design consistency
Standardize to dark background (#0f172a / slate-900) and add emoji
data URI favicon matching the rStack ecosystem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:19:05 -08:00
Jeff Emmett 05db0343af feat: add rStack AppSwitcher dropdown to header
Adds the unified rStack app switcher with pastel badges, emoji icons,
and categorized navigation across all 17 rStack apps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:15:52 -08:00
Jeff Emmett cdd04fe185 Fix EncryptID auth: add .well-known/webauthn + fix pingerName scope
1. WebAuthn Related Origins: rmaps.online was missing the
   .well-known/webauthn endpoint, so browsers couldn't use passkeys
   registered under RP ID "rspace.online" on rmaps.online. Added
   Next.js route handler returning { origins: ["https://rspace.online"] }.

2. Server: moved pingerName declaration before the WS message block
   (was inside the push block, causing ReferenceError on every ping).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:32:13 +00:00
Jeff Emmett f54f537483 Fix pingerName crash + auto-redirect returning users to last room
1. Server: pingerName was used before declaration in the WS message
   block (defined inside the push block). Moved declaration above both
   blocks. This caused all /push/request-location calls to crash with
   ReferenceError.

2. Landing page: always auto-redirect returning users (have saved user
   + last room) instead of only in standalone mode. Shows a loading
   spinner during redirect so the landing page doesn't flash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:44:19 +00:00
Jeff Emmett 53dd95fcac PWA auto-opens last room + visible ping notifications
1. Installed PWA (standalone mode) auto-redirects to last visited room
   on launch instead of showing the landing page. Uses localStorage
   rmaps_last_room + display-mode: standalone media query.

2. Manual pings now show visible feedback in three ways:
   - In-app toast: green banner "Alice pinged you for your location!"
   - Browser notification: fires Notification API when permission granted
   - Vibration: unchanged [200, 100, 200, 100, 400] pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:38:47 +00:00
Jeff Emmett a1132371f4 Thread caller name through ping notifications
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>
2026-02-19 00:35:54 +00:00
Jeff Emmett c3f884d2c4 Ensure offline users vibrate and auto-respond to manual pings
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>
2026-02-19 00:28:18 +00:00
Jeff Emmett 8fd4ed22f9 Add floating QR code button on map for easy room joining
Tap the QR icon (bottom-right on mobile, top-right on desktop) to show
an inline QR code overlay. Scan-to-join — tapping the QR dismisses it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:20:30 +00:00
Jeff Emmett a54ae04140 feat: manual ping vibrates device and force-shares GPS location
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>
2026-02-19 00:06:05 +00:00
Jeff Emmett 186aeb72f9 feat: standardize ecosystem footer with all 16 r-suite apps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 09:43:05 +00:00
Jeff Emmett 81fb2db865 chore: add rInbox to r* Ecosystem footer
Add rinbox.online link to the ecosystem footer navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:31:21 -07:00
Jeff Emmett 30f32e6da7 fix: deduplicate participants, visible callout push for offline users, fix notification timing
- 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>
2026-02-15 14:01:56 -07:00
Jeff Emmett 8e96d4eec0 feat: rewrite demo page with live rSpace data via useDemoSync
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>
2026-02-15 09:39:13 -07:00
Jeff Emmett 96e46af9dc feat: overhaul landing page and add demo with SVG map
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>
2026-02-15 08:58:54 -07:00
Jeff Emmett e7738b5f9f Add emoji favicon (🗺️) for browser tab
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 19:13:38 -07:00
Jeff Emmett f174709086 feat: add EncryptID auth to sync server and gate room creation
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>
2026-02-13 11:54:20 -07:00
Jeff Emmett 88aebcd997 feat: add optional EncryptID passkey authentication
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>
2026-02-13 07:35:08 -07:00
Jeff Emmett aacc6eb03f feat: Add floating "See Friends" button when list is closed
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>
2026-01-23 17:38:47 +01:00
Jeff Emmett 4302f2d4f8 feat: Add Google Maps import feature
- 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>
2026-01-23 16:33:53 +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 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 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 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 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 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 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 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