Skip to content

fix(email): keep the cached mail list as deep as the user scrolled it - #8244

Closed
synoet wants to merge 1 commit into
synoet/soup-keep-pages-on-refreshfrom
synoet/email-mail-list-depth
Closed

synoet wants to merge 1 commit into
synoet/soup-keep-pages-on-refreshfrom
synoet/email-mail-list-depth

Conversation

@synoet

@synoet synoet commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #8243 (email list stability).

Why

Every email tab shows the local cache's Mail page once the cache changes after the network page landed, and the mail backfill, thread loads and read marks change it every few seconds. Each change evaluated the page at its first 100 rows, so a list scrolled past them collapsed back. Loading more failed too: the backfill moved the page's cursor before the next page arrived, the page was dropped and re-evaluated at 100 rows, and Load More did nothing. No tab could show more than 100 threads while the cache was busy.

How it works

local Mail page depth = rows loaded through either source
cache write ─► evaluate at that depth (≤499 rows per request, following the index cursor)
Load More   ─► next page; if a write staled the cursor ─► raise the depth and evaluate again
            └► also fetch the next server page, so the network page is as deep when it is authoritative again

What

  • create-soup-live-query.ts: localMailDepth; stale-cursor and stale-revision paths deepen instead of dropping to the first page. graphql_cache.soup_local_evaluation records evaluation.depth and evaluation.depth_requests.
  • mail-depth.ts: readMailDepth, a bounded cursor walk that stops at a revision change, an empty page or a repeated cursor.
  • Tests: mail-depth.test.ts covers each stop condition and the per-request limit; items.test.ts checks a paged Mail list stays as deep across a cache write, and paging still works when a write stales the cursor, and a Load More reads only the page it asked for.
  • docs/local-predicate-pagination-plan.md describes the new revision behavior.

Verified on a seeded inbox: Signal and All page past 100 threads while the backfill runs, and marking a thread done 260 rows down removes one row without moving the viewport.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: macro-inc/macro/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bb1da4e3-9ffe-44fd-9435-84f3a89f561f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

@synoet
synoet force-pushed the synoet/soup-keep-pages-on-refresh branch from f509dfa to 77fd288 Compare October 17, 2026 12:43
@synoet
synoet force-pushed the synoet/email-mail-list-depth branch from 97e3a13 to 39d28eb Compare October 17, 2026 12:43
Why: every email tab shows the local cache's Mail page once the cache
changes after the network page landed, and the mail backfill, thread
loads and read marks change it every few seconds. Each change evaluated
the page at its first 100 rows, so a list scrolled past them collapsed
back. Loading more failed too: the backfill moved the page's cursor
before the next page arrived, the page was dropped, and Load More did
nothing, so no tab could show more than 100 threads.

What: the local Mail page remembers its depth, the rows loaded through
either source, and every evaluation reads that deep, following the
index's cursor in requests the cache accepts (fewer than 500 rows each).
A next page whose cursor went stale raises the depth and evaluates again
instead of dropping back to the first page. Loading more also advances
the server pages, so the list stays as deep when the network page is
authoritative again.
@synoet
synoet force-pushed the synoet/soup-keep-pages-on-refresh branch from 77fd288 to fc29458 Compare October 17, 2026 12:56
@synoet
synoet force-pushed the synoet/email-mail-list-depth branch from 39d28eb to 968e615 Compare October 17, 2026 12:56
@synoet

synoet commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Consolidated into #8247 with the other list stability fixes.

@synoet synoet closed this Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant