From af6290fd4c800db0acf7b8552b217cbbaf8a3289 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 24 Sep 2026 19:33:24 +0200 Subject: [PATCH] fix: only show the unified mailbox when it can hold more than one account's mail #843 The drawer showed "All inboxes" and the Unified section as soon as a second account was signed in, but with cross-account off the unified views only cover the active account, so they repeated its own folders. They now follow the webmail's rule: shown with cross-account on and several accounts, or when group inboxes are merged in. --- src/components/SidebarDrawer.tsx | 14 +++++++++----- src/lib/__tests__/unified-section.test.ts | 21 +++++++++++++++++++++ src/lib/unified-section.ts | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/lib/__tests__/unified-section.test.ts create mode 100644 src/lib/unified-section.ts diff --git a/src/components/SidebarDrawer.tsx b/src/components/SidebarDrawer.tsx index e2d4e6ec..caeb679f 100644 --- a/src/components/SidebarDrawer.tsx +++ b/src/components/SidebarDrawer.tsx @@ -26,6 +26,7 @@ import { buildMailboxTree, flattenVisible, mailboxSubtreeIds, ownMailboxes, type MailboxNode, } from '../lib/mailbox-tree'; import { localizeMailboxName } from '../lib/mailbox-label'; +import { showUnifiedSection } from '../lib/unified-section'; import { generateAvatarColor, getAccountInitials } from '../lib/avatar-utils'; import { jmapClient } from '../api/jmap-client'; import { @@ -631,12 +632,15 @@ export default function SidebarDrawer({ visible, onClose }: SidebarDrawerProps) }; // ── Unified rows ────────────────────────────────────────────────────── - // Shown with one account as soon as it has group inboxes to merge, and - // always with several accounts. Counts are projected from the mailbox - // lists we hold: the active account's (own + shared) plus, cross-account, - // the tucked-away snapshots of the other accounts. + // Shown only when the views hold more than this account's own folders: + // cross-account with several accounts, or group inboxes to merge (#843). + // Counts are projected from the mailbox lists we hold: the active + // account's (own + shared) plus, cross-account, the tucked-away snapshots + // of the other accounts. const hasSharedInbox = mailboxes.some((m) => m.isShared && m.role === 'inbox'); - const showUnified = accounts.length > 1 || (includeGroupInUnified && hasSharedInbox); + const showUnified = showUnifiedSection({ + accountCount: accounts.length, unifiedCrossAccount, includeGroupInUnified, hasSharedInbox, + }); const unifiedCounts = React.useMemo(() => { const pools: Mailbox[][] = [mailboxes]; if (unifiedCrossAccount) { diff --git a/src/lib/__tests__/unified-section.test.ts b/src/lib/__tests__/unified-section.test.ts new file mode 100644 index 00000000..bba0006a --- /dev/null +++ b/src/lib/__tests__/unified-section.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest'; +import { showUnifiedSection } from '../unified-section'; + +const base = { accountCount: 1, unifiedCrossAccount: false, includeGroupInUnified: true, hasSharedInbox: false }; + +describe('showUnifiedSection (#843)', () => { + it('hides it for a second account while cross-account is off', () => { + expect(showUnifiedSection({ ...base, accountCount: 2 })).toBe(false); + }); + + it('shows it once cross-account is on with several accounts', () => { + expect(showUnifiedSection({ ...base, accountCount: 2, unifiedCrossAccount: true })).toBe(true); + // Cross-account with a single account has nothing to merge. + expect(showUnifiedSection({ ...base, unifiedCrossAccount: true })).toBe(false); + }); + + it('shows it for group inboxes only when they are merged in', () => { + expect(showUnifiedSection({ ...base, hasSharedInbox: true })).toBe(true); + expect(showUnifiedSection({ ...base, hasSharedInbox: true, includeGroupInUnified: false })).toBe(false); + }); +}); diff --git a/src/lib/unified-section.ts b/src/lib/unified-section.ts new file mode 100644 index 00000000..54d4c518 --- /dev/null +++ b/src/lib/unified-section.ts @@ -0,0 +1,20 @@ +/** + * Whether the drawer offers the unified mailbox (the "All inboxes" row and + * the Unified section), following the webmail's rule (#843): only when the + * unified views will hold more than the open account's own folders. + * + * - Cross-account on and a second account signed in: every account's mail. + * - Group inboxes merged in and the account has one: own plus group mail. + * + * A second account alone is not enough: with cross-account off the views + * cover only the active account, so "All inboxes" merely repeated Inbox. + */ +export function showUnifiedSection(opts: { + accountCount: number; + unifiedCrossAccount: boolean; + includeGroupInUnified: boolean; + hasSharedInbox: boolean; +}): boolean { + const crossAccountActive = opts.unifiedCrossAccount && opts.accountCount > 1; + return crossAccountActive || (opts.includeGroupInUnified && opts.hasSharedInbox); +}