fix: show how many emails were moved instead of {count}

This commit is contained in:
Linus Rath
2026-10-31 14:18:40 +01:00
parent 350b0e8e74
commit 58c8054339
2 changed files with 51 additions and 2 deletions
@@ -0,0 +1,45 @@
// The toasts the email store raises fill every placeholder their catalog text
// has. Moving several emails to a folder without a name read
// "{count} emails moved": the call passed no count, and the catalog text
// (the webmail's notifications.emails_moved) wins over the fallback.
import { describe, expect, it, vi } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
vi.mock('expo-localization', () => ({ getLocales: () => [] }));
import { getDictionary, translate } from '../../i18n';
const SOURCE = path.resolve(__dirname, '../email-store.ts');
function flatten(obj: Record<string, unknown>, prefix = '', out = new Map<string, string>()): Map<string, string> {
for (const [k, v] of Object.entries(obj)) {
const key = prefix ? `${prefix}.${k}` : k;
if (v && typeof v === 'object') flatten(v as Record<string, unknown>, key, out);
else if (typeof v === 'string') out.set(key, v);
}
return out;
}
// t('key', 'fallback') closed right after the fallback: no values passed.
const CALL_WITHOUT_VALUES = /\bt\(\s*'([^']+)'\s*,\s*('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`[^`]*`)\s*,?\s*\)/g;
const PLACEHOLDER = /(?<!\{)\{\s*\w+\s*[,}]/;
describe('email store toasts', () => {
it('pass values for every catalog text with a placeholder', () => {
const en = flatten(getDictionary('en') as Record<string, unknown>);
const source = fs.readFileSync(SOURCE, 'utf8');
const offenders = [...source.matchAll(CALL_WITHOUT_VALUES)]
.map((m) => ({ key: m[1], text: en.get(m[1]) }))
.filter(({ text }) => !!text && PLACEHOLDER.test(text))
.map(({ key, text }) => `${key} = ${text}`);
expect(offenders).toEqual([]);
});
it('reads the moved count in the catalog text', () => {
expect(translate('en', 'notifications.emails_moved', 'Emails moved', { count: 3 })).toBe('3 emails moved');
expect(PLACEHOLDER.test('{count} emails moved')).toBe(true);
expect([..."t('notifications.emails_moved', 'Emails moved')".matchAll(CALL_WITHOUT_VALUES)]).toHaveLength(1);
expect([..."t('notifications.emails_moved', `${count} emails moved`, { count })".matchAll(CALL_WITHOUT_VALUES)]).toHaveLength(0);
});
});
+6 -2
View File
@@ -2072,7 +2072,9 @@ export const useEmailStore = create<EmailState>()(
? (targets.length === 1
? t('notifications.moved_to_mailbox', `Email moved to ${targetName}`, { mailbox: targetName })
: t('email_list.emails_moved_to', `${targets.length} emails moved to ${targetName}`, { count: targets.length, mailbox: targetName }))
: t('notifications.emails_moved', 'Emails moved'),
: (targets.length === 1
? t('notifications.email_moved', 'Email moved')
: t('notifications.emails_moved', `${targets.length} emails moved`, { count: targets.length })),
createdAt: Date.now(),
accountId: source.accountId,
items,
@@ -2838,7 +2840,9 @@ async function fileAcrossAccounts(action: SpanningAction, targets: Email[], toMa
? (count === 1
? t('notifications.moved_to_mailbox', `Email moved to ${targetName}`, { mailbox: targetName })
: t('email_list.emails_moved_to', `${count} emails moved to ${targetName}`, { count, mailbox: targetName }))
: t('notifications.emails_moved', 'Emails moved');
: (count === 1
? t('notifications.email_moved', 'Email moved')
: t('notifications.emails_moved', `${count} emails moved`, { count }));
set({
emails: get().emails.filter((e) => !goneKeys.has(rowKeyOf(e))),
...(count > 0