fix: page the viewer over the list a unified-inbox message was opened from

This commit is contained in:
Linus Rath
2026-08-29 18:01:53 +02:00
parent 9ae91a6ab6
commit c8be383c05
2 changed files with 23 additions and 2 deletions
+16 -1
View File
@@ -82,7 +82,22 @@ export default function EmailThreadScreen({ route, navigation }: Props) {
const archiveEmailAction = useEmailStore((s) => s.archiveEmail);
const mailboxes = useEmailStore((s) => s.mailboxes);
const currentMailboxId = useEmailStore((s) => s.currentMailboxId);
const emails = useEmailStore((s) => s.emails);
const storeEmails = useEmailStore((s) => s.emails);
// The list the pager pages over. A message opened from the active folder
// pages over that folder; one opened from another list (unified inbox,
// contact activity) pages over the ids that list handed us, and a message
// that is in neither (e.g. a group-inbox message not in the folder page)
// gets a one-element list — otherwise the pager would render `emails[0]`
// while the toolbar acted on the tapped message.
const emails = React.useMemo<Email[]>(() => {
const { emailIds, emailId, threadId } = route.params;
if (emailIds && emailIds.length > 0) {
const byId = jmapAccountId ? null : new Map(storeEmails.map((e) => [e.id, e]));
return emailIds.map((id) => byId?.get(id) ?? ({ id, threadId } as Email));
}
if (!jmapAccountId && storeEmails.some((e) => e.id === emailId)) return storeEmails;
return [{ id: emailId, threadId } as Email];
}, [storeEmails, route.params, jmapAccountId]);
// The JMAP account the open message belongs to: the route param when the
// unified inbox opened a group message, otherwise the account behind the
+7 -1
View File
@@ -69,6 +69,11 @@ export default function UnifiedInboxScreen({ navigation }: Props) {
await switchAccount(email.sourceAccountId);
if (useAuthStore.getState().activeAccountId !== email.sourceAccountId) return;
}
// Page over the rows of the same account the user is looking at
// (ids are only unique per JMAP account, so never mix accounts).
const emailIds = emails
.filter((e) => e.sourceAccountId === email.sourceAccountId && e.jmapAccountId === email.jmapAccountId)
.map((e) => e.id);
navigation.navigate('EmailThread', {
emailId: email.id,
threadId: email.threadId,
@@ -76,13 +81,14 @@ export default function UnifiedInboxScreen({ navigation }: Props) {
// Group/shared messages live under another JMAP account in the
// same session; pass it so the thread opens against the right one.
jmapAccountId: email.isShared ? email.jmapAccountId : undefined,
emailIds,
});
} finally {
setOpening(false);
}
})();
},
[opening, switchAccount, navigation],
[opening, switchAccount, navigation, emails],
);
const errorCount = Object.keys(errors).length;