i18n: extract the strings left behind in already-localized screens

Part of #145.

Two files you localized yourself, each with a handful of strings that the
pass didn't reach:

- `ChoreView` — the offline-sync notices ("You're offline — completion
  will sync when back online" and its skip/start/pause/restore siblings)
  and the error toasts they fall back to. 12 keys added to `en/chores.json`.
- `MFASettings` — the "Generate New Codes" button. 1 key added to
  `en/settings.json`.

Both extend namespaces that already exist, so `src/i18n/config.js` is
untouched and this cannot conflict with my other open PRs.

English only — no translations, no behaviour change. Every t() value is
checked to appear character-for-character in the code it replaces, or to
match the value already in your dictionary for the same key (126 call
sites total across both files).
This commit is contained in:
everysingletear
2026-08-14 11:10:35 +08:00
parent 677376983b
commit 6e97c70570
4 changed files with 29 additions and 16 deletions

View File

@@ -70,7 +70,19 @@
"paused": "Timer Paused", "paused": "Timer Paused",
"reset": "Reset Timer", "reset": "Reset Timer",
"delete": "Delete Session" "delete": "Delete Session"
} },
"unableUndo": "Failed to undo",
"offlineComplete": "You're offline — completion will sync when back online",
"unableComplete": "Unable to complete task",
"offlineSkip": "You're offline — skip will sync when back online",
"unableSkip": "Unable to skip task",
"offlineStart": "You're offline — start will sync when back online",
"unableStart": "Unable to start task",
"offlinePause": "You're offline — pause will sync when back online",
"unablePause": "Unable to pause task",
"offlineRestore": "You're offline — restore will sync when back online",
"restoreFailed": "Failed to restore",
"unableRestore": "Unable to restore task"
}, },
"toolbar": { "toolbar": {
"defaultProject": "Default Project" "defaultProject": "Default Project"

View File

@@ -348,7 +348,8 @@
"backupCodesModal": { "backupCodesModal": {
"title": "New Backup Codes", "title": "New Backup Codes",
"warning": "Your previous backup codes are now invalid. Save these new codes in a safe place. Each code can only be used once." "warning": "Your previous backup codes are now invalid. Save these new codes in a safe place. Each code can only be used once."
} },
"generateCodes": "Generate New Codes"
}, },
"apiTokens": { "apiTokens": {
"title": "API Tokens", "title": "API Tokens",

View File

@@ -280,7 +280,7 @@ const ChoreView = () => {
message: t('choreView.taskCompletionUndone'), message: t('choreView.taskCompletionUndone'),
}) })
} else { } else {
throw new Error('Failed to undo') throw new Error(t('choreView.unableUndo'))
} }
} catch (error) { } catch (error) {
showError({ showError({
@@ -318,7 +318,7 @@ const ChoreView = () => {
}) })
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
showSuccess({ showSuccess({
message: "You're offline — completion will sync when back online", message: t('choreView.offlineComplete'),
undoAction: async () => { undoAction: async () => {
await commandQueue.cancel(cmdId) await commandQueue.cancel(cmdId)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
@@ -327,7 +327,7 @@ const ChoreView = () => {
} else { } else {
showError({ showError({
title: t('choreView.undoFailed'), title: t('choreView.undoFailed'),
message: error?.message || 'Unable to complete task', message: error?.message || t('choreView.unableComplete'),
}) })
} }
} }
@@ -356,7 +356,7 @@ const ChoreView = () => {
message: t('choreView.taskSkipUndone'), message: t('choreView.taskSkipUndone'),
}) })
} else { } else {
throw new Error('Failed to undo') throw new Error(t('choreView.unableUndo'))
} }
} catch (error) { } catch (error) {
showError({ showError({
@@ -376,7 +376,7 @@ const ChoreView = () => {
) )
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
showSuccess({ showSuccess({
message: "You're offline — skip will sync when back online", message: t('choreView.offlineSkip'),
undoAction: async () => { undoAction: async () => {
await commandQueue.cancel(cmdId) await commandQueue.cancel(cmdId)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
@@ -385,7 +385,7 @@ const ChoreView = () => {
} else { } else {
showError({ showError({
title: t('choreView.undoFailed'), title: t('choreView.undoFailed'),
message: error?.message || 'Unable to skip task', message: error?.message || t('choreView.unableSkip'),
}) })
} }
} }
@@ -411,7 +411,7 @@ const ChoreView = () => {
setChore(startedChore) setChore(startedChore)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
showSuccess({ showSuccess({
message: "You're offline — start will sync when back online", message: t('choreView.offlineStart'),
undoAction: async () => { undoAction: async () => {
await commandQueue.cancel(cmdId) await commandQueue.cancel(cmdId)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
@@ -423,7 +423,7 @@ const ChoreView = () => {
showError({ showError({
title: t('choreView.undoFailed'), title: t('choreView.undoFailed'),
message: error?.message || 'Unable to start task', message: error?.message || t('choreView.unableStart'),
}) })
}, },
}) })
@@ -450,7 +450,7 @@ const ChoreView = () => {
setChore(pausedChore) setChore(pausedChore)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
showSuccess({ showSuccess({
message: "You're offline — pause will sync when back online", message: t('choreView.offlinePause'),
undoAction: async () => { undoAction: async () => {
await commandQueue.cancel(cmdId) await commandQueue.cancel(cmdId)
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
@@ -462,7 +462,7 @@ const ChoreView = () => {
showError({ showError({
title: t('choreView.undoFailed'), title: t('choreView.undoFailed'),
message: error?.message || 'Unable to pause task', message: error?.message || t('choreView.unablePause'),
}) })
}, },
}) })
@@ -566,7 +566,7 @@ const ChoreView = () => {
setChore({ ...chore, isActive: true }) setChore({ ...chore, isActive: true })
queryClient.invalidateQueries({ queryKey: ['pendingCommands'] }) queryClient.invalidateQueries({ queryKey: ['pendingCommands'] })
showSuccess({ showSuccess({
message: "You're offline — restore will sync when back online", message: t('choreView.offlineRestore'),
undoAction: async () => { undoAction: async () => {
await commandQueue.cancel(cmdId) await commandQueue.cancel(cmdId)
await offlineDB.saveChores([{ ...chore, isActive: false }]) await offlineDB.saveChores([{ ...chore, isActive: false }])
@@ -576,8 +576,8 @@ const ChoreView = () => {
}) })
} else { } else {
showError({ showError({
title: 'Failed to restore', title: t('choreView.restoreFailed'),
message: error.message || 'Unable to restore task', message: error.message || t('choreView.unableRestore'),
}) })
} }
} }

View File

@@ -249,7 +249,7 @@ const MFASettings = () => {
size='sm' size='sm'
onClick={handleRegenerateBackupCodes} onClick={handleRegenerateBackupCodes}
> >
Generate New Codes {t('mfa.generateCodes')}
</Button> </Button>
</Box> </Box>
</Card> </Card>