feat: per-account All Mail folder selection
Replaces the global allMailFolderIds (string[] | null) with a per-account
Record<accountId, string[]>, so each account chooses which of its own folders
the "All Mail" view merges. A missing entry = "not configured" (defaults to
every no-role folder); an explicit [] = "no folders".
- settings-store: type/default -> Record (default {}); persist version 4 -> 5,
migration drops the legacy global list (the active account isn't known at
migrate time); onRehydrate + importSettings coerce/ignore any non-record
(legacy global string[] | null) shape. isPlainRecord() guard.
- email-store.resolveAllMailJmapIds: reads the entry for the account the view is
scoped to (viewingAccountId ?? activeAccountId); undefined -> all no-role,
[] -> none.
- layout-settings: read/write the active account's entry; when more than one
account is logged in, an italic hint names the account the selection applies
to (settings.appearance.all_mail.account_hint, 19 locales; de/ro translated).
- Test: stores/__tests__/settings-store-all-mail.test.ts (per-account
independence, explicit-empty vs not-configured, importSettings legacy guard).
This commit is contained in:
committed by
Linus Rath
parent
5c2f206c74
commit
751f3c1685
@@ -121,24 +121,37 @@ export function LayoutSettings() {
|
||||
const { toolbarPosition, showToolbarLabels, hideAccountSwitcher, showRailAccountList, enableUnifiedMailbox, includeGroupInUnified, enableAllMailView, allMailFolderIds, colorfulSidebarIcons, mailLayout, proInterface, updateSetting } = useSettingsStore();
|
||||
const { isSettingLocked, isSettingHidden, isFeatureEnabled } = usePolicyStore();
|
||||
const accounts = useAccountStore(s => s.accounts);
|
||||
const activeAccountId = useAccountStore(s => s.activeAccountId);
|
||||
const mailboxes = useEmailStore(s => s.mailboxes);
|
||||
const hasGroupInboxes = useMemo(() => mailboxes.some(m => m.isShared), [mailboxes]);
|
||||
const allMailViewAllowed = isFeatureEnabled('allMailViewEnabled');
|
||||
|
||||
// Own (non-shared) folders and the current All Mail selection. `null` =
|
||||
// never configured, which defaults to all non-special (no-role) folders.
|
||||
// Own (non-shared) folders and the active account's All Mail selection. The
|
||||
// selection is per account: a missing entry = never configured, which
|
||||
// defaults to all no-role folders; an explicit [] = no folders.
|
||||
const ownMailboxes = useMemo(() => mailboxes.filter(m => !m.isShared), [mailboxes]);
|
||||
const currentAllMailEntry = activeAccountId ? allMailFolderIds[activeAccountId] : undefined;
|
||||
const allMailSelected = new Set(
|
||||
allMailFolderIds === null
|
||||
currentAllMailEntry === undefined
|
||||
? ownMailboxes.filter(m => !m.role).map(m => m.id)
|
||||
: allMailFolderIds
|
||||
: currentAllMailEntry
|
||||
);
|
||||
const toggleAllMailFolder = (id: string) => {
|
||||
if (!activeAccountId) return;
|
||||
const next = new Set(allMailSelected);
|
||||
if (next.has(id)) next.delete(id);
|
||||
else next.add(id);
|
||||
updateSetting('allMailFolderIds', ownMailboxes.filter(m => next.has(m.id)).map(m => m.id));
|
||||
updateSetting('allMailFolderIds', {
|
||||
...allMailFolderIds,
|
||||
[activeAccountId]: ownMailboxes.filter(m => next.has(m.id)).map(m => m.id),
|
||||
});
|
||||
};
|
||||
// Name the account the selection applies to, but only when more than one is
|
||||
// logged in (otherwise it's unambiguous).
|
||||
const activeAccount = accounts.find(a => a.id === activeAccountId);
|
||||
const allMailAccountHint = accounts.length > 1 && activeAccount
|
||||
? t('all_mail.account_hint', { account: activeAccount.displayName || activeAccount.email })
|
||||
: null;
|
||||
|
||||
return (
|
||||
<SettingsSection title={t('title')} description={t('description')}>
|
||||
@@ -244,6 +257,9 @@ export function LayoutSettings() {
|
||||
<div>
|
||||
<div className="text-sm font-medium text-foreground">{t('all_mail.folders_label')}</div>
|
||||
<div className="text-xs text-muted-foreground">{t('all_mail.folders_description')}</div>
|
||||
{allMailAccountHint && (
|
||||
<div className="text-xs italic text-muted-foreground mt-0.5">{allMailAccountHint}</div>
|
||||
)}
|
||||
</div>
|
||||
{ownMailboxes.length === 0 ? (
|
||||
<p className="text-xs text-muted-foreground">{t('all_mail.no_folders')}</p>
|
||||
|
||||
Reference in New Issue
Block a user