From 4eb820ce4ea87913364bca38da567e30826d030b Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:09:15 +0100 Subject: [PATCH] fix: drop ticked messages when a category tab or filter chip changes the list --- .../email/__tests__/email-list-plugin-filters.test.tsx | 9 +++++++++ components/email/__tests__/message-list-tabs.test.tsx | 9 +++++++++ components/email/email-list.tsx | 2 +- components/email/message-list-tabs.tsx | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/components/email/__tests__/email-list-plugin-filters.test.tsx b/components/email/__tests__/email-list-plugin-filters.test.tsx index 2a836e864..a452749a6 100644 --- a/components/email/__tests__/email-list-plugin-filters.test.tsx +++ b/components/email/__tests__/email-list-plugin-filters.test.tsx @@ -71,6 +71,15 @@ describe('plugin list filters in the message list', () => { expect(fetchEmails).toHaveBeenCalledTimes(2); }); + it('drops ticked messages when a chip narrows the list', async () => { + useEmailStore.setState({ selectedEmailKeys: new Set(['a', 'b']) }); + render(); + const chip = await screen.findByRole('button', { name: 'Open' }); + expect(useEmailStore.getState().selectedEmailKeys.size).toBe(2); + act(() => { fireEvent.click(chip); }); + expect(useEmailStore.getState().selectedEmailKeys.size).toBe(0); + }); + it('does not call the folder empty while a filter hides its mail', async () => { render(); expect(await screen.findByText('no_emails_description')).toBeInTheDocument(); diff --git a/components/email/__tests__/message-list-tabs.test.tsx b/components/email/__tests__/message-list-tabs.test.tsx index e9001bb04..6c4ae13e9 100644 --- a/components/email/__tests__/message-list-tabs.test.tsx +++ b/components/email/__tests__/message-list-tabs.test.tsx @@ -51,6 +51,15 @@ describe('MessageListTabs', () => { expect(screen.getByRole('tabpanel', { name: 'Primary' })).toHaveTextContent('list'); }); + it('drops ticked messages on a switch of tab, which lists other mail', () => { + useEmailStore.setState({ selectedEmailKeys: new Set(['a', 'b']) } as never); + render(); + fireEvent.click(screen.getByRole('tab', { name: 'Primary' })); + expect(useEmailStore.getState().selectedEmailKeys.size).toBe(2); + fireEvent.click(screen.getByRole('tab', { name: 'Social' })); + expect(useEmailStore.getState().selectedEmailKeys.size).toBe(0); + }); + it('keeps one tab stop and moves with the arrow keys', () => { render(); const [primary, promotions, social] = screen.getAllByRole('tab'); diff --git a/components/email/email-list.tsx b/components/email/email-list.tsx index 15e2f7673..b0f15d687 100644 --- a/components/email/email-list.tsx +++ b/components/email/email-list.tsx @@ -1177,7 +1177,7 @@ export function EmailList({ { if (client) void useEmailStore.getState().fetchEmails(client); }} + onChange={() => { clearSelection(); if (client) void useEmailStore.getState().fetchEmails(client); }} /> )} diff --git a/components/email/message-list-tabs.tsx b/components/email/message-list-tabs.tsx index b4f720286..631cb4416 100644 --- a/components/email/message-list-tabs.tsx +++ b/components/email/message-list-tabs.tsx @@ -99,6 +99,8 @@ export function MessageListTabs({ panelId }: { panelId: string }) { const handleSelect = (tabId: string) => { if (tabId === activeTabId) return; useMessageListTabsStore.getState().setActiveTab(tabId, selectedMailbox); + // The other tab lists other mail; ticks here would act on rows out of sight. + useEmailStore.getState().clearSelection(); if (client) void useEmailStore.getState().fetchEmails(client); };