i18n: extract the chore list and its modals (chores namespace)

Part of #145.

Twenty-three files across the task list zone: the list and card views,
sorting and grouping, multi-select and its toolbar and help sheet,
archived tasks, the assignee card, the chore action menu, the
nudge/NFC/photo modals, the rich text editor, the scan panel, the
notification templates and the keyboard-shortcut toasts.

Extends the existing `chores` namespace, so `src/i18n/config.js` is
untouched.

English only — no translations, no behaviour change. Every t() value is
checked against this branch's base: the string must appear
character-for-character in the code it replaces (247 call sites).

Two values are matched loosely and worth naming: archived.closeMultiSelect
in both the archived view and the toolbar. The base builds that tooltip as
`${size === 0 ? 'Close' : 'Clear'} multi-select (Esc)`, so only one branch
of the ternary exists contiguously in the source. Both keys hold exactly
what each branch renders; the tooltip is kept whole so a translator can
reorder it.

Rebased on current `develop` again after #215 and #216 landed — the
dictionary conflict was theirs, not the code's. No code file in this PR
was touched upstream in the meantime.
This commit is contained in:
everysingletear
2026-08-15 09:03:28 +08:00
parent f43369c960
commit 7d36090e46
25 changed files with 542 additions and 273 deletions

View File

