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.
This commit is contained in:
Linus Rath
2026-09-24 19:36:41 +02:00
parent 4e6426171a
commit af6290fd4c
3 changed files with 50 additions and 5 deletions
+9 -5
View File
@@ -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) {
+21
View File
@@ -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);
});
});
+20
View File
@@ -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);
}