Presence & live location¶
Presence is two separate user-visible things bundled together:
- Am I online? — an implicit indicator the app maintains automatically.
- Am I actively sharing my live location? — an explicit, time-boxed session the user starts and stops.
This page covers both.
Entry points¶
| From | Action |
|---|---|
| Discover map → dock | "Active Location" pill opens the session sheet. |
| Hub → Preferences | "Location sharing" master toggle (is_location_shared). |
| Hub → Preferences | "Show activity status" toggle (show_activity_status). |
| First-foreground after auth | Implicit — the app heartbeats presence automatically without user action. |
Primary flow — online presence (passive)¶
- Sign in. The app immediately starts heartbeating presence in the background — a small ping every few minutes that keeps a 3-minute TTL fresh server-side.
- Background the app. Heartbeats stop. After ~3 minutes the presence key expires server-side; friends now see the user as offline.
- Foreground. Heartbeat resumes; within seconds, friends see the user back online.
- Disable activity status. In Preferences, toggling "Show activity status" off makes the user appear offline to everyone — the heartbeat still runs, but consumers gate on the preference and hide the indicator.
There is no manual "go offline" button — going offline is implicit (close the app, lose connectivity, or disable activity status).
Primary flow — active location sharing¶
- Open the Active Location sheet. The map dock's "Active Location" pill opens a bottom sheet.
- Choose duration. Four time boxes: 30m, 1h, 6h, 12h. Tapping one starts the session immediately and the sheet shows a countdown to expiry.
- Confirm. The sheet now shows a "Sharing for N minutes" line, the expiry time, and a "Stop sharing" button. The user's own marker on the map starts pulsing.
- Friends see it. For the duration, friends see this user's marker with a "Sharing live" indicator; their detail card shows the remaining time.
- Stop. Either tap "Stop sharing", or let the session expire naturally. When expired, the marker goes static and the user reverts to standard (non-live) friend visibility.
Sub-flows¶
| Sub-flow | Behavior |
|---|---|
| Sharing master toggle off | If is_location_shared is off in Preferences, the Active Location pill is hidden / disabled. The master toggle is the privacy gate for the whole feature. |
| Restart while a session is active | Closing and reopening the app does not interrupt the session. The sheet, on next open, shows the existing session and its remaining time. |
| Switch from 30m to 6h mid-session | Tapping a different duration replaces the current session with a new one. There is no extend / append. |
| Geofence on map view | Friends with active location appear with their pulse only when within the map's viewport. Friends outside the viewport are still listed on the radar. |
| Friend without active sharing | Friends who have is_location_shared on but no active session appear as a static marker with their last-known location (24-hour TTL on the Redis-side store). |
| Stay-duration display | If a friend's last location was less than ~50m from a previous reading, the "arrived at" timestamp is preserved — the UI shows "been here for 14 minutes". This is automatic; nothing in the UI controls it. |
| Radar from active location | While the user is sharing, the "Radar" dock action surfaces a more proximate feed because the live location is feeding the proximity sort. |
States¶
| State | What the user sees |
|---|---|
| Sharing master off | Active Location pill is greyed out with a tooltip: "Enable location sharing in Settings to use this." |
| Master on, no session | Pill shows "Share live location" with no duration. |
| Session active | Pill turns green with "Sharing for N min" and a small countdown. The user's own map marker pulses. |
| Session expiring soon (<5min) | Pill shows the countdown emphasized. No automatic extension prompt. |
| Session ended | Pill collapses back to "Share live location". A brief toast: "Live sharing ended." |
| Activity status off | Friends see this user as offline regardless of heartbeat. The user themselves sees no UI change. |
| Backend / Redis cache cleared mid-session | The app rehydrates from the persistent session record on next status check. The user sees no interruption. |
Edge cases & gotchas¶
- Going offline is implicit, never manual. There is no "go offline" button. The user either closes the app, loses connectivity, or toggles "Show activity status" off.
- Activity status gates the indicator, not the data. With "Show activity status" off, the server still knows the user is online (presence heartbeat runs), but every consumer in the feed checks the preference and hides the indicator. Friends see them offline.
is_location_sharedis one-way. It controls whether others see this user's location. It does not hide the user's friends from them — the friend feed still shows visible friends regardless of the caller's own sharing toggle. This is intentional.- Active location intervals are strict. Only
30 / 60 / 360 / 720minutes are allowed. The UI exposes exactly those four options. - Sessions survive a redeploy. If the server's Redis is wiped, the active session is rehydrated from the persisted DB row — the user does not need to retap.
- Permission revoked mid-session. If the OS revokes location permission while a session is active, the session continues server-side but the marker stops moving (no fresh coords). The next foreground attempts to read location and surfaces the permission banner.
- App backgrounded for hours. Heartbeat stops; presence falls to offline within 3 minutes. The active-location session continues server-side until its expiry; friends still see the last-known marker but with no fresh updates.
- Friend with sharing off. Friends with
is_location_sharedoff are invisible on the friend feed entirely — they don't appear as a static marker, just nothing. - Stranger discovery (Near You). Strangers in the radar are also presence-driven. A "Near You" stranger with stale presence (>3 min) is filtered out.
- Backgrounded mid-stop. Tapping "Stop sharing" then immediately backgrounding the app: the stop request completes; on resume, the pill correctly shows "Share live location". The brief race is invisible to the user.
See also¶
product/bible/— narrative for live location (TBD).product/domains/— privacy rules, allowed intervals (TBD).- Map & radar — how the radar list builds on top of presence + active location.
- Friends — the "Online now" strip and friend-list integration.
- Profile & settings — preferences toggles location.
- Frontend → Routing —
/discoverhosts the dock and the sheet. - Backend → Presence service — heartbeat TTLs, allowed intervals, session restore semantics.
- Backend → Friends service — the multi-friend live-location feed.