- 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>
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>
- 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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>