Files
WintermuteandThomas Petersen d42a1fa95b feat(feed): cursor pagination for the inbox — scroll-end loads older conversations
PR #5834 windowed the mentions feed per conversation, which fixed
starvation but capped the inbox at the newest N conversations with no
way to reach older ones. This adds an inclusive `until` cursor across
the whole path so scroll-end loads the next page of older conversations.

Relay/DB:
- build_mentions_query takes `until` bounding conv_latest (the
  conversation's newest activity), NOT event time: pages are whole
  conversations, and no conversation whose latest activity falls
  between an event-time cursor and its conv_latest can be skipped.
  The candidate CTE stays unbounded by the cursor so page membership
  is stable.
- needs_action / activity queries bound event time directly (flat feeds).
- All Db wrappers and routed variants (replica/writer/fallback) thread
  `until`; the bridge feed path parses `filter.until` into all three.

Desktop:
- get_feed accepts `until`; e2e bridge mirrors the wire shape.
- getOldestConversationActivity derives the cursor as min(conv_latest)
  across conversations in hand, mirroring the relay's conversation key
  (dm:<channel> / NIP-10 thread root) — pagination is gated on the
  channel list so DM keys resolve.
- useHomeFeedPagination layers fetched-once older pages under the live
  30s-polled first page; merge dedupes the inclusive boundary overlap
  by event id; `exhausted` stops fetching when a page adds nothing.
- InboxListPane triggers fetchOlder within one viewport of scroll-end,
  re-checked on items growth so short pages chain; tail spinner
  (testid home-inbox-loading-older).

Verification:
- buzz-db feed suite 31/31 (incl. new Postgres paging test: 9
  conversations, limit 3, cursor walks pages with inclusive boundary);
  SQL-shape test asserts the cursor does not leak into the candidate scan.
- buzz-relay lib suite: 870 passed, 9 failures pre-existing on the base
  commit (api::media/admin/telemetry, verified via stash).
- desktop: check/typecheck/test 4778 green; tauri tests 2415 green.
- New Playwright spec inbox-pagination-screenshots.spec.ts proves
  scroll-end pages older conversations in against a live isolated
  relay (before/after screenshots); the windowing spec's "after" test
  now step-scrolls the virtualized list and tolerates sibling-spec
  conversations on a shared relay.

Depth is bounded by FEED_WINDOW_SCAN_CAP (2000 events) — acceptable:
the cursor reaches conversations far beyond the first window, and the
cap keeps the scan predictable.

Co-authored-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
2026-08-14 09:18:25 -04:00
..
2026-08-03 21:51:17 -04:00
2026-06-11 15:06:24 +00:00

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition