Skip to content

Mobile Feed

Location: apps/mobile/src/app/(main)/feed/

The feed is the main discovery surface. It has 5 tabs and a keyword filter system. Feed state is persisted in MMKV so tabs retain their scroll position and last loaded content between sessions.


Files

FileDescription
index.tsxFeed root — tab bar + tab switcher
filter.tsxFilter presets modal (format, depth, interest)
keywords.tsxKeyword mute management UI

5 Feed Tabs

TabKeyAPI EndpointDescription
For YouforyouGET /posts/feedPersonalised ranked feed based on user interests
FollowingfollowingGET /posts/feed?following=truePosts from users you follow
TrendingtrendingGET /posts/trendingHigh-engagement posts in last 24h
CirclescirclesGET /posts/feed?visibility=circlesPosts visible to your circles
DiscoverdiscoverGET /discovery/candidates + GET /posts/feed?interest=...Discovery + interest-based posts

Feed Query Parameters

ParamTypeNotes
formatString?Filter by post format
depthInt?Filter by content depth 0..5
interestSlugString?Filter by primary interest
journalismBool?Show only journalism-tagged posts
followingBool?Restrict to followed users
cursorString?Pagination (postId cursor)
limitInt?Page size (default 20)

Filter Presets (filter.tsx)

A bottom sheet modal with:

  • Format chips: All, Note, Essay, Photo, Video, Quote, Thread
  • Depth slider: 0 (any) to 5 (thesis-level)
  • Interest picker: Select from user's followed interests
  • Journalism toggle: Show only isJournalism = true posts

Presets are persisted in MMKV under feed_filter_preset.


MMKV Persistence

MMKV KeyValueDescription
feed_active_tabStringLast active tab key
feed_filter_presetJSONSaved filter preset
feed_scroll_<tab>IntScroll position per tab

Unified Cards

Text posts render PostCard; video and audio items render MediaCard, which now shares PostCard's header (avatar · author · interest · time · reputation) and the same Stat footer bar (react / reply / repost / bookmark) — Stat is exported from post-card as the single source of truth. This makes media first-class siblings of text posts across every screen.

Each card shows:

  • Author avatar + name + persona indicator
  • Interest tag with accent color
  • Post title + excerpt (or media player for video/audio)
  • Format badge (Note, Essay, Photo, etc.)
  • Depth indicator (0..5 dots)
  • Reaction count + reply count + bookmark count
  • Author reputation in primary interest (level badge)
  • Boost indicator (⚡) if boostScore > 0
  • Journalism badge (📰) if isJournalism

Real video engagement. Video cards in the stream carry live react / comment / repost counts plus the viewer's reacted/reposted state from the discovery stream serializer, with optimistic toggles — not a bare caption.

Loading & Empty States

  • Skeletons render while a tab's first page loads (shimmer placeholders matching card layout).
  • A consistent EmptyState block (icon medallion + serif line + hint + CTA) replaces ad-hoc "No posts yet" snippets — shared from @regulus/ui.

Active-Signal Filters

When any filter (format / depth / interest / journalism) is applied, the feed surfaces an active-signal indicator on the filter control so a narrowed feed is never mistaken for an empty one. Tapping it reopens the filter sheet; clearing restores the full feed.


Realtime Updates

When Centrifugo is connected, a feed:public channel pushes new post IDs. The feed shows a "N new posts" pill at the top. Tapping it scrolls to top and loads the new batch.

Regulus — invite-only social-knowledge platform