Discovery feed
The discover view is the user's signed-in landing surface. /discover shows the home view: a greeting, the user's city and the date, and a feed of moments from friends and the community. From there the user can step into the map view at /discover/map to see what's happening nearby on a live map. It is the answer to "where am I, who's around, and what is there to do?"
Entry points
| From |
Action |
| Sign-in |
Default redirect after login lands on /discover (home view). |
| Nav dock |
The center Discover button on the mobile bottom dock; Discover at the top of the web sidebar. |
| Logo / brand tap |
Returns to /discover from anywhere in the app. |
| Deep link |
tomoda://discover and https://tomoda.life/discover. /discover/map is also deep-linkable. |
| Capture flow exit |
After cancelling event creation or finishing capture, the user returns to the previous view (home or map). |
Primary flow, home view (/discover)
- Landing. A magazine-style cover shows the time-of-day greeting, the user's first name, the current city, and the date. Beneath it sits the feed surface.
- Open map. A pill-shaped affordance directly under the cover opens
/discover/map. The mobile bottom nav's center Discover button morphs into the capture shutter on this route (see Capture below).
- Feed. The body shows moments from friends and the community. (v1 ships an empty-state placeholder; the feed surface lands with the moments-feed PRs.)
Capture from Discover
The mobile bottom dock's center Discover button morphs into the gold-edged capture shutter while the user is on /discover or /discover/map. Tapping it opens /(capture) (native-only). When the proximity poll finds an in-progress RSVPed event nearby, the shutter glows gold and tapping it opens the event check-in sheet instead. The capture flow is removed from the web bundle: the route group redirects to /discover and the MapDock web control omits the shutter.
Map view (/discover/map)
- Landing. The map opens at the user's current region (or a default San Francisco region if location permission isn't granted yet). A faint progress indicator runs at the top while the first tile of markers loads.
- First fetch. The viewport's bounding box and zoom level are sent to the backend; the response paints three marker categories: events, locations, and standalone moments, plus friend markers overlaid on top.
- Pan / zoom. As the user drags or pinch-zooms, the viewport refetches in the background. At low zoom, individual markers collapse into geo-cluster badges showing aggregate counts ("23 events, 7 places"). At high zoom, individual markers appear.
- Tap a marker. A bottom sheet slides up with a detail card: event title, host, capacity, time, or location name, category, photo strip, top moments. Friend markers open a profile-mini card with their last-seen and an "Open profile" affordance.
- Tap a cluster. First tap centers the map on the cluster and pops a small carousel preview of its top items. Second tap (or tapping the carousel) zooms in one tier.
- Open a dock action. The dock above the bottom nav offers Radar, Active Location, and Map Legend. Each opens its own sheet without leaving the map.
Sub-flows
| Sub-flow |
Behavior |
| Filter by category |
A horizontal chip row at the top filters event categories (sports, food, music...). Filters apply to both Map and List. |
| Radar |
Dock action — opens the radar list of friends + Near-You strangers, sorted by distance, independent of the current viewport. |
| Active location on |
When the user has live location sharing on, their own marker pulses; the dock shows a green "Sharing" pill. |
| Friend marker tap |
Profile-mini sheet: avatar, name, last-active, "Open profile", "Message". |
| Create event from map |
A floating action button on the map opens the event-create modal, prefilled with the tap-and-hold coordinates as the location. |
| Share a discovered place |
The detail sheet's overflow menu has "Share" → opens the OS share sheet with a tomoda.life/places/... link. |
States
| State |
What the user sees |
| Loading |
Skeleton markers fade in; the top progress bar runs. Cards in the list show shimmer placeholders. |
| Empty viewport |
Map renders with no markers. A muted toast appears: "Nothing happening here yet — try panning out." |
| Location permission denied |
The map opens at the default region (San Francisco). A persistent banner at the top offers "Enable location" → opens system settings. |
| Offline |
Last-cached markers stay on screen, dimmed. A red toast: "You're offline." Pull-to-refresh retries. |
| Backend error |
A toast appears with the error; the previous markers stay. |
| Successful refresh |
New markers fade in over old ones. No spinner if the data changed by less than ~20%. |
Edge cases & gotchas
- Geo-cluster tap is two-stage. The first tap centers and previews the cluster; only the second tap (or carousel tap) zooms. This is deliberate to let the user inspect the carousel without losing the cluster on a single tap.
- Sponsored events stay visible at low zoom. Global-tier sponsored events are flagged as priority markers — they bypass clustering. The user may see two markers near each other when one is sponsored and the other is not.
- Friend markers always show through. Even at continent-zoom, the user sees friend markers as individual pins (capped at the friend list size). They never roll into a cluster.
- The user's own hosted events are priority. They render as priority markers regardless of sponsorship, so the user can always find their own event on the map.
- App backgrounded mid-pan. When the user backgrounds the app and returns, the viewport refetches once. If the user moved physically, the location pulse updates to the new position; nothing else jumps.
- Permission revoked at the OS level. If location permission is revoked from system settings while the app is in the background, the next focus shows the "Enable location" banner without an error toast — the app does not assume the user explicitly denied.
- Profile incomplete. If username or date of birth is missing, the user is redirected to
/auth/complete-profile before the discover screen renders.
See also