@@ -100,11 +100,24 @@
"saveFilter": "Save Filter",
"saveAsNew": "Save as New Filter",
"groupBy": "Group by",
"showTasksFor": "Show tasks for"
"showTasksFor": "Show tasks for",
"type": {
"assignee": "Assignee"
}
},
"sort": {
"assignedToMe": "Assigned to me",
"smart": "Smart"
"smart": "Smart",
"createdDate": "Created Date",
"updatedDate": "Updated Date",
"sortAndGroup": "Sort and Group (Ctrl+G)",
"groupBy": "Group By",
"quickFilters": "Quick Filters",
"assignedTo": "Assigned to:",
"availableForMe": "Available for me",
"assignedToOthers": "Assigned to others",
"createFilter": "Create Filter",
"createFilterHint": "Build advanced filter rules"
},
"thing": {
"triggerHint": "Trigger a task when a thing state changes to a desired state",
@@ -124,7 +137,9 @@
"dueToday": "Due Today",
"pendingApproval": "Pending Approval",
"dueThisWeek": "Due This Week",
"noDueDate": "No Due Date"
"noDueDate": "No Due Date",
"dueDate": "Due Date",
"dueLater": "Due Later"
},
"insights": {
"highPriority": "High Priority"
@@ -134,7 +149,16 @@
},
"actionMenu": {
"view": "View",
"archive": "Archive"
"archive": "Archive",
"writeNFC": "Write to NFC",
"completeWithNote": "Complete with note",
"completeInPast": "Complete in past",
"skipToNext": "Skip to next due date",
"sendNudge": "Send nudge",
"history": "History",
"clone": "Clone",
"moveToProject": "Move to project",
"removeDueDate": "Remove due date"
},
"actions": {
"rescheduledTitle": "Task Rescheduled",
@@ -187,18 +211,195 @@
"someFailedTitle": "Some Tasks Failed",
"unexpectedError": "An unexpected error occurred. Please try again.",
"deletedBulkTitle": "🗑️ Tasks Deleted",
"bulkDeleteFailTitle": "Bulk Delete Failed"
"bulkDeleteFailTitle": "Bulk Delete Failed",
"archivedDate": "Archived Date",
"loadFailTitle": "Failed to load archived tasks",
"loadFailMsg": "Please try again later.",
"deletedMsg": "The archived task has been permanently deleted.",
"restoreTasksTitle": "Restore Tasks",
"restore": "Restore",
"restoreConfirm_one": "Restore {{count}} task to active list?",
"restoreConfirm_other": "Restore {{count}} tasks to active list?",
"restoredBulkTitle": "📤 Tasks Restored",
"restoredCount_one": "Restored {{count}} task{{offline}}.",
"restoredCount_other": "Restored {{count}} tasks{{offline}}.",
"restoreFailCount_one": "{{count}} task could not be restored.",
"restoreFailCount_other": "{{count}} tasks could not be restored.",
"bulkRestoreFailTitle": "Bulk Restore Failed",
"deleteTasksTitle": "Delete Archived Tasks",
"deleteConfirm_one": "Permanently delete {{count}} archived task?\n\nThis action cannot be undone.",
"deleteConfirm_other": "Permanently delete {{count}} archived tasks?\n\nThis action cannot be undone.",
"deletedCount_one": "Successfully deleted {{count}} task.",
"deletedCount_other": "Successfully deleted {{count}} tasks.",
"deleteFailCount_one": "{{count}} task could not be deleted.",
"deleteFailCount_other": "{{count}} tasks could not be deleted.",
"title": "Archived Tasks",
"subtitle": "View and manage tasks that have been archived or completed.",
"heading": "Archived Tasks",
"searchPlaceholder": "Search archived tasks",
"switchToCompact": "Switch to Compact View",
"switchToCard": "Switch to Card View",
"exitMultiSelect": "Exit Multi-select Mode (Ctrl+S)",
"enableMultiSelect": "Enable Multi-select Mode (Ctrl+S)",
"selected_one": "{{count}} task selected",
"selected_other": "{{count}} tasks selected",
"selectAllTitle": "Select all visible tasks (Ctrl+A)",
"all": "All",
"closeMultiSelect": "Close multi-select (Esc)",
"clearMultiSelect": "Clear multi-select (Esc)",
"close": "Close",
"clear": "Clear",
"restoreSelectedTitle": "Restore selected tasks (R)",
"deleteSelectedTitle": "Delete selected tasks (E)",
"clearSearch": "Clear search",
"clearFilters": "Clear filters",
"count_one": "{{count}} archived task",
"count_other": "{{count}} archived tasks",
"matching": " matching \"{{term}}\""
},
"edit": {
"deleteConfirm": "Are you sure you want to delete this chore?"
},
"list": {
"complete": "Complete"
"complete": "Complete",
"filterSaved": "Filter Saved",
"filterSavedMsg": "\"{{name}}\" has been saved",
"nothingScheduled": "Nothing scheduled",
"createChore": "Create new chore (Cmd+C)",
"filterUpdated": "Filter Updated",
"filterUpdatedMsg": "\"{{name}}\" has been updated successfully",
"advancedFilterCreated": "Advanced Filter Created",
"advancedFilterCreatedMsg": "\"{{name}}\" has been created successfully"
},
"multiToolbar": {
"skip": "Skip"
"skip": "Skip",
"completeTitle": "Complete selected tasks (Enter)",
"complete": "Complete",
"skipTitle": "Skip selected tasks (/)",
"archiveTitle": "Archive selected tasks (X)",
"archive": "Archive",
"deleteTitle": "Delete selected tasks (Shift+X)"
},
"remind": {
"title": "Reminders"
},
"assignee": {
"anyone": "Anyone"
},
"filterChip": {
"cancelAll": "Cancel All Filters",
"unpin": "Unpin filter",
"pin": "Pin filter",
"edit": "Edit filter",
"delete": "Delete filter"
},
"multiSelect": {
"showShortcuts": "Show keyboard shortcuts",
"title": "Multi-select Mode",
"selection": "Selection",
"selectAll": "Select all visible tasks",
"clearOrExit": "Clear selection or exit multi-select mode",
"actions": "Actions",
"markCompleted": "Mark selected tasks as completed",
"deleteSelected": "Delete selected tasks",
"interface": "Interface",
"quickAdd": "Quick add new task"
},
"notifications": {
"needTitle": "Need Notification?",
"needBody": "You need to enable permission to receive notifications, do you want to enable it?",
"keepDisabled": "No, Keep it Disabled"
},
"assigneeCard": {
"loading": "Loading tasks by assignee...",
"title": "Tasks by Assignee",
"scheduled": "Scheduled",
"pendingReview": "Pending Review"
},
"filter": {
"status": {
"inProgress": "In Progress"
}
},
"impersonate": {
"viewAs": "View tasks as",
"switchTitle": "Switch to user view",
"switchHint": "Tasks will be filtered to show only assignments for selected user",
"chooseUser": "Choose User",
"changeUser": "Change User"
},
"modals": {
"changeDueDate": "Change due date",
"completePast": "Save Chore that you completed in the past",
"delegate": "Delegate to someone else",
"selectPerformer": "Select a performer",
"addNote": "Add note to attach to this completion:",
"complete": "Complete"
},
"shortcuts": {
"allSelectedTitle": "✅ All Tasks Selected",
"someSelectedTitle": "🎯 Tasks Selected",
"allSelectedAltTitle": "🎯 All Tasks Selected"
},
"overview": {
"title": "Chores Overviews",
"search": "Search",
"newChore": "New Chore",
"unassigned": "Unassigned",
"changeDueDate": "Change due date"
},
"dataError": {
"attachmentsFailed": "Failed to fetch attachments"
},
"nudge": {
"title": "Send Nudge",
"customMessage": "Custom Message (optional)",
"messagePlaceholder": "Add a personal message with your nudge...",
"notifyAll": "Notify All Assignees",
"notifyAllHint": "If enabled, all members who can see this task will be notified. Otherwise, only the assigned person will receive the nudge."
},
"nfc": {
"errWrite": "Error writing to NFC tag. Please try again.",
"errUnsupported": "NFC is not supported by this browser. Copy the URL and write it to an NFC tag using a compatible device.",
"titleSuccess": "Tag written!",
"titleError": "Something went wrong",
"titleWaiting": "Hold near NFC tag",
"subSuccess": "Your NFC tag is ready to use.",
"subWaiting": "Keep your device near the tag until complete.",
"subIdle": "Encode this task link onto any NFC tag.",
"tagUrl": "Tag URL",
"copyUrl": "Copy URL",
"autoComplete": "Auto-complete on scan",
"autoCompleteHint": "Mark task done when tag is tapped"
},
"duePicker": {
"today": "Today",
"tomorrow": "Tomorrow",
"weekend": "Weekend",
"nextWeek": "Next week"
},
"photoTask": {
"title": "Scan photo to create task",
"cameraUnavailable": "Camera not available",
"uploadPhoto": "Upload Photo",
"scanDocument": "Scan Document",
"capture": "Capture",
"processNatively": "Process Natively",
"processImage": "Process Image",
"createTask": "Create Task",
"failedScan": "Failed scan"
},
"descriptionPlaceholder": "Enter description...",
"notifTemplate": {
"onDueDate": "On due date",
"beforeDue": "{{count}} {{unit}} before due",
"afterDue": "{{count}} {{unit}} after due",
"errDuplicate": "This notification setting already exists. Please use a different timing.",
"errOneDue": "Only one \"Due Alert\" notification is allowed.",
"errAllConfigured": "All common {{type}} times are already configured.",
"reminder": "Reminder",
"dueAlert": "Due Alert",
"followUp": "Follow-up",
"rememberFuture": "Remember for Future Tasks"
}
}

View File

@@ -131,7 +131,14 @@
"tooLargeTitle": "File Too Large",
"tooLargeMessage": "The file you are trying to upload is too large.",
"deniedTitle": "Permission Denied",
"deniedMessage": "You do not have permission to upload files."
"deniedMessage": "You do not have permission to upload files.",
"plusFeatureTitle": "Plus Feature",
"plusFeatureMessage": "Image uploads are not available in the Basic plan. Upgrade to Plus to add images to your content.",
"upgradeTitle": "Upgrade Required",
"upgradeMessage": "Image uploads are only available for Plus accounts.",
"failedTitle": "Upload Failed",
"failedMessage": "Failed to upload image.",
"processingMessage": "An error occurred while processing the image."
},
"getStarted": "Get Started!",
"imageLoadFailed": "Failed to load image.",
@@ -191,5 +198,7 @@
"allSynced": "All changes synced",
"willSync": "Will sync when back online",
"cancelAll": "Cancel All"
}
},
"attachments": "Attachments",
"fileNumbered": "File {{index}}"
}