Conversation
CandelR
added this pull request to stack #583
September 16, 2026 14:35
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Mailboxes only ever showed their first 50 threads and reloaded from scratch every time the user came back from an email. They now load older emails as the user scrolls, keep the pages already loaded and the scroll position when coming back, and reflect what was done in an email (read, unread, trash, spam) without reloading, while a page that fails no longer leaves the mailbox stuck or requested in a loop.
Summary
store/slices/mail/index.ts: the Mail slice. Emails are entities shared by id and each mailbox keeps which ids it shows and how far it has paged, so a change to one email reaches every mailbox that shows it. Loading from scratch replaces a mailbox, a further page is appended, refreshing merges the newest page over what is loaded,threadReadStateChangedandthreadMovedOutapply what was done in an email to every mailbox, andresetStateempties everything.store/slices/mail/thunks.ts: loads the first page, the next page and the newest emails of a mailbox, decrypting the previews of each page. The next page continues after the oldest email loaded instead of the anchor the server returned. A failed page is retried once from the email before; if that fails too, itsconditionstops further requests until the user retries, which avoids the loop the list footer used to trigger. Each mailbox remembers the request id of its last first page, and any page or refresh that started from an earlier one is dropped.store/slices/mail/pagination.ts: pure functions that order a mailbox, choose where the next page starts and merge the newest page. The merge drops emails that are gone from the newest page and the older row of a thread that got a reply, except in Drafts, where every draft is its own row.store/slices/mail/selectors.ts,store/slices/mail/types.tsandstore/slices/mail/initialState.ts: the selectors, the state types and the empty states, kept apart fromindex.tsto avoid a circular import between the slice and its thunks. The emails selector keeps returning the same array while a mailbox does not change, so reading an email in Inbox does not render Spam again.store/slices/mail/hooks/useMailboxEmails.ts: what the mailbox screen uses to read a mailbox and load, retry and refresh its pages.screens/mail/MailboxListScreen/groupEmailsByThread.ts: grouped the list by thread on the client. Removed because the server already collapses threads in every mailbox except Drafts, and in Drafts the grouping hid drafts that share a thread.screens/mail/MailboxListScreen/index.tsx: the mailbox list screen. It loaded the emails itself and reloaded them on every focus. Now the first focus loads from scratch, later focuses only refresh the newest emails, and pull-to-refresh loads from scratch again because it is the only way to pick up an email restored to an older date.screens/mail/EmailDetailScreen/index.tsx: the email detail. Once the server confirms marking an email as read or unread, or moving the thread to Trash or Spam, it dispatches the change so every mailbox updates without reloading.services/mail/mailbox.service.ts: now pages by anchor with a fixed page size of 25 and returns the whole response.store/index.tsandstore/slices/auth/index.ts: register the Mail reducer and reset it on sign out, so the next account never sees the emails of the previous one.