From 484cac58b7fe930556b4a7dc115c92c6e832b8f5 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 29 Oct 2026 03:30:12 +0100 Subject: [PATCH] fix: search Sent, Archive and Drafts from the unified All mail view --- .../__tests__/unified-inbox-filter.test.ts | 25 +++++++++++++++++++ src/api/unified-inbox.ts | 11 ++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/api/__tests__/unified-inbox-filter.test.ts b/src/api/__tests__/unified-inbox-filter.test.ts index 44a9fb28..2ddede99 100644 --- a/src/api/__tests__/unified-inbox-filter.test.ts +++ b/src/api/__tests__/unified-inbox-filter.test.ts @@ -44,3 +44,28 @@ describe('buildFilter (aggregated views)', () => { }); }); }); + +describe('buildFilter: searching from All mail', () => { + const all = [...MAILBOXES, mailbox('arch', 'archive'), mailbox('drafts', 'drafts'), mailbox('spam', 'junk')]; + + it('searches Sent, Archive and Drafts too, and only leaves Trash and Junk out', () => { + expect(buildFilter(all, { view: 'all', query: 'budget' })).toEqual({ + operator: 'AND', + conditions: [{ inMailboxOtherThan: ['bin', 'spam'] }, { text: 'budget' }], + }); + }); + + it('keeps the All mail folders without a query, and Unread narrows to its list', () => { + expect(buildFilter(all, { view: 'all' })).toEqual({ + operator: 'OR', conditions: [{ inMailbox: 'in' }, { inMailbox: 'projects' }], + }); + expect(buildFilter(all, { view: 'unread', query: 'budget' })).toEqual({ + operator: 'AND', + conditions: [ + { operator: 'OR', conditions: [{ inMailbox: 'in' }, { inMailbox: 'projects' }] }, + { notKeyword: '$seen' }, + { text: 'budget' }, + ], + }); + }); +}); diff --git a/src/api/unified-inbox.ts b/src/api/unified-inbox.ts index b5e7deba..91354be4 100644 --- a/src/api/unified-inbox.ts +++ b/src/api/unified-inbox.ts @@ -350,7 +350,15 @@ export function buildFilter( opts: UnifiedFetchOptions, ): Record | null { const conditions: Record[] = []; - if (opts.view) { + const q = opts.query?.trim(); + if (opts.view === 'all' && q) { + // Searching from All mail searches every folder but Trash and Junk, the + // default search scope: the All mail list leaves Sent, Archive and + // Drafts out, and narrowing the search to it hid every sent reply + // (webmail lib/unified-mailbox.ts searchCrossViewEmails). + const skipped = mailboxes.filter((m) => m.role === 'trash' || m.role === 'junk' || m.role === 'spam'); + if (skipped.length > 0) conditions.push({ inMailboxOtherThan: skipped.map((m) => m.id) }); + } else if (opts.view) { const included = crossIncludedMailboxes(mailboxes); if (included.length === 0) return null; conditions.push( @@ -367,7 +375,6 @@ export function buildFilter( } // One condition per quoted phrase or `word*` (see splitSearchText), in the // same AND as the folder conditions. - const q = opts.query?.trim(); if (q) conditions.push(...textConditions(q)); return conditions.length === 1 ? conditions[0] : { operator: 'AND', conditions }; }