Commit Graph

96 Commits

Author SHA1 Message Date
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 9a815db28e Standardize emojis across header, favicons, and ecosystem links
Canonical emoji set for consistency:
- 🕸️ rNetwork (was 🌐), ⚖️ rChoices (was 🔀), 📋 rWork (was 💼)
- 🔐 rIdentity (was 🔑), 📖 rPubs (was 📰), 💸 rFunds (was 💰)
- 💰 rWallet (was 💼 in footer), 📬 rInbox (was ✉️)
- 💭 rForum (was 💬, differentiates from rChats)
- 📢 rSocials (was 📱), 🔨 rAuctions (was 🏛️ in footer)
- 🎬 rTube (was 📹 in footer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:57:11 -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 16edbdf544 fix: space links use subdomain URLs instead of rspace.online path
Space links now go to <space>.<app-domain> (e.g., myspace.rfunds.online)
instead of rspace.online/<space>. Domain derived from window.location
when not explicitly provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:18:17 -08:00
Jeff Emmett be8c7395de fix: nest Sign Out under username dropdown in UserMenu
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:09:13 -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 8af286e992 refactor: migrate EncryptID URLs from encryptid.jeffemmett.com to auth.ridentity.online
Part of the ridentity.online branding migration. The EncryptID auth
server is now accessible at auth.ridentity.online (with the legacy
encryptid.jeffemmett.com kept as a backward-compatible alias).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:20:08 -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 d6ac72e6cf feat: wire rmaps sync server to pull secrets from Infisical at startup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:06:42 -08:00
Jeff Emmett ee692ae2dc Add .dockerignore for optimized Docker builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:59:38 -07:00
Jeff Emmett c0ef77b6b8 Broaden WebAuthn error handling to show register form
Catch SecurityError and AbortError in addition to NotAllowedError
when login fails — all indicate the user needs to register rather
than showing a cryptic error message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:46:26 +00: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 0bea3ba73b feat: persist offline users and push subscriptions to disk
Rooms and push subscriptions now survive server restarts via JSON files
on a Docker volume. Stale participant cleanup skips users who have
active push subscriptions — they remain in the room and can still be
pinged for location and notifications when offline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:10:53 +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 f9faea1851 fix: connect frontend to sync server for multiplayer
NEXT_PUBLIC_SYNC_URL was never set, so useRoom always fell into
local-only mode — users couldn't see other joiners. Added build arg
to bake wss://sync.rmaps.online into the client bundle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:34:04 +00:00
Jeff Emmett 7aca62e9fa feat: add QR code to share modal for easy room sharing
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>
2026-02-18 09:56:47 +00:00
Jeff Emmett 4faab77278 fix: auto-center map on user's location instead of Hamburg
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>
2026-02-18 09:47:13 +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 0f2bee21a9 fix: use parent context in Docker build for encryptid-sdk dependency
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>
2026-02-17 16:08:48 -07:00
Jeff Emmett c8aab758eb chore: backlog TASK-14 SpaceRole bridge (Done)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:35:15 -07:00
Jeff Emmett 4b2e345652 chore: update lockfile after encryptid-sdk install
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:33:49 -07:00
Jeff Emmett 97e9922da2 feat: add SpaceRole bridge for cross-module membership sync
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>
2026-02-17 14:32:26 -07:00
Jeff Emmett b26547bd83 docs: add MODULE_SPEC.md with permission model and capabilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:30:14 -07: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 a4caa71621 feat: migrate auth to EncryptID SDK client
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>
2026-02-15 09:35:58 -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 9a8ea19f89 Mark PWA offline support task as done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:40:47 -07:00
Jeff Emmett 6814f156a0 Fix TypeScript build: enable downlevelIteration for Uint8Array spread
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 19:27:39 -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 d7fc2cc8db fix: ArrayBuffer type casts for WebAuthn in TS 5.x strict mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 07:43:06 -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 3f37d92aa0 feat: Simplify Google Maps import - accept ZIP files directly
- 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>
2026-01-23 17:57:52 +01:00
Jeff Emmett fb38a07e37 fix: Ensure header displays on mobile
- 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>
2026-01-23 17:49:57 +01: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 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