diff --git a/locales/rn/en.json b/locales/rn/en.json index 1338e78e..f3cfb40b 100644 --- a/locales/rn/en.json +++ b/locales/rn/en.json @@ -640,6 +640,13 @@ "experimental": { "title": "Experimental Feature" }, + "filters": { + "remove_action": "Remove action", + "remove_condition": "Remove condition", + "sieve_editor": { + "line_count": "{count, plural, one {# line} other {# lines}}" + } + }, "folders": { "account": "Account", "cannot_delete": "Cannot delete", diff --git a/src/components/__tests__/settings-i18n.test.ts b/src/components/__tests__/settings-i18n.test.ts index 86208132..5e1fadb3 100644 --- a/src/components/__tests__/settings-i18n.test.ts +++ b/src/components/__tests__/settings-i18n.test.ts @@ -5,27 +5,49 @@ import { describe, it, expect } from 'vitest'; import { join } from 'node:path'; import { findUntranslatedLiterals } from './untranslated-literals'; -// Pane file → texts that stay as they are on purpose. +// Pane file (relative to src/components/) → texts that stay as they are on +// purpose: product names, units, format patterns and sample data. const TRANSLATED_PANES: Record = { - 'ReadingSettings.tsx': [], - 'ContactsSettings.tsx': [], - 'ContentSendersSettings.tsx': [], - 'LayoutSettings.tsx': [], - 'CalendarSettings.tsx': [], - 'IdentitySettings.tsx': [ - // Example signatures in the placeholders: sample data, not UI text. + 'settings/AboutDataSettings.tsx': ['MB', 'GitHub'], + 'settings/AccountSecuritySettings.tsx': ['AES-128', 'AES-256'], + 'settings/AccountSettings.tsx': [], + 'settings/AppearanceSettings.tsx': [], + 'settings/CalendarSettings.tsx': [], + // Sub-address delimiter samples ("user+tag"). + 'settings/ComposingSettings.tsx': ['user tag'], + 'settings/ContactsSettings.tsx': [], + 'settings/ContentSendersSettings.tsx': [], + 'settings/DownloadsSettings.tsx': [], + 'settings/FilesSettings.tsx': [], + 'settings/FilterSettings.tsx': [], + 'settings/FolderSettings.tsx': [], + 'settings/IdentitySettings.tsx': [ + // Example signatures in the placeholders. '-- Jane Doe Bulwark Mail', '

Jane Doe
Bulwark Mail

', ], - 'FilterSettings.tsx': [], - 'SidebarAppsSettings.tsx': ['https://example.com'], - 'TemplateSettings.tsx': ['JSON', '{"templates": [...]}'], + // The raw keyword prefix shown next to a tag id. + 'settings/KeywordSettings.tsx': ['$label:'], + 'settings/LanguageSettings.tsx': [], + 'settings/LayoutSettings.tsx': [], + 'settings/NotificationSettings.tsx': [], + 'settings/PluginsSettings.tsx': [], + 'settings/ReadingSettings.tsx': [], + 'settings/SidebarAppsSettings.tsx': ['https://example.com'], + 'settings/SmimeSettings.tsx': [], + 'settings/TemplateSettings.tsx': ['JSON', '{"templates": [...]}'], + 'settings/ThemesSettings.tsx': [], + 'settings/UpdatesSettings.tsx': [], + 'settings/VacationSettings.tsx': ['YYYY-MM-DD HH:MM'], + 'settings/settings-section.tsx': [], + 'filters/FilterRuleModal.tsx': [], + 'filters/SieveEditorSheet.tsx': [], }; describe('translated settings panes', () => { for (const [file, allow] of Object.entries(TRANSLATED_PANES)) { it(`${file} has no hard-coded English text`, () => { - const literals = findUntranslatedLiterals(join(__dirname, '..', 'settings', file), allow); + const literals = findUntranslatedLiterals(join(__dirname, '..', file), allow); expect(literals).toEqual([]); }); } diff --git a/src/components/filters/FilterRuleModal.tsx b/src/components/filters/FilterRuleModal.tsx index edcdaf9a..7128ac31 100644 --- a/src/components/filters/FilterRuleModal.tsx +++ b/src/components/filters/FilterRuleModal.tsx @@ -229,7 +229,13 @@ export function FilterRuleModal({ visible, rule, mailboxes, onSave, onClose }: F - + @@ -295,6 +301,8 @@ export function FilterRuleModal({ visible, rule, mailboxes, onSave, onClose }: F disabled={conditions.length <= 1} hitSlop={8} style={[styles.removeBtn, conditions.length <= 1 && styles.removeBtnDisabled]} + accessibilityRole="button" + accessibilityLabel={t('settings.filters.remove_condition', 'Remove condition')} > @@ -361,6 +369,8 @@ export function FilterRuleModal({ visible, rule, mailboxes, onSave, onClose }: F disabled={actions.length <= 1} hitSlop={8} style={[styles.removeBtn, actions.length <= 1 && styles.removeBtnDisabled]} + accessibilityRole="button" + accessibilityLabel={t('settings.filters.remove_action', 'Remove action')} > diff --git a/src/components/filters/SieveEditorSheet.tsx b/src/components/filters/SieveEditorSheet.tsx index b9252532..51a0ebd4 100644 --- a/src/components/filters/SieveEditorSheet.tsx +++ b/src/components/filters/SieveEditorSheet.tsx @@ -65,7 +65,13 @@ export function SieveEditorSheet({ visible, content, onSave, onClose, onValidate - + {t('settings.filters.sieve_editor.title', 'Sieve Script Editor')} @@ -104,7 +110,9 @@ export function SieveEditorSheet({ visible, content, onSave, onClose, onValidate /> - {lineCount} {lineCount === 1 ? 'line' : 'lines'} + + {t('settings.filters.sieve_editor.line_count', '{count, plural, one {# line} other {# lines}}', { count: lineCount })} + {validationResult && ( diff --git a/src/components/settings/AboutDataSettings.tsx b/src/components/settings/AboutDataSettings.tsx index 1bbd6a71..24f35691 100644 --- a/src/components/settings/AboutDataSettings.tsx +++ b/src/components/settings/AboutDataSettings.tsx @@ -268,7 +268,7 @@ export function AboutDataSettings() { : sync.phase === 'scanning' ? t('settings.offline.scanning', 'Scanning recent mail…') : sync.phase === 'error' - ? t('settings.offline.last_sync_failed', 'Last sync failed: {message}', { message: sync.message ?? 'unknown error' }) + ? t('settings.offline.last_sync_failed', 'Last sync failed: {message}', { message: sync.message ?? t('identities.validation_errors.unknown_error', 'Unknown error') }) : t('settings.offline.last_sync', 'Last sync {when}', { when: formatRelativeTime(sync.finishedAt) })} {queuedChanges > 0 && ( diff --git a/src/components/settings/ComposingSettings.tsx b/src/components/settings/ComposingSettings.tsx index 540ffd98..8407ae29 100644 --- a/src/components/settings/ComposingSettings.tsx +++ b/src/components/settings/ComposingSettings.tsx @@ -205,7 +205,12 @@ export function ComposingSettings() { {attachmentReminderKeywords.map((kw) => ( {kw} - removeKeyword(kw)} hitSlop={6}> + removeKeyword(kw)} + hitSlop={6} + accessibilityRole="button" + accessibilityLabel={t('settings.email_behavior.attachment_reminder.remove', 'Remove')} + > diff --git a/src/components/settings/FilterSettings.tsx b/src/components/settings/FilterSettings.tsx index 9f972b8b..9e1339c8 100644 --- a/src/components/settings/FilterSettings.tsx +++ b/src/components/settings/FilterSettings.tsx @@ -408,6 +408,8 @@ export function FilterSettings({ onOpenVacation }: FilterSettingsProps = {}) { disabled={editIdx <= 0} hitSlop={6} style={[styles.reorderBtn, editIdx <= 0 && styles.reorderBtnDisabled]} + accessibilityRole="button" + accessibilityLabel={t('settings.appearance.message_list_order.move_up', 'Move up')} > @@ -416,12 +418,20 @@ export function FilterSettings({ onOpenVacation }: FilterSettingsProps = {}) { disabled={editIdx === editableIds.length - 1} hitSlop={6} style={[styles.reorderBtn, editIdx === editableIds.length - 1 && styles.reorderBtnDisabled]} + accessibilityRole="button" + accessibilityLabel={t('settings.appearance.message_list_order.move_down', 'Move down')} > - handleDelete(rule)} hitSlop={6} style={styles.deleteBtn}> + handleDelete(rule)} + hitSlop={6} + style={styles.deleteBtn} + accessibilityRole="button" + accessibilityLabel={t('settings.filters.delete_rule', 'Delete Rule')} + > diff --git a/src/components/settings/FolderSettings.tsx b/src/components/settings/FolderSettings.tsx index 1679ffd4..5951cd22 100644 --- a/src/components/settings/FolderSettings.tsx +++ b/src/components/settings/FolderSettings.tsx @@ -306,7 +306,12 @@ export function FolderSettings() { ? t('settings.folders.edit_folder', `Edit "${editor.mailbox.name}"`, { name: editor.mailbox.name }) : t('settings.folders.new_folder', 'New folder')} - + diff --git a/src/components/settings/ReadingSettings.tsx b/src/components/settings/ReadingSettings.tsx index 0be8f6bc..ef39e666 100644 --- a/src/components/settings/ReadingSettings.tsx +++ b/src/components/settings/ReadingSettings.tsx @@ -232,6 +232,8 @@ export function ReadingSettings() { ) } hitSlop={6} + accessibilityRole="button" + accessibilityLabel={t('settings.email_behavior.attachment_reminder.remove', 'Remove')} >