diff --git a/config/mobile-localization-coverage-allowlist.json b/config/mobile-localization-coverage-allowlist.json index 31821f2c63b..3251f791639 100644 --- a/config/mobile-localization-coverage-allowlist.json +++ b/config/mobile-localization-coverage-allowlist.json @@ -195,41 +195,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/new-workspace/NewWorkspaceHostPicker.tsx", - "kind": "jsx-attribute:title", - "text": "Create Workspace On", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/new-workspace/NewWorkspaceLoadingDrawer.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Cancel", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/new-workspace/NewWorkspaceLoadingDrawer.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Downloading", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/new-workspace/NewWorkspaceLoadingDrawer.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Loading", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/new-workspace/NewWorkspaceLoadingDrawer.tsx", - "kind": "jsx-text", - "text": "Downloading…", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/onboarding/NotificationOnboardingPreview.tsx", "kind": "jsx-text", @@ -335,90 +300,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/source-control/mobile-branch-compare-outcome.ts", - "kind": "object-property:message", - "text": "Unable to resolve the base branch for comparison.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-branch-compare.ts", - "kind": "object-property:title", - "text": "Committed on Branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-create-pr-action.ts", - "kind": "object-property:label", - "text": "Checking review status…", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-create-pr-action.ts", - "kind": "object-property:label", - "text": "Create Pull Request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-create-pr-action.ts", - "kind": "object-property:label", - "text": "Review creation unavailable for this provider", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-create-pr-action.ts", - "kind": "object-property:label", - "text": "Review status unavailable", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-hosted-review-create-intent.ts", - "kind": "object-property:error", - "text": "Branch changed while preparing the pull request.", - "dynamic": false, - "count": 4 - }, - { - "filePath": "mobile/src/source-control/mobile-hosted-review-create-intent.ts", - "kind": "object-property:error", - "text": "Could not generate a commit message. Add one in Source Control, then retry.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-hosted-review-create-intent.ts", - "kind": "object-property:error", - "text": "Resolve conflicts before creating a pull request.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-hosted-review-create-intent.ts", - "kind": "object-property:error", - "text": "Resolve or stage changes before creating a pull request.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/mobile-hosted-review-create-intent.ts", - "kind": "object-property:error", - "text": "Review the commit message, then retry Create PR.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Close committed diff preview", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx", "kind": "jsx-expression", @@ -426,482 +307,6 @@ "dynamic": true, "count": 1 }, - { - "filePath": "mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx", - "kind": "jsx-expression", - "text": "Committed on branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx", - "kind": "jsx-text", - "text": "Diff truncated for mobile preview.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx", - "kind": "jsx-text", - "text": "Unable to Load Diff", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Fix commit failure with AI", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Hide commit failure details", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Show commit failure details", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-expression", - "text": "Commit failed.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-expression", - "text": "Hide details", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-expression", - "text": "Show details", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-text", - "text": "Commit failed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileCommitFailurePanel.tsx", - "kind": "jsx-text", - "text": "Fix", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Retry", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Retry commit files", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-expression", - "text": "Waiting for desktop...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-text", - "text": "No commits.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-text", - "text": "No file changes", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-text", - "text": "Retry", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/source-control/MobileGitHistoryList.tsx", - "kind": "jsx-text", - "text": "Waiting for desktop...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlBranchCard.tsx", - "kind": "jsx-text", - "text": "changed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlBranchCard.tsx", - "kind": "jsx-text", - "text": "on branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlBranchCard.tsx", - "kind": "jsx-text", - "text": "staged", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:accessibilityHint", - "text": "Clear the message to regenerate.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Cancel commit message generation", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Commit message disabled. No staged files.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Generate commit message with AI", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open source control actions", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Commit message", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "No local changes", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "No staged files", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "Reconnecting to desktop...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "Stage All", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "Unstage All", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlContent.tsx", - "kind": "jsx-text", - "text": "Working tree is clean.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileList.tsx", - "kind": "object-property:title", - "text": "Committed on Branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Discard", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open changed file", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open committed change", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Stage", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Unstage", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-expression", - "text": "Committed changes unavailable.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-expression", - "text": "Unresolved conflict", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-text", - "text": "Committed on Branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-text", - "text": "from", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlFileRows.tsx", - "kind": "jsx-text", - "text": "Loading committed changes...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Back to session", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Close source control", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "on the web", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open pull request #", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open pull request on the web", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Refresh source control", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlHeader.tsx", - "kind": "jsx-text", - "text": "Source Control", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:message", - "text": "\"? This cannot be undone.", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:message", - "text": "Discard changes to \"", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:message", - "text": "Open it in your browser?", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:message", - "text": "Open it in your browser?", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:title", - "text": "Discard Change", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:title", - "text": "Pull Request Created", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:title", - "text": "Source Control", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlModals.tsx", - "kind": "jsx-attribute:title", - "text": "Switch Branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlPanel.tsx", - "kind": "jsx-expression", - "text": "Source Control Unavailable", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlPanel.tsx", - "kind": "jsx-expression", - "text": "Unable to Load", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlPanel.tsx", - "kind": "jsx-text", - "text": "Retry", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlPrChip.tsx", - "kind": "jsx-text", - "text": "Create pull request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/MobileSourceControlPrChip.tsx", - "kind": "jsx-text", - "text": "Loading pull request…", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/source-control/use-mobile-source-control-loaders.ts", - "kind": "object-property:message", - "text": "Update Orca desktop to use Source Control on mobile.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "All", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Closed", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", "kind": "object-property:label", @@ -930,69 +335,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Merged", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Name", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Open", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-smart-source-modes.ts", - "kind": "object-property:label", - "text": "Smart", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-task-view-options.tsx", - "kind": "object-property:subtitle", - "text": "Unresolved issues across the selected sites", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-task-view-options.tsx", - "kind": "object-property:subtitle", - "text": "Unresolved issues assigned to you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-task-view-options.tsx", - "kind": "object-property:subtitle", - "text": "Unresolved issues you reported", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-task-view-options.tsx", - "kind": "object-property:subtitle", - "text": "Your recently resolved issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add context", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", "kind": "jsx-attribute:placeholder", @@ -1000,1126 +342,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Task title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-attribute:title", - "text": "Create Workspace In", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-attribute:title", - "text": "Linear Team", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-attribute:title", - "text": "Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Create an issue in the selected Linear team.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Create an issue in the selected repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Origin", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Team", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-expression", - "text": "Upstream", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Connect", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Connect Linear workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Create Issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "File in", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Issue source", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Linear Settings / Security / New API key", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "New", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Paste a Personal API key to browse issues from that workspace.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Personal API key", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-create-drawers.tsx", - "kind": "jsx-text", - "text": "Your key is encrypted via the host OS keychain and stored locally.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "GitLab Filter", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "GitLab View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Jira Filter", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Jira Site", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Linear Filter", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Linear Workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-expression", - "text": "Hidden from cards", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-expression", - "text": "Linear issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-expression", - "text": "Shown on cards", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "All teams", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Change Status", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Choose which Project fields appear on item cards.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Choose which teams appear in Tasks.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Linear Teams", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Loading states...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "No states available", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "Project Fields", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "teams", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-filter-pickers.tsx", - "kind": "jsx-text", - "text": "This view has no extra fields to show.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-expression", - "text": "Issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-expression", - "text": "Items", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-expression", - "text": "Project item", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-expression", - "text": "Pull request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-text", - "text": "Browse projects", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-text", - "text": "Choose a GitHub project", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-text", - "text": "fields", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-list.tsx", - "kind": "jsx-text", - "text": "No project items", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add by URL or owner/number", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Search projects", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Choose Project View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Project Sort", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Project View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Add", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Adding...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Browse all", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Browse all (loading...)", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Couldn't load projects from", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "No matching projects.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "No more projects.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-expression", - "text": "Some organizations didn't load (", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Choose a project view for the Tasks page.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "GitHub Projects", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "No projects loaded", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Pin", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Pinned", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Recent", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Remove", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Tap to retry.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-project-pickers.tsx", - "kind": "jsx-text", - "text": "Use Add by URL to reach missing projects.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-view-controls.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Open view in GitHub", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-view-controls.tsx", - "kind": "jsx-text", - "text": "Fields:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-view-controls.tsx", - "kind": "jsx-text", - "text": "Sort:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-github-view-controls.tsx", - "kind": "jsx-text", - "text": "Source:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-expression", - "text": "Copied", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-expression", - "text": "Copy GitHub link", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-expression", - "text": "Copy Linear link", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-expression", - "text": "Create Workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-expression", - "text": "Creating...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-text", - "text": "Change status", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-text", - "text": "GitHub reports merge conflicts.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-text", - "text": "Merge merge request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-actions.tsx", - "kind": "jsx-text", - "text": "Merge pull request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Sub-issue title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-expression", - "text": "jobs", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-expression", - "text": "None", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Add sub-issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Assignee", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Assignees", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Checks", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Discussion", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "No checks found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "No comments.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "No pipeline runs for this MR.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "No sub-issues.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Open", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Pipeline", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Project", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Refresh", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Rerun all", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Rerun failed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Status", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Sub-issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-content.tsx", - "kind": "jsx-text", - "text": "Type", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-detail-drawer.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Refresh details", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add labels, comma separated", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add usernames, comma separated", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Remove labels, comma separated", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Remove usernames, comma separated", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-expression", - "text": "None", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Assignees", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Labels", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Loading assignees...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Loading labels...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "No assignable users found for this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "No labels in this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Save title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Update assignees", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-field-editors.tsx", - "kind": "jsx-text", - "text": "Update labels", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Request reviewers", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-expression", - "text": "Hide", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-expression", - "text": "Mark unviewed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-expression", - "text": "Mark viewed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-expression", - "text": "View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Binary file.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Changed files", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "File contents unavailable.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Loading reviewers...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "No reviewer suggestions found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "No reviewers requested.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Request review", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Reviewers", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-item-review-sections.tsx", - "kind": "jsx-text", - "text": "Save description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-linear-list.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Change status from", - "dynamic": true, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-linear-view-controls.tsx", - "kind": "jsx-text", - "text": "Display", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-linear-view-controls.tsx", - "kind": "jsx-text", - "text": "Group:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-linear-view-controls.tsx", - "kind": "jsx-text", - "text": "Order:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-display-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Group Linear Issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-display-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Linear View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-display-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Order Linear Issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-display-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Sort Tasks", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-display-pickers.tsx", - "kind": "jsx-text", - "text": "Display Properties", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-surface.tsx", - "kind": "jsx-text", - "text": "Browse and start work on your assigned Linear issues directly from Tasks.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-surface.tsx", - "kind": "jsx-text", - "text": "Connect Linear", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-surface.tsx", - "kind": "jsx-text", - "text": "Connect your Linear account", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-surface.tsx", - "kind": "jsx-text", - "text": "This mobile Tasks view needs a newer desktop runtime.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-list-surface.tsx", - "kind": "jsx-text", - "text": "Update Orca desktop", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "All", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Assigned to me", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Assignee", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Board", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Closed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Completed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Created", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", "kind": "object-property:label", @@ -2134,20 +356,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Identifier", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Issues", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", "kind": "object-property:label", @@ -2155,13 +363,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Labels", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", "kind": "object-property:label", @@ -2169,1378 +370,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "List", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Merged", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Mine", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "My Issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "My Todos", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Needs review", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "No grouping", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Open", - "dynamic": false, - "count": 3 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Priority", - "dynamic": false, - "count": 3 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Project MRs", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Projects", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "PRs", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Status", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Team", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:label", - "text": "Updated", - "dynamic": false, - "count": 3 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Any GitLab state", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Assigned and reported issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Assigned and team issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Closed issues and merge requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Compact issue rows", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "GitHub issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "GitHub Projects views", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "GitHub pull requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Group by repository, then newest activity", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Grouped columns", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Issues and merge requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Issues and pull requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Issues assigned to you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Issues created by you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Merge requests and issues by repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Merged merge requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Newest activity first", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Open GitHub issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Open issues across connected workspaces", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Open issues and merge requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Open issues assigned to you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Open pull requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Pending GitLab todos", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Pull requests authored by you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Recently completed issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-options.tsx", - "kind": "object-property:subtitle", - "text": "Review requests assigned to you", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Edit comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Reply", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "comments", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "Reopen thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "Resolve thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "Show", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-expression", - "text": "thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "by", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Cancel", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Delete", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Discussion", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Edit", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "No comments.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Reply", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Resolved", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-comments.tsx", - "kind": "jsx-text", - "text": "Save", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Close item", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Copied", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Copy GitHub link", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Copy repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Draft issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "No type", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Project item", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Pull request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-expression", - "text": "Reopen item", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Clear type", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Create Workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "GitHub Project ·", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "is not added to Orca. Add this repository from the desktop app, then refresh mobile Tasks.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Issue type", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Loading issue types...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Merge pull request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Merge requires this repository in Orca.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "No issue types configured for this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Open in GitHub", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Repository not in Orca", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Status", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Type", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx", - "kind": "jsx-text", - "text": "Workspaces can only be created from GitHub issues and pull requests.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Number", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Text", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "YYYY-MM-DD", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-expression", - "text": "Completed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-expression", - "text": "Current & upcoming", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-text", - "text": "Clear field", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-text", - "text": "No iterations available.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-text", - "text": "Project fields", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-field-editors.tsx", - "kind": "jsx-text", - "text": "Save field", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-expression", - "text": "None", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Assignees", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Description", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Labels", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Loading assignees...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Loading labels...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "No assignable users found for this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "No labels in this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Save description", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Save title", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx", - "kind": "jsx-text", - "text": "Title", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Request reviewers", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-expression", - "text": "Hide", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-expression", - "text": "Mark unviewed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-expression", - "text": "Mark viewed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-expression", - "text": "View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Binary file.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Changed files", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Checks", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "File contents unavailable.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Loading reviewers...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "No checks found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "No reviewer suggestions found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "No reviewers requested.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Refresh", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Request review", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Rerun all", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Rerun failed", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-project-review-panels.tsx", - "kind": "jsx-text", - "text": "Reviewers", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-controls.tsx", - "kind": "jsx-expression", - "text": "My Todos", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-controls.tsx", - "kind": "jsx-expression", - "text": "Project MRs", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-controls.tsx", - "kind": "jsx-text", - "text": "Sort:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Next page", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "of", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Previous page", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Select page, Page", - "dynamic": true, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-expression", - "text": "of", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-expression", - "text": "Page", - "dynamic": true, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-item-list.tsx", - "kind": "jsx-text", - "text": "into", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "GitHub View", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Issues", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Pull Requests", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-attribute:title", - "text": "Task Source", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-expression", - "text": "Loaded", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-expression", - "text": "Loads older results", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-expression", - "text": "Origin", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-expression", - "text": "Upstream", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "All repositories", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Choose whether each repository queries and creates work from upstream or origin.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Choose which repositories to query.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "GitHub Issue Sources", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "GitHub Pages", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Jump to a loaded or available result page.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "No alternate issue sources available.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Page", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Querying", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-provider-pickers.tsx", - "kind": "jsx-text", - "text": "Repositories", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-reviewer-linear.ts", - "kind": "object-property:label", - "text": "Issues", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-screen-chrome.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Back", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-screen-chrome.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Connect Linear", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-screen-chrome.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "New GitHub issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-screen-chrome.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "New Linear issue", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-screen-chrome.tsx", - "kind": "jsx-text", - "text": "Tasks", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-search-control.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Jira JQL, e.g. project = ABC AND statusCategory != Done", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-search-control.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Search", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-search-control.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Search project view...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-search-control.tsx", - "kind": "jsx-attribute:placeholder", - "text": "tasks...", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-attribute:title", - "text": "Agent", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-attribute:title", - "text": "Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Add a Git repository before creating a Linear workspace.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Connect", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Connect Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Connect repository first", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Connecting...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Create Workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Default branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Detecting agents...", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Remote repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Repository not found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-expression", - "text": "Select a repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "[Optional]", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Advanced", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Agent", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Create from", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Create Workspace", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "SSH Connection", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Start from", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx", - "kind": "jsx-text", - "text": "Workspace Name", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Edit", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Search branches", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Branch name:", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Default branch", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Full checkout", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "New preset", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "No branches match.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Pick an existing branch or ref.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Sparse Checkout", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Start From", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Use the whole repository", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx", - "kind": "jsx-text", - "text": "Use this repository's configured base", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Renderer UI", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", "kind": "jsx-attribute:placeholder", @@ -3548,412 +377,6 @@ "dynamic": false, "count": 1 }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "'s setup script changed", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "1 directory", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "Creating...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "directories", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "Edit Sparse Preset", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "New setup script", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "New Sparse Preset", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "Run setup and create", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "Run setup from", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-expression", - "text": "Setup script", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Always trust and run", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Cancel", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Directories", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Don't run", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Name", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "requires a setup choice before creating this workspace.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Run hooks", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Run Setup Script?", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Save", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "Skip setup and create", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx", - "kind": "jsx-text", - "text": "This repository's orca.yaml runs on your machine before the workspace starts. Only run it if you trust this repository.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Retry loading issues from", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:message", - "text": "Choose how this merge request should be merged.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:message", - "text": "Choose how this pull request should be merged.", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:title", - "text": "Merge method", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:title", - "text": "Merge Pull Request", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:title", - "text": "Merge Request", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-attribute:title", - "text": "Update Item", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-expression", - "text": "Retry", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-expression", - "text": "Retrying...", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-text", - "text": ". Using origin.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-text", - "text": "Couldn't load issues from", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-text", - "text": "Preferred issue source upstream is unavailable for", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksLegacySurface.tsx", - "kind": "jsx-text", - "text": "Sub-issue data is unavailable for your token.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add review comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-text", - "text": "Comment on line", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-text", - "text": "diff lines.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-text", - "text": "No text changes found.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-text", - "text": "of", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/MobileTasksPrFileDiff.tsx", - "kind": "jsx-text", - "text": "Showing first", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/sparse-preset-draft.ts", - "kind": "object-property:error", - "text": "Add at least one directory.", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/sparse-preset-draft.ts", - "kind": "object-property:error", - "text": "Use repo-relative directories, not root, absolute paths, or parent segments.", - "dynamic": false, - "count": 2 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-attribute:accessibilityLabel", - "text": "Send comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Add a comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-attribute:placeholder", - "text": "Reply", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "comment", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "comments", - "dynamic": true, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "Reopen thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "Resolve thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "Show", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-expression", - "text": "thread", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-text", - "text": "by", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-text", - "text": "Reply", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx", - "kind": "jsx-text", - "text": "Resolved", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-picker-projection.tsx", - "kind": "object-property:label", - "text": "All sites", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-picker-projection.tsx", - "kind": "object-property:label", - "text": "View order", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-provider-view-projection.tsx", - "kind": "object-property:label", - "text": "All workspaces", - "dynamic": false, - "count": 1 - }, - { - "filePath": "mobile/src/tasks/use-mobile-tasks-workspace-create-projection.tsx", - "kind": "object-property:subtitle", - "text": "Open a shell", - "dynamic": false, - "count": 1 - }, { "filePath": "mobile/src/terminal/terminal-key-definitions.ts", "kind": "object-property:accessibilityLabel", diff --git a/config/scripts/verify-mobile-web-app-bundle.mjs b/config/scripts/verify-mobile-web-app-bundle.mjs index 78c8055760c..07f0c465caf 100644 --- a/config/scripts/verify-mobile-web-app-bundle.mjs +++ b/config/scripts/verify-mobile-web-app-bundle.mjs @@ -230,7 +230,7 @@ export async function verifyMobileWebAppBundle({ bundleDir = defaultBundleDir } `budget of ${String(MOBILE_WEB_APP_BUNDLE_MAX_ENTRY_BYTES)}` ) } - return manifest + return { ...manifest, catalogBytes: first.catalogBytes } } if (isDirectInvocation(import.meta.url, process.argv[1])) { @@ -239,7 +239,8 @@ if (isDirectInvocation(import.meta.url, process.argv[1])) { console.log( `[verify-mobile-web-app-bundle] OK — ${String(manifest.assets.length)} asset(s), ` + `${String(manifest.totalBytes)} total bytes, ` + - `${String(mobileWebAppBundleBudgetBytes(manifest))}/${String(MOBILE_WEB_APP_BUNDLE_MAX_TOTAL_BYTES)} bytes excluding the approved font, ` + + `${String(mobileWebAppBundleBudgetBytes(manifest) - manifest.catalogBytes)}/${String(MOBILE_WEB_APP_BUNDLE_MAX_TOTAL_BYTES)} bytes excluding the approved font, ` + + `${String(manifest.catalogBytes)}/${String(MOBILE_WEB_APP_BUNDLE_MAX_CATALOG_BYTES)} bytes of language catalogs, ` + `reproducible buildId ${manifest.buildId}` ) } catch (error) { diff --git a/mobile/app/_layout.tsx b/mobile/app/_layout.tsx index 346238dc412..8aa9a49cfb9 100644 --- a/mobile/app/_layout.tsx +++ b/mobile/app/_layout.tsx @@ -31,6 +31,7 @@ import { appUpdateChecker } from '../src/app-update/app-update-runtime' import { SideSafeArea } from '../src/layout/side-safe-area' import { useFollowDeviceUiLocale } from '../src/i18n/use-follow-device-ui-locale' import { startMobileUiLanguage } from '../src/i18n/ui-language-preference' +import { subscribeMobileUiLanguage } from '../src/i18n/mobile-i18n' // Keep splash visible until React content is ready to avoid a blank frame. SplashScreen.preventAutoHideAsync() @@ -41,6 +42,10 @@ const languageReady = startMobileUiLanguage() // Create orca-desktop channel at boot: background FCM can arrive before socket subscription, and Android drops unknown-channel pushes. void ensureDesktopNotificationChannel().catch(() => {}) +// Channel names show in Android settings; rename them in the active language. +subscribeMobileUiLanguage(() => { + void ensureDesktopNotificationChannel().catch(() => {}) +}) void registerPushDismissalTask().catch(() => {}) // Register before scheduling so foreground delivery uses the same suppression policy. diff --git a/mobile/src/i18n/en-runtime-required.json b/mobile/src/i18n/en-runtime-required.json index 8f690de7048..4bfab6bc30c 100644 --- a/mobile/src/i18n/en-runtime-required.json +++ b/mobile/src/i18n/en-runtime-required.json @@ -199,6 +199,18 @@ } }, "sourceControl": { + "actions": { + "pullCommits_one": "Pull {{count}} commit.", + "pullCommits_other": "Pull {{count}} commits.", + "pushCommits_one": "Push {{count}} commit.", + "pushCommits_other": "Push {{count}} commits." + }, + "branchCompare": { + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commits", + "files_one": "{{count}} file", + "files_other": "{{count}} files" + }, "dropdownCounts": { "fastForwardCount_one": "Fast-forward {{count}} commit", "fastForwardCount_other": "Fast-forward {{count}} commits", @@ -214,6 +226,58 @@ "titleManualForcePush_other": "Force push {{count}} local commits with lease to update {{upstreamName}}.", "titleUnpublishedForcePushCount_one": "Force push {{count}} branch commit with lease and set an upstream if needed.", "titleUnpublishedForcePushCount_other": "Force push {{count}} branch commits with lease and set an upstream if needed." + }, + "gitHistory": { + "days_one": "{{count}}d", + "days_other": "{{count}}d", + "hours_one": "{{count}}h", + "hours_other": "{{count}}h", + "minutes_one": "{{count}}m", + "minutes_other": "{{count}}m", + "months_one": "{{count}}mo", + "months_other": "{{count}}mo", + "years_one": "{{count}}y", + "years_other": "{{count}}y" + }, + "prChip": { + "openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.", + "openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request." + } + }, + "tasks": { + "detailCommentRenderers": { + "comments_one": "{{count}} comment", + "comments_other": "{{count}} comments" + }, + "filterPickers": { + "teams_one": "{{count}} team", + "teams_other": "{{count}} teams" + }, + "githubProjectList": { + "moreFields_one": "+{{count}} field", + "moreFields_other": "+{{count}} fields" + }, + "itemDetailContent": { + "pipelineJobs_one": "{{count}} jobs", + "pipelineJobs_other": "{{count}} jobs" + }, + "pickerProjection": { + "repos_one": "{{count}} repo", + "repos_other": "{{count}} repos", + "sources_one": "{{count}} source", + "sources_other": "{{count}} sources" + }, + "projectComments": { + "comments_one": "{{count}} comment", + "comments_other": "{{count}} comments" + }, + "providerViewProjection": { + "teams_one": "{{count}} team", + "teams_other": "{{count}} teams" + }, + "workspaceTrustDrawers": { + "directories_one": "{{count}} directory", + "directories_other": "{{count}} directories" } }, "worktree": { diff --git a/mobile/src/i18n/locales/de.json b/mobile/src/i18n/locales/de.json index 9447153d73f..3e99b83e5c7 100644 --- a/mobile/src/i18n/locales/de.json +++ b/mobile/src/i18n/locales/de.json @@ -6,7 +6,7 @@ "connectingTo": "Verbindung zu {{name}} wird hergestellt…", "default": "Systemstandard", "hostNotFound": "Host nicht gefunden", - "invalidSnapshot": "Ungültiger Kontodaten-Snapshot vom Host", + "invalidSnapshot": "Ungültige Momentaufnahme der Konten vom Host", "loadingAccounts": "Konten werden geladen…", "manageAccountsHint": "Konten auf dem Desktop unter Einstellungen → Konten hinzufügen oder erneut authentifizieren.", "refreshAccounts": "Konten aktualisieren", @@ -572,10 +572,10 @@ "codexResetCreditAction": { "activeAccountHint": "Verbraucht einen verdienten Credit zum Zurücksetzen des Ratenlimits für das aktive Codex-Konto", "earnedReset": "Verdienter Credit zum Zurücksetzen des Codex-Ratenlimits", - "resetting": "Einlösen…", + "resetting": "Wird zurückgesetzt…", "resettingLabel": "Codex-Ratenlimits werden zurückgesetzt", "scopedHint": "Verbraucht einen verdienten Credit zum Zurücksetzen des Ratenlimits für {{scopeLabel}}", - "useReset": "Einlösen", + "useReset": "Jetzt zurücksetzen", "useResetLabel": "Zurücksetzung des Codex-Ratenlimits verwenden" }, "customKeyModal": { @@ -1495,7 +1495,21 @@ "workspace": "Arbeitsbereich" } }, + "newWorkspace": { + "hostPicker": { + "title": "Arbeitsbereich auf Host erstellen" + }, + "loadingDrawer": { + "downloadProgress": "Wird heruntergeladen… {{progress}}", + "downloading": "Wird heruntergeladen", + "loading": "Wird geladen" + } + }, "notifications": { + "desktopChannel": { + "name": "Desktop-Benachrichtigungen", + "silentName": "Lautlose Orca-Benachrichtigungen" + }, "notificationDeliverySection": { "footer": "Die Benachrichtigungsarten richten sich nach den Benachrichtigungseinstellungen des jeweiligen gekoppelten Computers. Nach 7 Tagen ohne Nutzung dieser App werden Benachrichtigungen pausiert; zum Fortsetzen die App öffnen und erneut verbinden.", "onlyWhenAway": "Nur bei Abwesenheit vom Computer", @@ -1785,10 +1799,10 @@ "dismissed": "Verworfen", "loadFailed": "Prüfer konnten nicht geladen werden. Zum erneuten Laden auf „Aktualisieren“ tippen.", "loading": "Prüfer werden geladen…", - "noReviewers": "Keine Prüfer angefragt", + "noReviewers": "Keine Prüfer angefordert", "pending": "Ausstehend", "removeReviewer": "{{login}} entfernen", - "requested": "Angefragt", + "requested": "Angefordert", "reviewed": "Geprüft", "title": "Prüfer" } @@ -2217,7 +2231,7 @@ }, "terminalLiveInputStatus": { "listening": "Hört zu", - "liveInput": "Live-Eingabe", + "liveInput": "Direkte Eingabe", "preparingMic": "Mikrofon wird vorbereitet", "processing": "Wird verarbeitet", "releaseMicHint": "Zum Stoppen Mikrofon loslassen", @@ -2524,11 +2538,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "Kein Basis-Branch für den Rebase vorhanden", + "waitingForDesktop": "Warten auf den Desktop…" + }, "actions": { + "checkingReviewStatus": "Review-Status wird geprüft.", + "checkoutBeforePublish": "Vor dem Veröffentlichen von Commits einen Branch auschecken.", + "commitStagedChanges": "Vorgemerkte Änderungen committen.", "commits": "Commits", + "committing": "Commit läuft.", "createPr": "PR erstellen", + "enterCommitMessage": "Zum Committen eine Commit-Nachricht eingeben.", + "forcePushWithLease": "Push mit Lease erzwingen, um den entfernten Branch zu aktualisieren.", + "forcePushing": "Push wird erzwungen.", + "linkedReviewUnavailable": "Der verknüpfte Review-Branch ist nicht verfügbar.", + "publishToOrigin": "Diesen Branch auf origin veröffentlichen.", + "pullCommits_one": "{{count}} Commit pullen.", + "pullCommits_other": "{{count}} Commits pullen.", "pushAndCreatePr": "Pushen & PR erstellen", - "switchBranch": "Branch wechseln" + "pushCommits_one": "{{count}} Commit pushen.", + "pushCommits_other": "{{count}} Commits pushen.", + "pushLinkedReview": "Änderungen auf den verknüpften Review-Branch pushen.", + "remoteOperationInProgress": "Remote-Vorgang läuft.", + "resolveConflicts": "Vor dem Committen Konflikte lösen.", + "reviewAlreadyMerged": "Nichts zu committen. Das Review wurde bereits gemergt.", + "stageAllChanges": "Alle Änderungen vormerken.", + "stageFileToCommit": "Zum Committen mindestens eine Datei vormerken.", + "switchBranch": "Branch wechseln", + "syncCounts": "{{behind}} pullen, {{ahead}} pushen.", + "upToDate": "Nichts zu committen. Branch ist aktuell.", + "waitForRemoteOperation": "Nach Abschluss des Remote-Vorgangs erneut versuchen." + }, + "branchBaseRef": { + "resolveFailed": "Branch-Basis konnte nicht ermittelt werden." + }, + "branchCard": { + "branchCount": "{{count}} auf Branch", + "changedCount": "{{count}} geändert", + "cherryPickState": "Cherry-pick", + "mergeState": "Merge", + "rebaseState": "Rebase", + "stagedCount": "{{count}} vorgemerkt" + }, + "branchCompare": { + "commits_one": "{{count}} Commit", + "commits_other": "{{count}} Commits", + "files_one": "{{count}} Datei", + "files_other": "{{count}} Dateien", + "sectionTitle": "Auf Branch committet", + "summary": "{{files}} – gegenüber {{baseRef}}", + "summaryWithCommits": "{{files}} – {{commits}} – gegenüber {{baseRef}}" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Basis-Branch für den Vergleich konnte nicht ermittelt werden.", + "loadFailed": "Committete Änderungen konnten nicht geladen werden." + }, + "branchDiffPreviewDrawer": { + "closePreview": "Diff-Vorschau der committeten Änderungen schließen", + "committedOnBranch": "Auf Branch committet", + "loadFailed": "Laden des Diffs fehlgeschlagen", + "truncated": "Diff für die mobile Vorschau gekürzt." }, "commitDropdown": { "checkOutBranchToPush": "Vor dem Pushen von Commits einen Branch auschecken", @@ -2553,8 +2623,49 @@ "stageFile": "Zum Committen mindestens eine Datei vormerken", "useCommitAndForcePush": "„Committen & Push erzwingen“ verwenden — das Remote enthält nur ältere Kopien lokaler Commits" }, + "commitFailurePanel": { + "fix": "Beheben", + "fixWithAi": "Commit-Fehler mit KI beheben", + "hideDetails": "Details ausblenden", + "hideFailureDetails": "Details zum Commit-Fehler ausblenden", + "showDetails": "Details anzeigen", + "showFailureDetails": "Details zum Commit-Fehler anzeigen", + "summary": "Commit fehlgeschlagen.", + "title": "Commit fehlgeschlagen" + }, + "commitMessageAi": { + "generateFailed": "Commit-Nachricht konnte nicht generiert werden." + }, + "commitRunners": { + "actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen", + "commitFailed": "Commit fehlgeschlagen" + }, + "conflictAbort": { + "abortMerge": "Merge abbrechen", + "abortOperation": "{{operation}} abbrechen", + "abortRebase": "Rebase abbrechen", + "aborting": "Wird abgebrochen…" + }, + "content": { + "cancelGeneration": "Generierung der Commit-Nachricht abbrechen", + "commitMessageDisabled": "Commit-Nachricht deaktiviert. Keine vorgemerkten Dateien.", + "commitMessagePlaceholder": "Commit-Nachricht", + "emptyMessage": "Der Worktree ist sauber.", + "emptyTitle": "Keine lokalen Änderungen", + "generateMessage": "Commit-Nachricht mit KI generieren", + "noStagedFiles": "Keine vorgemerkten Dateien", + "openActions": "Aktionen der Quellcodeverwaltung öffnen", + "reconnecting": "Verbindung zum Desktop wird wiederhergestellt…", + "regenerateHint": "Nachricht leeren, um sie neu zu generieren.", + "stageAll": "Alle vormerken", + "unstageAll": "Alle Vormerkungen aufheben" + }, "createPrAction": { - "createReview": "{{titleLabel}} erstellen" + "checkingStatus": "Review-Status wird geprüft…", + "createPullRequest": "Pull Request erstellen", + "createReview": "{{titleLabel}} erstellen", + "providerUnavailable": "Review-Erstellung bei diesem Anbieter nicht verfügbar", + "statusUnavailable": "Review-Status nicht verfügbar" }, "dropdownCounts": { "fastForwardCount_one": "{{count}} Commit per Fast-Forward übernehmen", @@ -2576,6 +2687,64 @@ "titleUnpublishedForcePushCount_one": "Push von {{count}} Branch-Commit mit Lease erzwingen und bei Bedarf einen Upstream festlegen.", "titleUnpublishedForcePushCount_other": "Push von {{count}} Branch-Commits mit Lease erzwingen und bei Bedarf einen Upstream festlegen." }, + "fileList": { + "committedSection": "Auf Branch committet" + }, + "fileRows": { + "addedByThem": "Von ihnen hinzugefügt", + "addedByUs": "Von uns hinzugefügt", + "bothAdded": "Beidseitig hinzugefügt", + "bothDeleted": "Beidseitig gelöscht", + "bothModified": "Beidseitig geändert", + "committedSection": "Auf Branch committet", + "committedUnavailable": "Committete Änderungen nicht verfügbar.", + "deletedByThem": "Von ihnen gelöscht", + "deletedByUs": "Von uns gelöscht", + "discardFile": "Änderungen an {{path}} verwerfen", + "loadingCommitted": "Committete Änderungen werden geladen…", + "openChangedFile": "Geänderte Datei {{path}} öffnen", + "openCommittedChange": "Committete Änderung an {{path}} öffnen", + "renamedFrom": "von {{path}}", + "stageFile": "{{path}} vormerken", + "unresolvedConflict": "Ungelöster Konflikt", + "unstageFile": "Vormerkung für {{path}} aufheben" + }, + "gitHistory": { + "days_one": "{{count}} T.", + "days_other": "{{count}} T.", + "hours_one": "{{count}} Std.", + "hours_other": "{{count}} Std.", + "justNow": "gerade eben", + "loadFailed": "Commit-Verlauf konnte nicht geladen werden.", + "minutes_one": "{{count}} Min.", + "minutes_other": "{{count}} Min.", + "months_one": "{{count}} Mon.", + "months_other": "{{count}} Mon.", + "noCommitMessage": "(keine Commit-Nachricht)", + "years_one": "{{count}} J.", + "years_other": "{{count}} J." + }, + "gitHistoryList": { + "loadFailed": "Verlauf konnte nicht geladen werden.", + "loadFilesFailed": "Commit-Dateien konnten nicht geladen werden.", + "noCommits": "Keine Commits.", + "noFileChanges": "Keine Dateiänderungen", + "retryFiles": "Commit-Dateien erneut laden", + "waitingForDesktop": "Warten auf Desktop…" + }, + "gitStatus": { + "changes": "Änderungen", + "conflicts": "Konflikte", + "stagedChanges": "Vorgemerkte Änderungen" + }, + "header": { + "backToSession": "Zurück zur Sitzung", + "close": "Quellcodeverwaltung schließen", + "openNumberedPrWeb": "Pull Request #{{number}} im Web öffnen", + "openPrWeb": "Pull Request im Web öffnen", + "refresh": "Quellcodeverwaltung aktualisieren", + "title": "Quellcodeverwaltung" + }, "hostedReview": { "mrCopy": { "reviewLabel": "Merge Request", @@ -2588,9 +2757,81 @@ "titleLabel": "Pull Request" } }, + "hostedReviewCopy": { + "committingChanges": "Änderungen werden committet…", + "creatingReview": "Review wird erstellt…", + "forcePushing": "Push mit Lease wird erzwungen…", + "generatingCommitMessage": "Commit-Nachricht wird generiert…", + "publishingBranch": "Branch wird veröffentlicht…", + "pushingCommits": "Commits werden gepusht…", + "stagingChanges": "Änderungen werden vorgemerkt…", + "updatingBranch": "Branch wird aktualisiert…" + }, "hostedReviewCreate": { "pushSucceeded": "Push erfolgreich, aber der {{shortLabel}} konnte nicht erstellt werden: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "Branch wurde während der Vorbereitung des Pull Requests geändert.", + "generateMessageFailed": "Commit-Nachricht konnte nicht generiert werden. In der Quellcodeverwaltung eine hinzufügen und erneut versuchen.", + "resolveConflicts": "Vor dem Erstellen eines Pull Requests Konflikte lösen.", + "resolveOrStageChanges": "Vor dem Erstellen eines Pull Requests Änderungen bereinigen oder vormerken.", + "reviewCommitMessage": "Commit-Nachricht prüfen und anschließend „PR erstellen“ erneut versuchen." + }, + "hostedReviewGitPreparation": { + "commitFailed": "Commit fehlgeschlagen", + "refreshFailed": "Quellcodeverwaltung konnte nicht aktualisiert werden.", + "stageFailed": "Änderungen konnten nicht vorgemerkt werden.", + "updateBranchFailed": "Entfernter Branch konnte nicht aktualisiert werden. „PR erstellen“ erneut versuchen." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "Push mit Lease konnte nicht erzwungen werden.", + "publishFailed": "Branch konnte nicht veröffentlicht werden.", + "pushFailed": "Commits konnten nicht gepusht werden." + }, + "hostedReviewService": { + "createFailed": "Pull Request konnte nicht erstellt werden.", + "pushBeforeCreateFailed": "Push fehlgeschlagen. Den Push-Fehler beheben und erneut versuchen." + }, + "hubTab": { + "changes": "Änderungen", + "commits": "Commits", + "pullRequest": "Pull Request" + }, + "loaders": { + "connectingToDesktop": "Verbindung zum Desktop wird hergestellt…", + "loadFailed": "Quellcodeverwaltung konnte nicht geladen werden.", + "updateDesktop": "Orca auf dem Desktop aktualisieren, um die Quellcodeverwaltung mobil zu nutzen.", + "waitingForDesktop": "Warten auf den Desktop…" + }, + "modals": { + "actionsTitle": "Quellcodeverwaltung", + "currentBranch": "aktuell", + "discardButton": "Verwerfen", + "discardConfirmMessage": "Änderungen an „{{path}}“ verwerfen? Dies kann nicht rückgängig gemacht werden.", + "discardTitle": "Änderung verwerfen?", + "openPrMessage": "Im Browser öffnen?", + "openPrWithWarning": "Im Browser öffnen?\n\n{{warning}}", + "prCreatedTitle": "Pull Request erstellt", + "switchBranchTitle": "Branch wechseln" + }, + "openers": { + "openDiffFailed": "Diff konnte nicht geöffnet werden.", + "tabNotReady": "Die Datei wurde geöffnet, aber ihr Tab ist noch nicht bereit. Erneut versuchen.", + "waitingForDesktop": "Warten auf den Desktop…" + }, + "panel": { + "loadFailedTitle": "Laden fehlgeschlagen", + "unavailableTitle": "Quellcodeverwaltung nicht verfügbar" + }, + "prChip": { + "createPr": "Pull Request erstellen", + "loading": "Pull Request wird geladen…", + "loadingLabel": "Pull Request wird geladen", + "openLabel": "Pull Request #{{number}}, {{state}}, {{checks}}. Pull Request öffnen.", + "openWithComments_one": "Pull Request #{{number}}, {{state}}, {{checks}}, {{count}} ungelöster Kommentar. Pull Request öffnen.", + "openWithComments_other": "Pull Request #{{number}}, {{state}}, {{checks}}, {{count}} ungelöste Kommentare. Pull Request öffnen.", + "unavailableLabel": "Pull Request nicht verfügbar: {{message}}" + }, "prCreate": { "authRequired": "Vor dem Erstellen eines {{reviewLabel}}s ist eine Authentifizierung erforderlich.", "baseNotOnRemote": "Den Basis-Branch pushen, bevor ein {{reviewLabel}} erstellt wird.", @@ -2609,8 +2850,19 @@ "unsupportedMergeRequests": "Das Erstellen von Merge Requests wird für dieses Repo nicht unterstützt.", "unsupportedPullRequests": "Das Erstellen von Pull Requests wird für dieses Repo nicht unterstützt." }, + "prLink": { + "updatePullRequestFailed": "Verknüpfter Pull Request konnte nicht aktualisiert werden.", + "updateReviewFailed": "Verknüpftes Review konnte nicht aktualisiert werden." + }, "primaryAction": { - "forcePushFromDesktop": "Push für den Branch dieses Pull Requests vom Desktop aus erzwingen" + "commit": "Committen", + "forcePush": "Push erzwingen", + "forcePushFromDesktop": "Push für den Branch dieses Pull Requests vom Desktop aus erzwingen", + "publishBranch": "Branch veröffentlichen", + "pull": "Pullen", + "push": "Pushen", + "stageAll": "Alle vormerken", + "sync": "Synchronisieren" }, "remoteDropdown": { "branchAlreadyPublished": "Branch ist bereits veröffentlicht", @@ -2660,6 +2912,591 @@ "tryFastForwardPull": "Pull per Fast-Forward versuchen; git lehnt lokale Commits eventuell ab", "tryRegularPush": "Regulären Push versuchen; git erfordert eventuell einen erzwungenen Push", "useForcePushToSync": "„Push erzwingen“ verwenden – das Remote enthält nur ältere Kopien lokaler Commits" + }, + "runners": { + "actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen" + }, + "screenState": { + "noBranch": "Kein Branch" + }, + "state": { + "noUpstream": "Kein Upstream", + "syncStatus": "{{ahead}} voraus, {{behind}} zurück" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Agent konnte nicht gestartet werden.", + "waitingForDesktop": "Warten auf den Desktop…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Commit-Nachricht konnte nicht generiert werden." + }, + "useMobileCreatePrRunner": { + "branchRequired": "Vor dem Erstellen eines Pull Requests einen Branch auschecken." + }, + "useMobileGitRequests": { + "actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen", + "branchUnavailable": "Branch-Status nicht verfügbar", + "commitFailed": "Commit fehlgeschlagen", + "waitingForDesktop": "Warten auf den Desktop…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "Der Basis-Branch konnte nicht ermittelt werden.", + "forkPushWarning": "Bei diesem PR ist „Allow edits from maintainers“ deaktiviert; GitHub könnte einen Push zum Fork ablehnen." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Kommentar hinzufügen", + "comments_one": "{{count}} Kommentar", + "comments_other": "{{count}} Kommentare", + "reopenThread": "Thread wieder öffnen", + "reply": "Antworten", + "resolveThread": "Thread als erledigt markieren", + "resolvedCommentBy": "Erledigter Kommentar von {{author}}", + "resolvedThreadBy": "Erledigter Thread von {{author}}", + "sendComment": "Kommentar senden", + "show": "Anzeigen" + }, + "filterPickers": { + "allTeams": "Alle Teams", + "changeStatus": "Status ändern", + "fieldHidden": "Auf Karten ausgeblendet", + "fieldShown": "Auf Karten angezeigt", + "fieldsSubtitle": "Auswählen, welche Projektfelder auf Eintragskarten angezeigt werden.", + "fieldsTitle": "Projektfelder", + "gitlabFilter": "GitLab-Filter", + "gitlabView": "GitLab-Ansicht", + "jiraFilter": "Jira-Filter", + "jiraSite": "Jira-Site", + "linearFilter": "Linear-Filter", + "linearIssue": "Linear-Issue", + "linearWorkspace": "Linear-Arbeitsbereich", + "loadingStates": "Statusoptionen werden geladen…", + "noFields": "Diese Ansicht enthält keine zusätzlichen Felder.", + "noStates": "Keine Statusoptionen verfügbar", + "switchWorkspaceFailed": "Arbeitsbereich konnte nicht gewechselt werden.", + "teamsSubtitle": "Auswählen, welche Teams unter „Aufgaben“ angezeigt werden.", + "teamsTitle": "Linear-Teams", + "teams_one": "{{count}} Team", + "teams_other": "{{count}} Teams" + }, + "githubProjectList": { + "browseProjects": "Projekte durchsuchen", + "chooseProject": "GitHub-Projekt auswählen", + "emptyField": "Leer", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "Projekteintrag · {{repository}}{{number}}", + "items": "Einträge", + "moreFields_one": "+{{count}} Feld", + "moreFields_other": "+{{count}} Felder", + "noItems": "Keine Projekteinträge", + "pullRequestSubtitle": "Pull Request · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Hinzufügen", + "addByUrlHint": "Fehlende Projekte lassen sich per URL hinzufügen.", + "addPlaceholder": "Per URL oder owner/number hinzufügen", + "adding": "Wird hinzugefügt…", + "browseAll": "Alle durchsuchen", + "browseLoading": "Alle durchsuchen (wird geladen…)", + "chooseView": "Projektansicht auswählen", + "loadFailed": "Laden der Projekte fehlgeschlagen", + "noMatches": "Keine passenden Projekte.", + "noMoreProjects": "Keine weiteren Projekte.", + "noProjects": "Keine Projekte geladen", + "organizationsError": "Organisationen: {{message}}", + "organizationsLoadFailed": "Einige Organisationen konnten nicht geladen werden ({{count}}).", + "ownerLoadFailed": "Projekte von {{owner}} konnten nicht geladen werden.", + "pin": "Anheften", + "pinned": "Angeheftet", + "recent": "Zuletzt verwendet", + "retryHint": "Zum Wiederholen tippen.", + "searchProjects": "Projekte suchen", + "sort": "Projektsortierung", + "subtitle": "Eine Projektansicht für die Seite „Aufgaben“ auswählen.", + "title": "GitHub Projects", + "unsupportedLayout": "Orca unterstützt dieses Layout in GitHub Projects noch nicht.", + "view": "Projektansicht" + }, + "githubViewControls": { + "fields": "Felder: {{fields}}", + "openView": "Ansicht in GitHub öffnen", + "sort": "Sortierung: {{sort}}", + "source": "Quelle: {{source}}" + }, + "itemActions": { + "changeStatus": "Status ändern", + "copyGitHubLink": "GitHub-Link kopieren", + "copyLinearLink": "Linear-Link kopieren", + "createWorkspace": "Arbeitsbereich erstellen", + "creating": "Wird erstellt…", + "mergeConflicts": "GitHub meldet Merge-Konflikte.", + "mergeMergeRequest": "Merge Request mergen", + "mergePullRequest": "Pull Request mergen" + }, + "itemDetailContent": { + "addSubIssue": "Unter-Issue hinzufügen", + "assignee": "Zuständige Person", + "assignees": "Zuständige Personen", + "checks": "Checks", + "description": "Beschreibung", + "discussion": "Diskussion", + "noChecks": "Keine Checks gefunden.", + "noComments": "Keine Kommentare.", + "noPipelineRuns": "Keine Pipeline-Ausführungen für diesen MR.", + "noSubIssues": "Keine untergeordneten Issues.", + "none": "Keine", + "pipeline": "Pipeline", + "pipelineJobs_one": "{{count}} Job", + "pipelineJobs_other": "{{count}} Jobs", + "project": "Projekt", + "rerunAll": "Alle erneut ausführen", + "rerunFailed": "Fehlgeschlagene erneut ausführen", + "status": "Status", + "subIssueTitle": "Titel des Unter-Issues", + "subIssues": "Untergeordnete Issues", + "type": "Typ" + }, + "itemDetailDrawer": { + "refreshDetails": "Details aktualisieren" + }, + "itemFieldEditors": { + "addLabels": "Labels hinzufügen, kommagetrennt", + "addUsernames": "Benutzernamen hinzufügen, kommagetrennt", + "assignees": "Zuständige Personen", + "labels": "Labels", + "loadingAssignees": "Zuständige Personen werden geladen…", + "loadingLabels": "Labels werden geladen…", + "noAssignableUsers": "Keine zuweisbaren Benutzer für dieses Repository gefunden.", + "noLabels": "Keine Labels in diesem Repository.", + "none": "Keine", + "removeLabels": "Labels entfernen, kommagetrennt", + "removeUsernames": "Benutzernamen entfernen, kommagetrennt", + "saveTitle": "Titel speichern", + "title": "Titel", + "updateAssignees": "Zuständige Personen aktualisieren", + "updateLabels": "Labels aktualisieren" + }, + "itemReviewSections": { + "binaryFile": "Binärdatei.", + "changedFilesTitle": "Geänderte Dateien", + "descriptionPlaceholder": "Beschreibung", + "fileContentsUnavailable": "Dateiinhalt nicht verfügbar.", + "hideFile": "Ausblenden", + "loadingReviewers": "Prüfer werden geladen…", + "markUnviewed": "Als nicht angesehen markieren", + "markViewed": "Als angesehen markieren", + "noDescription": "Keine Beschreibung.", + "noReviewerSuggestions": "Keine Vorschläge für Prüfer gefunden.", + "noReviewersRequested": "Keine Prüfer angefordert.", + "requestReview": "Review anfordern", + "reviewersPlaceholder": "Prüfer anfordern", + "reviewersTitle": "Prüfer", + "saveDescription": "Beschreibung speichern", + "viewFile": "Anzeigen" + }, + "legacySurface": { + "loadIssuesFailed": "Issues aus {{source}} konnten nicht geladen werden.", + "mergeAction": "Mergen", + "mergeMethodTitle": "Merge-Methode", + "mergePullRequestTitle": "Pull Request mergen?", + "mergeRequestMergeMessage": "Auswählen, wie dieser Merge Request gemergt werden soll.", + "mergeRequestTitle": "Merge Request mergen?", + "pullRequestMergeMessage": "Auswählen, wie dieser Pull Request gemergt werden soll.", + "retryLoadingIssues": "Issues aus {{source}} erneut laden", + "retrying": "Erneuter Versuch…", + "sourceFallback": "Die bevorzugte Issue-Quelle upstream ist für {{repo}} nicht verfügbar. Stattdessen wird origin verwendet.", + "subIssueDataUnavailable": "Daten zu untergeordneten Issues sind für diesen Token nicht verfügbar.", + "updateItemTitle": "Eintrag aktualisieren?" + }, + "linearList": { + "changeStatusFrom": "Status ändern (aktuell: {{status}})" + }, + "linearViewControls": { + "displayButton": "Anzeige", + "groupLabel": "Gruppierung: {{group}}", + "orderLabel": "Sortierung: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Angezeigte Eigenschaften", + "linearGroupTitle": "Linear-Issues gruppieren", + "linearOrderTitle": "Linear-Issues sortieren", + "linearViewTitle": "Linear-Ansicht", + "sortTasksTitle": "Aufgaben sortieren" + }, + "listSurface": { + "connectLinearButton": "Linear verbinden", + "connectLinearMessage": "Dir zugewiesene Linear-Issues direkt unter „Aufgaben“ durchsuchen und die Arbeit daran starten.", + "connectLinearTitle": "Linear-Konto verbinden", + "jiraStatusFailed": "Jira-Status konnte nicht gelesen werden.", + "updateDesktopMessage": "Diese mobile Aufgabenansicht benötigt eine neuere Version von Orca auf dem Desktop.", + "updateDesktopTitle": "Orca-Desktop-App aktualisieren" + }, + "options": { + "all": "Alle", + "assignedToMe": "Mir zugewiesen", + "assignee": "Zuständige Person", + "board": "Board", + "boardDescription": "Gruppierte Spalten", + "closedState": "Geschlossen", + "completedState": "Abgeschlossen", + "createdState": "Erstellt", + "githubAssignedIssuesDescription": "Offene Issues, die dir zugewiesen sind", + "githubDescription": "Issues und Pull Requests", + "githubIssuesDescription": "GitHub-Issues", + "githubOpenIssuesDescription": "Offene GitHub-Issues", + "githubProjectsDescription": "Ansichten in GitHub Projects", + "githubPullRequestsDescription": "GitHub-Pull-Requests", + "gitlabAllDescription": "Alle GitLab-Status", + "gitlabClosedDescription": "Geschlossene Issues und Merge Requests", + "gitlabDescription": "Issues und Merge Requests", + "gitlabMergedDescription": "Gemergte Merge Requests", + "gitlabOpenDescription": "Offene Issues und Merge Requests", + "identifier": "Kennung", + "issues": "Issues", + "jiraDescription": "Zugewiesene und gemeldete Issues", + "labels": "Labels", + "linearAllDescription": "Offene Issues aus verbundenen Arbeitsbereichen", + "linearAssignedDescription": "Dir zugewiesene Issues", + "linearCompletedDescription": "Kürzlich abgeschlossene Issues", + "linearCreatedDescription": "Von dir erstellte Issues", + "linearDescription": "Zugewiesene Issues und Team-Issues", + "list": "Liste", + "listDescription": "Kompakte Issue-Zeilen", + "mergedState": "Gemergt", + "mine": "Eigene", + "myIssues": "Meine Issues", + "myPullRequestsDescription": "Selbst erstellte Pull Requests", + "myTodos": "Meine To-dos", + "myTodosDescription": "Ausstehende GitLab-To-dos", + "needsReview": "Review erforderlich", + "noGrouping": "Keine Gruppierung", + "openPullRequestsDescription": "Offene Pull Requests", + "openState": "Offen", + "priority": "Priorität", + "projectMergeRequests": "Projekt-MRs", + "projectMergeRequestsDescription": "Merge Requests und Issues nach Repository", + "projects": "Projekte", + "pullRequests": "PRs", + "repository": "Repository", + "repositorySortDescription": "Nach Repository gruppieren, dann neueste Aktivität zuerst", + "reviewRequestsDescription": "Review-Anfragen, die dir zugewiesen sind", + "status": "Status", + "team": "Team", + "updated": "Aktualisiert", + "updatedSortDescription": "Neueste Aktivität zuerst" + }, + "pickerProjection": { + "allRepos": "Alle Repos", + "allSites": "Alle Websites", + "currentlyAscending": "Aktuell aufsteigend · für absteigende Sortierung tippen", + "currentlyDescending": "Aktuell absteigend · für aufsteigende Sortierung tippen", + "fieldAscending": "{{field}} aufsteigend", + "fieldDescending": "{{field}} absteigend", + "fields": "Felder", + "repos_one": "{{count}} Repo", + "repos_other": "{{count}} Repos", + "selectTarget": "Ziel auswählen", + "selectedFields": "{{selected}}/{{total}} Felder", + "sortAscending": "Aufsteigend sortieren", + "sources_one": "{{count}} Quelle", + "sources_other": "{{count}} Quellen", + "unsupportedLayout": "Layout auf Mobilgeräten nicht unterstützt", + "updatedSort": "Aktualisiert", + "usesFieldAscending": "Nach {{field}} aufsteigend sortiert", + "usesFieldDescending": "Nach {{field}} absteigend sortiert", + "usesGitHubRankOrder": "Verwendet die GitHub-Rangfolge", + "viewNumber": "Ansicht #{{number}}", + "viewOrder": "Reihenfolge der Ansicht" + }, + "prFileDiff": { + "commentOnLine": "Zeile {{line}} kommentieren", + "commentPlaceholder": "Review-Kommentar hinzufügen", + "noTextChanges": "Keine Textänderungen gefunden.", + "showingDiffLines": "Die ersten {{limit}} von {{total}} Diff-Zeilen werden angezeigt." + }, + "projectComments": { + "comments_one": "{{count}} Kommentar", + "comments_other": "{{count}} Kommentare", + "discussion": "Diskussion", + "editComment": "Kommentar bearbeiten", + "noComments": "Keine Kommentare.", + "reopenThread": "Thread erneut öffnen", + "reply": "Antworten", + "resolveThread": "Thread als erledigt markieren", + "resolvedCommentBy": "Erledigter Kommentar von {{author}}", + "resolvedThreadBy": "Erledigter Thread von {{author}}", + "show": "Anzeigen" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} wurde Orca noch nicht hinzugefügt. Das Repository in der Desktop-App hinzufügen und anschließend die Aufgaben in der mobilen App aktualisieren.", + "clearType": "Typ entfernen", + "closeItem": "Eintrag schließen", + "copyGitHubLink": "GitHub-Link kopieren", + "copyRepository": "Repository kopieren", + "createWorkspace": "Arbeitsbereich erstellen", + "draftIssue": "Issue-Entwurf", + "issue": "Issue", + "issueType": "Issue-Typ", + "loadingIssueTypes": "Issue-Typen werden geladen…", + "mergePullRequest": "Pull Request mergen", + "mergeRepositoryRequirement": "Für den Merge muss dieses Repository in Orca vorhanden sein.", + "noIssueTypes": "Für dieses Repository sind keine Issue-Typen konfiguriert.", + "noType": "Kein Typ", + "openInGitHub": "In GitHub öffnen", + "projectItem": "Projekteintrag", + "projectSubtitle": "GitHub-Projekt · {{repository}}{{itemNumber}}", + "pullRequest": "Pull Request", + "reopenItem": "Eintrag erneut öffnen", + "repositoryNotInOrca": "Repository nicht in Orca", + "status": "Status", + "type": "Typ", + "workspaceCreationRequirement": "Arbeitsbereiche können nur aus GitHub-Issues und Pull Requests erstellt werden." + }, + "projectFieldEditors": { + "clearField": "Feld leeren", + "completedIteration": "Abgeschlossen · {{startDate}} · {{duration}} T.", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "Ein Datum im Format YYYY-MM-DD eingeben.", + "invalidNumber": "Eine gültige Zahl eingeben.", + "noIterations": "Keine Iterationen verfügbar.", + "numberPlaceholder": "Zahl", + "projectFields": "Projektfelder", + "saveField": "Feld speichern", + "textPlaceholder": "Text", + "upcomingIteration": "Aktuell & anstehend · {{startDate}} · {{duration}} T." + }, + "projectMetadataEditors": { + "assignees": "Zuständige Personen", + "description": "Beschreibung", + "labels": "Labels", + "loadingAssignees": "Zuständige Personen werden geladen…", + "loadingLabels": "Labels werden geladen…", + "noAssignableUsers": "Keine zuweisbaren Benutzer für dieses Repository gefunden.", + "noDescription": "Keine Beschreibung.", + "noLabels": "Keine Labels in diesem Repository.", + "none": "Keine", + "saveDescription": "Beschreibung speichern", + "saveTitle": "Titel speichern", + "title": "Titel" + }, + "projectReviewPanels": { + "binaryFile": "Binärdatei.", + "changedFiles": "Geänderte Dateien", + "checks": "Checks", + "fileUnavailable": "Dateiinhalt nicht verfügbar.", + "hideFile": "Ausblenden", + "loadingReviewers": "Prüfer werden geladen…", + "markUnviewed": "Als nicht angesehen markieren", + "markViewed": "Als angesehen markieren", + "noChecks": "Keine Checks gefunden.", + "noReviewers": "Keine Prüfer angefordert.", + "noSuggestions": "Keine Prüfervorschläge gefunden.", + "requestReview": "Review anfordern", + "requestReviewers": "Prüfer anfordern", + "rerunAll": "Alle erneut ausführen", + "rerunFailed": "Fehlgeschlagene erneut ausführen", + "reviewers": "Prüfer", + "viewFile": "Anzeigen" + }, + "providerControls": { + "myTodos": "Meine To-dos", + "projectMergeRequests": "Projekt-MRs", + "sort": "Sortierung: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "in {{base}}", + "nextPage": "Nächste Seite", + "page": "Seite {{page}}", + "pageOfTotal": "Seite {{page}} von {{total}}", + "previousPage": "Vorherige Seite", + "selectPage": "Seite auswählen, Seite {{page}}", + "selectPageOfTotal": "Seite auswählen, Seite {{page}} von {{total}}" + }, + "providerPickers": { + "allRepositories": "Alle Repositorys", + "githubView": "GitHub-Ansicht", + "issueSources": "GitHub-Issue-Quellen", + "issueSourcesDescription": "Für jedes Repository auswählen, ob upstream oder origin für das Abfragen und Erstellen von Issues verwendet wird.", + "issues": "Issues", + "noIssueSources": "Keine alternativen Issue-Quellen verfügbar.", + "origin": "Origin", + "pageHint": "Zu einer geladenen oder verfügbaren Ergebnisseite wechseln.", + "pageLoaded": "Geladen", + "pageNotLoaded": "Lädt ältere Ergebnisse", + "pageNumber": "Seite {{page}}", + "pages": "GitHub-Seiten", + "pullRequests": "Pull Requests", + "queryingSource": "Abfrage von {{source}}", + "repoDescription": "Abzufragende Repositorys auswählen.", + "repos": "Repositorys", + "taskSource": "Aufgabenquelle", + "upstream": "Upstream" + }, + "providerViewProjection": { + "all": "Alle", + "allSites": "Alle Websites", + "allTeams": "Alle Teams", + "allWorkspaces": "Alle Arbeitsbereiche", + "chooseProject": "Projekt auswählen", + "default": "Standard", + "defaultSubtitle": "{{subtitle}} · Standard", + "issues": "Issues", + "list": "Liste", + "noGrouping": "Keine Gruppierung", + "openState": "Offen", + "priority": "Priorität", + "projects": "Projekte", + "pullRequests": "PRs", + "teams_one": "{{count}} Team", + "teams_other": "{{count}} Teams", + "workspace": "Arbeitsbereich" + }, + "reviewerLinear": { + "issues": "Issues", + "unassigned": "Nicht zugewiesen" + }, + "screenChrome": { + "connectLinear": "Linear verbinden", + "newGitHubIssue": "Neues GitHub-Issue", + "newLinearIssue": "Neues Linear-Issue", + "refreshGitHub": "GitHub-Aufgaben aktualisieren", + "refreshGitLab": "GitLab-Arbeitselemente aktualisieren", + "refreshJira": "Jira-Issues aktualisieren", + "refreshLinear": "Linear aktualisieren", + "title": "Aufgaben" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL, z. B. project = ABC AND statusCategory != Done", + "projectPlaceholder": "Projektansicht durchsuchen…", + "providerPlaceholder": "{{provider}}-Aufgaben suchen…" + }, + "smartSourceModes": { + "allStates": "Alle", + "branch": "Branch", + "closedState": "Geschlossen", + "mergedState": "Gemergt", + "name": "Name", + "openState": "Offen", + "smart": "Intelligent" + }, + "sparsePresetDraft": { + "directoryRequired": "Mindestens ein Verzeichnis hinzufügen.", + "repoRelativeDirectoriesRequired": "Verzeichnisse relativ zum Repo verwenden, keine Stammverzeichnisse, absoluten Pfade oder Pfadsegmente für übergeordnete Verzeichnisse." + }, + "taskViewOptions": { + "allSubtitle": "Ungelöste Issues auf den ausgewählten Sites", + "assignedSubtitle": "Dir zugewiesene ungelöste Issues", + "doneSubtitle": "Eigene kürzlich gelöste Issues", + "noGitHubTasks": "Keine GitHub-Aufgaben", + "noGitLabTasks": "Keine GitLab-Aufgaben", + "noJiraTasks": "Keine Jira-Aufgaben", + "noLinearTasks": "Keine Linear-Aufgaben", + "reportedSubtitle": "Von dir gemeldete ungelöste Issues" + }, + "tasksCreateDrawers": { + "connect": "Verbinden", + "connectLinearWorkspace": "Linear-Arbeitsbereich verbinden", + "createIssue": "Issue erstellen", + "createWorkspaceIn": "Arbeitsbereich im Repository erstellen", + "description": "Beschreibung", + "descriptionPlaceholder": "Kontext hinzufügen", + "fileIn": "In {{slug}} erstellen", + "issueSource": "Issue-Quelle", + "keySecurityHint": "Der Schlüssel wird über den Schlüsselbund des Host-Betriebssystems verschlüsselt und lokal gespeichert.", + "linearConnectSubtitle": "Persönlichen API-Schlüssel einfügen, um Issues aus diesem Arbeitsbereich anzuzeigen.", + "linearSettingsLink": "Linear Settings / Security / New API key", + "linearTeam": "Linear-Team", + "linearTeamSubtitle": "Issue im ausgewählten Linear-Team erstellen.", + "newIssueTitle": "Neues {{providerLabel}}-Issue", + "origin": "Origin", + "personalApiKey": "Persönlicher API-Schlüssel", + "repository": "Repository", + "repositorySubtitle": "Issue im ausgewählten Repository erstellen.", + "team": "Team", + "title": "Titel", + "titlePlaceholder": "Aufgabentitel", + "upstream": "Upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "Leeres Terminal" + }, + "workspaceCreateDrawer": { + "addRepository": "Vor dem Erstellen eines Linear-Arbeitsbereichs ein Git-Repository hinzufügen.", + "advanced": "Erweitert", + "agent": "Agent", + "connect": "Verbinden", + "connectFirst": "Zuerst Repository verbinden", + "connectRepository": "Repository verbinden", + "connecting": "Verbindung wird hergestellt…", + "createFrom": "Aus {{branch}} erstellen", + "defaultBranch": "Standard-Branch", + "detectingAgents": "Agenten werden erkannt…", + "optional": "[Optional]", + "remoteRepository": "Entferntes Repository", + "repository": "Repository", + "repositoryNotFound": "Repository nicht gefunden.", + "selectRepository": "Repository auswählen", + "sshConnection": "SSH-Verbindung", + "startFrom": "Ausgangspunkt", + "title": "Arbeitsbereich erstellen", + "workspaceName": "Arbeitsbereichsname" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "„{{name}}“ ist bereits vorhanden.", + "nameRequired": "Ein Name ist erforderlich.", + "nameTooLong": "Der Name darf höchstens 80 Zeichen lang sein.", + "openShell": "Shell öffnen" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Vorhandenen Branch oder Ref auswählen.", + "baseBranchTitle": "Ausgangspunkt", + "branchName": "Branch-Name: {{name}}", + "defaultBranch": "Standard-Branch", + "defaultBranchSubtitle": "Konfigurierten Basis-Branch des Repositorys verwenden", + "editPreset": "{{name}} bearbeiten", + "fullCheckout": "Vollständiger Checkout", + "fullCheckoutSubtitle": "Gesamtes Repository verwenden", + "newPreset": "Voreinstellung erstellen", + "noBranches": "Keine passenden Branches.", + "searchBranches": "Branches suchen", + "sparseCheckoutTitle": "Partieller Checkout" + }, + "workspaceSshGate": { + "authenticationFailed": "Authentifizierung fehlgeschlagen", + "connected": "Verbunden", + "connecting": "Verbindung wird hergestellt", + "connectionFailed": "Verbindung fehlgeschlagen", + "deployingRelay": "Relay wird bereitgestellt", + "disconnected": "Getrennt", + "reconnectFailed": "Erneute Verbindung fehlgeschlagen", + "reconnecting": "Wird erneut verbunden" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Immer vertrauen und ausführen", + "creating": "Wird erstellt…", + "directoriesLabel": "Verzeichnisse", + "directories_one": "{{count}} Verzeichnis", + "directories_other": "{{count}} Verzeichnisse", + "dontRun": "Nicht ausführen", + "editSparsePreset": "Voreinstellung für partiellen Checkout bearbeiten", + "nameLabel": "Name", + "namePlaceholder": "Renderer-Oberfläche", + "newSetupScript": "Neues Einrichtungsskript", + "newSparsePreset": "Neue Voreinstellung für partiellen Checkout", + "runHooks": "Hooks ausführen", + "runSetupAndCreate": "Einrichten und erstellen", + "runSetupTitle": "Einrichtung von {{name}} ausführen?", + "setupChangedTitle": "Einrichtungsskript von {{name}} geändert", + "setupScript": "Einrichtungsskript", + "setupSubtitle": "Für {{name}} muss vor dem Erstellen dieses Arbeitsbereichs eine Einrichtungsoption gewählt werden.", + "setupTitle": "Einrichtungsskript ausführen?", + "skipSetupAndCreate": "Ohne Einrichtung erstellen", + "trustFailed": "Das Einrichtungsskript konnte nicht als vertrauenswürdig markiert werden.", + "trustSubtitle": "Die orca.yaml dieses Repositorys wird vor dem Start des Arbeitsbereichs auf deinem Rechner ausgeführt. Nur ausführen, wenn du diesem Repository vertraust." + }, + "worktreeCreateRetry": { + "createFailed": "Arbeitsbereich konnte nicht erstellt werden." } }, "terminal": { diff --git a/mobile/src/i18n/locales/en.json b/mobile/src/i18n/locales/en.json index cb3cce6ff0d..74af82f4346 100644 --- a/mobile/src/i18n/locales/en.json +++ b/mobile/src/i18n/locales/en.json @@ -695,6 +695,10 @@ "suppressWhileFocused": "Suppress while focused", "suppressWhileFocusedHint": "Skip alerts for the workspace open on this phone.", "footer": "Alert types follow each paired desktop’s notification settings. Notifications pause after 7 days without using this app; open it and reconnect to resume." + }, + "desktopChannel": { + "silentName": "Orca silent notifications", + "name": "Desktop Notifications" } }, "onboarding": { @@ -2622,7 +2626,11 @@ "enterMessage": "Enter a commit message to commit" }, "createPrAction": { - "createReview": "Create {{titleLabel}}" + "createReview": "Create {{titleLabel}}", + "createPullRequest": "Create Pull Request", + "statusUnavailable": "Review status unavailable", + "checkingStatus": "Checking review status…", + "providerUnavailable": "Review creation unavailable for this provider" }, "prCreate": { "notReady": "This branch is not ready for a {{reviewLabel}} yet.", @@ -2698,7 +2706,29 @@ "createPr": "Create PR", "pushAndCreatePr": "Push & Create PR", "switchBranch": "Switch branch", - "commits": "Commits" + "commits": "Commits", + "committing": "Commit in progress.", + "forcePushing": "Force push in progress.", + "remoteOperationInProgress": "Remote operation in progress.", + "waitForRemoteOperation": "Try again once the remote operation finishes.", + "resolveConflicts": "Resolve conflicts before committing.", + "commitStagedChanges": "Commit staged changes.", + "enterCommitMessage": "Enter a commit message to commit.", + "stageAllChanges": "Stage all changes.", + "stageFileToCommit": "Stage at least one file to commit.", + "checkoutBeforePublish": "Check out a branch before publishing commits.", + "checkingReviewStatus": "Checking review status.", + "reviewAlreadyMerged": "Nothing to commit. The review is already merged.", + "publishToOrigin": "Publish this branch to origin.", + "pushLinkedReview": "Push updates to the linked review branch.", + "linkedReviewUnavailable": "The linked review branch is unavailable.", + "forcePushWithLease": "Force push with lease to update the remote branch.", + "syncCounts": "Pull {{behind}}, push {{ahead}}.", + "pullCommits_one": "Pull {{count}} commit.", + "pullCommits_other": "Pull {{count}} commits.", + "pushCommits_one": "Push {{count}} commit.", + "pushCommits_other": "Push {{count}} commits.", + "upToDate": "Nothing to commit. Branch is up to date." }, "dropdownCounts": { "pushCount_one": "Push {{count}} commit", @@ -2721,7 +2751,814 @@ "titleUnpublishedForcePushCount_other": "Force push {{count}} branch commits with lease and set an upstream if needed." }, "primaryAction": { - "forcePushFromDesktop": "Force push this pull request's branch from desktop" + "forcePushFromDesktop": "Force push this pull request's branch from desktop", + "forcePush": "Force Push", + "commit": "Commit", + "stageAll": "Stage All", + "push": "Push", + "pull": "Pull", + "sync": "Sync", + "publishBranch": "Publish Branch" + }, + "branchDiffPreviewDrawer": { + "committedOnBranch": "Committed on branch", + "closePreview": "Close committed diff preview", + "loadFailed": "Unable to Load Diff", + "truncated": "Diff truncated for mobile preview." + }, + "commitFailurePanel": { + "title": "Commit failed", + "summary": "Commit failed.", + "fixWithAi": "Fix commit failure with AI", + "fix": "Fix", + "hideFailureDetails": "Hide commit failure details", + "showFailureDetails": "Show commit failure details", + "hideDetails": "Hide details", + "showDetails": "Show details" + }, + "gitHistoryList": { + "loadFailed": "Failed to load history", + "loadFilesFailed": "Unable to load commit files", + "retryFiles": "Retry commit files", + "waitingForDesktop": "Waiting for desktop...", + "noFileChanges": "No file changes", + "noCommits": "No commits." + }, + "branchCard": { + "mergeState": "merge", + "rebaseState": "rebase", + "cherryPickState": "cherry-pick", + "changedCount": "{{count}} changed", + "stagedCount": "{{count}} staged", + "branchCount": "{{count}} on branch" + }, + "content": { + "reconnecting": "Reconnecting to desktop...", + "stageAll": "Stage All", + "unstageAll": "Unstage All", + "openActions": "Open source control actions", + "emptyTitle": "No local changes", + "emptyMessage": "Working tree is clean.", + "commitMessageDisabled": "Commit message disabled. No staged files.", + "noStagedFiles": "No staged files", + "commitMessagePlaceholder": "Commit message", + "regenerateHint": "Clear the message to regenerate.", + "cancelGeneration": "Cancel commit message generation", + "generateMessage": "Generate commit message with AI" + }, + "fileList": { + "committedSection": "Committed on Branch" + }, + "fileRows": { + "bothModified": "Both modified", + "bothAdded": "Both added", + "deletedByUs": "Deleted by us", + "deletedByThem": "Deleted by them", + "addedByUs": "Added by us", + "addedByThem": "Added by them", + "bothDeleted": "Both deleted", + "unresolvedConflict": "Unresolved conflict", + "openChangedFile": "Open changed file {{path}}", + "renamedFrom": "from {{path}}", + "unstageFile": "Unstage {{path}}", + "stageFile": "Stage {{path}}", + "discardFile": "Discard {{path}}", + "committedSection": "Committed on Branch", + "loadingCommitted": "Loading committed changes...", + "committedUnavailable": "Committed changes unavailable.", + "openCommittedChange": "Open committed change {{path}}" + }, + "header": { + "close": "Close source control", + "backToSession": "Back to session", + "title": "Source Control", + "openNumberedPrWeb": "Open pull request #{{number}} on the web", + "openPrWeb": "Open pull request on the web", + "refresh": "Refresh source control" + }, + "modals": { + "actionsTitle": "Source Control", + "discardTitle": "Discard Change", + "discardConfirmMessage": "Discard changes to \"{{path}}\"? This cannot be undone.", + "discardButton": "Discard", + "switchBranchTitle": "Switch Branch", + "currentBranch": "current", + "prCreatedTitle": "Pull Request Created", + "openPrWithWarning": "Open it in your browser?\n\n{{warning}}", + "openPrMessage": "Open it in your browser?" + }, + "panel": { + "unavailableTitle": "Source Control Unavailable", + "loadFailedTitle": "Unable to Load" + }, + "prChip": { + "loading": "Loading pull request…", + "createPr": "Create pull request", + "loadingLabel": "Loading pull request", + "unavailableLabel": "Pull request unavailable: {{message}}", + "openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.", + "openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.", + "openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Open pull request." + }, + "hostedReviewCopy": { + "updatingBranch": "Updating branch...", + "stagingChanges": "Staging changes...", + "generatingCommitMessage": "Generating commit message...", + "committingChanges": "Committing changes...", + "publishingBranch": "Publishing branch...", + "pushingCommits": "Pushing commits...", + "forcePushing": "Force pushing with lease...", + "creatingReview": "Creating review..." + }, + "branchBaseRef": { + "resolveFailed": "Unable to resolve branch base" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Unable to resolve the base branch for comparison.", + "loadFailed": "Unable to load committed changes" + }, + "branchCompare": { + "sectionTitle": "Committed on Branch", + "summary": "{{files}} - vs {{baseRef}}", + "summaryWithCommits": "{{files}} - {{commits}} - vs {{baseRef}}", + "files_one": "{{count}} file", + "files_other": "{{count}} files", + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commits" + }, + "commitMessageAi": { + "generateFailed": "Failed to generate commit message" + }, + "gitHistory": { + "justNow": "just now", + "minutes_one": "{{count}}m", + "minutes_other": "{{count}}m", + "hours_one": "{{count}}h", + "hours_other": "{{count}}h", + "days_one": "{{count}}d", + "days_other": "{{count}}d", + "months_one": "{{count}}mo", + "months_other": "{{count}}mo", + "years_one": "{{count}}y", + "years_other": "{{count}}y", + "noCommitMessage": "(no commit message)", + "loadFailed": "Failed to load commit history" + }, + "gitStatus": { + "conflicts": "Conflicts", + "changes": "Changes", + "stagedChanges": "Staged Changes" + }, + "hostedReviewCreateIntent": { + "resolveConflicts": "Resolve conflicts before creating a pull request.", + "branchChanged": "Branch changed while preparing the pull request.", + "resolveOrStageChanges": "Resolve or stage changes before creating a pull request.", + "generateMessageFailed": "Could not generate a commit message. Add one in Source Control, then retry.", + "reviewCommitMessage": "Review the commit message, then retry Create PR." + }, + "hostedReviewGitPreparation": { + "refreshFailed": "Unable to refresh source control", + "updateBranchFailed": "Could not update the remote branch. Retry Create PR.", + "stageFailed": "Failed to stage changes", + "commitFailed": "Commit failed" + }, + "hostedReviewRemotePrerequisite": { + "publishFailed": "Failed to publish branch", + "pushFailed": "Failed to push commits", + "forcePushFailed": "Failed to force push with lease" + }, + "hostedReviewService": { + "pushBeforeCreateFailed": "Push failed. Resolve the push error, then try again.", + "createFailed": "Failed to create pull request" + }, + "prLink": { + "updatePullRequestFailed": "Failed to update linked pull request", + "updateReviewFailed": "Failed to update linked review" + }, + "conflictAbort": { + "aborting": "Aborting…", + "abortMerge": "Abort merge", + "abortRebase": "Abort rebase", + "abortOperation": "Abort {{operation}}" + }, + "hubTab": { + "changes": "Changes", + "pullRequest": "Pull Request", + "commits": "Commits" + }, + "screenState": { + "noBranch": "No branch" + }, + "useMobileCommitFailureRecovery": { + "waitingForDesktop": "Waiting for desktop...", + "launchFailed": "Failed to launch agent" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Failed to generate commit message" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Check out a branch before creating a pull request." + }, + "useMobileGitRequests": { + "waitingForDesktop": "Waiting for desktop...", + "actionFailed": "Source control action failed", + "commitFailed": "Commit failed", + "branchUnavailable": "Branch status unavailable" + }, + "actionSheetRunners": { + "waitingForDesktop": "Waiting for desktop...", + "noBaseBranch": "No base branch to rebase onto" + }, + "commitRunners": { + "commitFailed": "Commit failed", + "actionFailed": "Source control action failed" + }, + "loaders": { + "connectingToDesktop": "Connecting to desktop...", + "waitingForDesktop": "Waiting for desktop...", + "updateDesktop": "Update Orca desktop to use Source Control on mobile.", + "loadFailed": "Unable to load source control" + }, + "openers": { + "waitingForDesktop": "Waiting for desktop...", + "openDiffFailed": "Unable to open diff", + "tabNotReady": "The file opened, but its tab isn't ready yet. Try again." + }, + "runners": { + "actionFailed": "Source control action failed" + }, + "state": { + "syncStatus": "{{ahead}} ahead, {{behind}} behind", + "noUpstream": "No upstream" + } + }, + "newWorkspace": { + "hostPicker": { + "title": "Create Workspace On" + }, + "loadingDrawer": { + "loading": "Loading", + "downloading": "Downloading", + "downloadProgress": "Downloading… {{progress}}" + } + }, + "tasks": { + "legacySurface": { + "sourceFallback": "Preferred issue source upstream is unavailable for {{repo}}. Using origin.", + "loadIssuesFailed": "Couldn't load issues from {{source}}.", + "retryLoadingIssues": "Retry loading issues from {{source}}", + "retrying": "Retrying...", + "subIssueDataUnavailable": "Sub-issue data is unavailable for your token.", + "mergeMethodTitle": "Merge method", + "pullRequestMergeMessage": "Choose how this pull request should be merged.", + "mergeRequestMergeMessage": "Choose how this merge request should be merged.", + "mergeAction": "Merge", + "mergeRequestTitle": "Merge Request", + "mergePullRequestTitle": "Merge Pull Request", + "updateItemTitle": "Update Item" + }, + "prFileDiff": { + "noTextChanges": "No text changes found.", + "showingDiffLines": "Showing first {{limit}} of {{total}} diff lines.", + "commentPlaceholder": "Add review comment", + "commentOnLine": "Comment on line {{line}}" + }, + "smartSourceModes": { + "smart": "Smart", + "branch": "Branch", + "name": "Name", + "openState": "Open", + "mergedState": "Merged", + "closedState": "Closed", + "allStates": "All" + }, + "taskViewOptions": { + "noGitHubTasks": "No GitHub tasks", + "noGitLabTasks": "No GitLab tasks", + "noLinearTasks": "No Linear tasks", + "noJiraTasks": "No Jira tasks", + "assignedSubtitle": "Unresolved issues assigned to you", + "reportedSubtitle": "Unresolved issues you reported", + "allSubtitle": "Unresolved issues across the selected sites", + "doneSubtitle": "Your recently resolved issues" + }, + "tasksCreateDrawers": { + "newIssueTitle": "New {{providerLabel}} Issue", + "repositorySubtitle": "Create an issue in the selected repository.", + "linearTeamSubtitle": "Create an issue in the selected Linear team.", + "repository": "Repository", + "team": "Team", + "issueSource": "Issue source", + "fileIn": "File in {{slug}}", + "upstream": "Upstream", + "origin": "Origin", + "title": "Title", + "titlePlaceholder": "Task title", + "description": "Description", + "descriptionPlaceholder": "Add context", + "createIssue": "Create Issue", + "linearTeam": "Linear Team", + "connectLinearWorkspace": "Connect Linear workspace", + "linearConnectSubtitle": "Paste a Personal API key to browse issues from that workspace.", + "personalApiKey": "Personal API key", + "linearSettingsLink": "Linear Settings / Security / New API key", + "keySecurityHint": "Your key is encrypted via the host OS keychain and stored locally.", + "connect": "Connect", + "createWorkspaceIn": "Create Workspace In" + }, + "filterPickers": { + "fieldsTitle": "Project Fields", + "fieldsSubtitle": "Choose which Project fields appear on item cards.", + "noFields": "This view has no extra fields to show.", + "fieldShown": "Shown on cards", + "fieldHidden": "Hidden from cards", + "gitlabView": "GitLab View", + "gitlabFilter": "GitLab Filter", + "linearFilter": "Linear Filter", + "linearWorkspace": "Linear Workspace", + "switchWorkspaceFailed": "Failed to switch workspace", + "teamsTitle": "Linear Teams", + "teamsSubtitle": "Choose which teams appear in Tasks.", + "allTeams": "All teams", + "teams_one": "{{count}} team", + "teams_other": "{{count}} teams", + "changeStatus": "Change Status", + "linearIssue": "Linear issue", + "loadingStates": "Loading states...", + "noStates": "No states available", + "jiraFilter": "Jira Filter", + "jiraSite": "Jira Site" + }, + "githubProjectList": { + "chooseProject": "Choose a GitHub project", + "browseProjects": "Browse projects", + "noItems": "No project items", + "items": "Items", + "pullRequestSubtitle": "Pull request · {{repository}}{{number}}", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "Project item · {{repository}}{{number}}", + "emptyField": "Empty", + "moreFields_one": "+{{count}} field", + "moreFields_other": "+{{count}} fields" + }, + "githubProjectPickers": { + "title": "GitHub Projects", + "subtitle": "Choose a project view for the Tasks page.", + "searchProjects": "Search projects", + "addPlaceholder": "Add by URL or owner/number", + "adding": "Adding...", + "add": "Add", + "ownerLoadFailed": "Couldn't load projects from {{owner}}.", + "organizationsLoadFailed": "Some organizations didn't load ({{count}}).", + "addByUrlHint": "Use Add by URL to reach missing projects.", + "organizationsError": "orgs: {{message}}", + "loadFailed": "Failed to load projects", + "noProjects": "No projects loaded", + "retryHint": "Tap to retry.", + "pinned": "Pinned", + "recent": "Recent", + "pin": "Pin", + "browseLoading": "Browse all (loading...)", + "browseAll": "Browse all", + "noMatches": "No matching projects.", + "noMoreProjects": "No more projects.", + "chooseView": "Choose Project View", + "view": "Project View", + "unsupportedLayout": "Orca doesn't support this GitHub Project layout yet.", + "sort": "Project Sort" + }, + "githubViewControls": { + "source": "Source: {{source}}", + "sort": "Sort: {{sort}}", + "fields": "Fields: {{fields}}", + "openView": "Open view in GitHub" + }, + "itemActions": { + "creating": "Creating...", + "createWorkspace": "Create Workspace", + "copyLinearLink": "Copy Linear link", + "copyGitHubLink": "Copy GitHub link", + "mergePullRequest": "Merge pull request", + "mergeConflicts": "GitHub reports merge conflicts.", + "mergeMergeRequest": "Merge merge request", + "changeStatus": "Change status" + }, + "itemDetailContent": { + "pipelineJobs_one": "{{count}} jobs", + "pipelineJobs_other": "{{count}} jobs", + "type": "Type", + "status": "Status", + "assignee": "Assignee", + "project": "Project", + "assignees": "Assignees", + "description": "Description", + "checks": "Checks", + "rerunFailed": "Rerun failed", + "rerunAll": "Rerun all", + "noChecks": "No checks found.", + "pipeline": "Pipeline", + "none": "None", + "noPipelineRuns": "No pipeline runs for this MR.", + "subIssues": "Sub-issues", + "noSubIssues": "No sub-issues.", + "subIssueTitle": "Sub-issue title", + "addSubIssue": "Add sub-issue", + "discussion": "Discussion", + "noComments": "No comments." + }, + "itemDetailDrawer": { + "refreshDetails": "Refresh details" + }, + "itemFieldEditors": { + "title": "Title", + "saveTitle": "Save title", + "labels": "Labels", + "none": "None", + "loadingLabels": "Loading labels...", + "noLabels": "No labels in this repository.", + "addLabels": "Add labels, comma separated", + "removeLabels": "Remove labels, comma separated", + "updateLabels": "Update labels", + "assignees": "Assignees", + "loadingAssignees": "Loading assignees...", + "noAssignableUsers": "No assignable users found for this repository.", + "addUsernames": "Add usernames, comma separated", + "removeUsernames": "Remove usernames, comma separated", + "updateAssignees": "Update assignees" + }, + "itemReviewSections": { + "descriptionPlaceholder": "Description", + "saveDescription": "Save description", + "noDescription": "No description.", + "reviewersTitle": "Reviewers", + "noReviewersRequested": "No reviewers requested.", + "loadingReviewers": "Loading reviewers...", + "noReviewerSuggestions": "No reviewer suggestions found.", + "reviewersPlaceholder": "Request reviewers", + "requestReview": "Request review", + "changedFilesTitle": "Changed files", + "hideFile": "Hide", + "viewFile": "View", + "markUnviewed": "Mark unviewed", + "markViewed": "Mark viewed", + "binaryFile": "Binary file.", + "fileContentsUnavailable": "File contents unavailable." + }, + "linearList": { + "changeStatusFrom": "Change status from {{status}}" + }, + "linearViewControls": { + "groupLabel": "Group: {{group}}", + "orderLabel": "Order: {{order}}", + "displayButton": "Display" + }, + "listDisplayPickers": { + "linearViewTitle": "Linear View", + "linearGroupTitle": "Group Linear Issues", + "linearOrderTitle": "Order Linear Issues", + "displayPropertiesTitle": "Display Properties", + "sortTasksTitle": "Sort Tasks" + }, + "listSurface": { + "updateDesktopTitle": "Update Orca desktop", + "updateDesktopMessage": "This mobile Tasks view needs a newer desktop runtime.", + "jiraStatusFailed": "Failed to read Jira status", + "connectLinearTitle": "Connect your Linear account", + "connectLinearMessage": "Browse and start work on your assigned Linear issues directly from Tasks.", + "connectLinearButton": "Connect Linear" + }, + "options": { + "githubDescription": "Issues and pull requests", + "gitlabDescription": "Issues and merge requests", + "linearDescription": "Assigned and team issues", + "jiraDescription": "Assigned and reported issues", + "openState": "Open", + "gitlabOpenDescription": "Open issues and merge requests", + "mergedState": "Merged", + "gitlabMergedDescription": "Merged merge requests", + "closedState": "Closed", + "gitlabClosedDescription": "Closed issues and merge requests", + "all": "All", + "gitlabAllDescription": "Any GitLab state", + "linearAllDescription": "Open issues across connected workspaces", + "myIssues": "My Issues", + "linearAssignedDescription": "Issues assigned to you", + "createdState": "Created", + "linearCreatedDescription": "Issues created by you", + "completedState": "Completed", + "linearCompletedDescription": "Recently completed issues", + "list": "List", + "listDescription": "Compact issue rows", + "board": "Board", + "boardDescription": "Grouped columns", + "noGrouping": "No grouping", + "status": "Status", + "assignee": "Assignee", + "priority": "Priority", + "team": "Team", + "updated": "Updated", + "identifier": "Identifier", + "labels": "Labels", + "issues": "Issues", + "githubIssuesDescription": "GitHub issues", + "pullRequests": "PRs", + "githubPullRequestsDescription": "GitHub pull requests", + "projects": "Projects", + "githubProjectsDescription": "GitHub Projects views", + "githubOpenIssuesDescription": "Open GitHub issues", + "assignedToMe": "Assigned to me", + "githubAssignedIssuesDescription": "Open issues assigned to you", + "openPullRequestsDescription": "Open pull requests", + "mine": "Mine", + "myPullRequestsDescription": "Pull requests authored by you", + "needsReview": "Needs review", + "reviewRequestsDescription": "Review requests assigned to you", + "projectMergeRequests": "Project MRs", + "projectMergeRequestsDescription": "Merge requests and issues by repository", + "myTodos": "My Todos", + "myTodosDescription": "Pending GitLab todos", + "updatedSortDescription": "Newest activity first", + "repository": "Repository", + "repositorySortDescription": "Group by repository, then newest activity" + }, + "projectComments": { + "comments_one": "{{count}} comment", + "comments_other": "{{count}} comments", + "discussion": "Discussion", + "noComments": "No comments.", + "resolvedThreadBy": "Resolved thread by {{author}}", + "resolvedCommentBy": "Resolved comment by {{author}}", + "show": "Show", + "editComment": "Edit comment", + "reopenThread": "Reopen thread", + "resolveThread": "Resolve thread", + "reply": "Reply" + }, + "projectDetailDrawer": { + "repositoryNotInOrca": "Repository not in Orca", + "addRepositoryFromDesktop": "{{repository}} is not added to Orca. Add this repository from the desktop app, then refresh mobile Tasks.", + "openInGitHub": "Open in GitHub", + "copyRepository": "Copy repository", + "projectSubtitle": "GitHub Project · {{repository}}{{itemNumber}}", + "type": "Type", + "pullRequest": "Pull request", + "issue": "Issue", + "draftIssue": "Draft issue", + "projectItem": "Project item", + "status": "Status", + "issueType": "Issue type", + "noType": "No type", + "loadingIssueTypes": "Loading issue types...", + "noIssueTypes": "No issue types configured for this repository.", + "clearType": "Clear type", + "createWorkspace": "Create Workspace", + "workspaceCreationRequirement": "Workspaces can only be created from GitHub issues and pull requests.", + "copyGitHubLink": "Copy GitHub link", + "reopenItem": "Reopen item", + "closeItem": "Close item", + "mergePullRequest": "Merge pull request", + "mergeRepositoryRequirement": "Merge requires this repository in Orca." + }, + "projectFieldEditors": { + "projectFields": "Project fields", + "invalidNumber": "Enter a valid number.", + "invalidDate": "Enter a date as YYYY-MM-DD.", + "noIterations": "No iterations available.", + "completedIteration": "Completed · {{startDate}} · {{duration}}d", + "upcomingIteration": "Current & upcoming · {{startDate}} · {{duration}}d", + "datePlaceholder": "YYYY-MM-DD", + "numberPlaceholder": "Number", + "textPlaceholder": "Text", + "saveField": "Save field", + "clearField": "Clear field" + }, + "projectMetadataEditors": { + "labels": "Labels", + "none": "None", + "loadingLabels": "Loading labels...", + "noLabels": "No labels in this repository.", + "assignees": "Assignees", + "loadingAssignees": "Loading assignees...", + "noAssignableUsers": "No assignable users found for this repository.", + "title": "Title", + "saveTitle": "Save title", + "description": "Description", + "saveDescription": "Save description", + "noDescription": "No description." + }, + "projectReviewPanels": { + "reviewers": "Reviewers", + "noReviewers": "No reviewers requested.", + "loadingReviewers": "Loading reviewers...", + "noSuggestions": "No reviewer suggestions found.", + "requestReviewers": "Request reviewers", + "requestReview": "Request review", + "checks": "Checks", + "rerunFailed": "Rerun failed", + "rerunAll": "Rerun all", + "noChecks": "No checks found.", + "changedFiles": "Changed files", + "hideFile": "Hide", + "viewFile": "View", + "markUnviewed": "Mark unviewed", + "markViewed": "Mark viewed", + "binaryFile": "Binary file.", + "fileUnavailable": "File contents unavailable." + }, + "providerControls": { + "projectMergeRequests": "Project MRs", + "myTodos": "My Todos", + "sort": "Sort: {{sortLabel}}" + }, + "providerItemList": { + "previousPage": "Previous page", + "selectPage": "Select page, Page {{page}}", + "selectPageOfTotal": "Select page, Page {{page}} of {{total}}", + "page": "Page {{page}}", + "pageOfTotal": "Page {{page}} of {{total}}", + "nextPage": "Next page", + "intoBranch": "into {{base}}" + }, + "providerPickers": { + "taskSource": "Task Source", + "repos": "Repositories", + "repoDescription": "Choose which repositories to query.", + "allRepositories": "All repositories", + "issueSources": "GitHub Issue Sources", + "issueSourcesDescription": "Choose whether each repository queries and creates work from upstream or origin.", + "noIssueSources": "No alternate issue sources available.", + "queryingSource": "Querying {{source}}", + "upstream": "Upstream", + "origin": "Origin", + "githubView": "GitHub View", + "pullRequests": "Pull Requests", + "issues": "Issues", + "pages": "GitHub Pages", + "pageHint": "Jump to a loaded or available result page.", + "pageNumber": "Page {{page}}", + "pageLoaded": "Loaded", + "pageNotLoaded": "Loads older results" + }, + "reviewerLinear": { + "unassigned": "Unassigned", + "issues": "Issues" + }, + "screenChrome": { + "refreshGitHub": "Refresh GitHub work", + "refreshGitLab": "Refresh GitLab work items", + "refreshLinear": "Refresh Linear", + "refreshJira": "Refresh Jira issues", + "title": "Tasks", + "newGitHubIssue": "New GitHub issue", + "newLinearIssue": "New Linear issue", + "connectLinear": "Connect Linear" + }, + "searchControl": { + "projectPlaceholder": "Search project view...", + "jiraPlaceholder": "Jira JQL, e.g. project = ABC AND statusCategory != Done", + "providerPlaceholder": "Search {{provider}} tasks..." + }, + "workspaceCreateDrawer": { + "title": "Create Workspace", + "repository": "Repository", + "selectRepository": "Select a repository", + "sshConnection": "SSH Connection", + "remoteRepository": "Remote repository", + "connecting": "Connecting...", + "connect": "Connect", + "workspaceName": "Workspace Name", + "optional": "[Optional]", + "agent": "Agent", + "connectFirst": "Connect repository first", + "detectingAgents": "Detecting agents...", + "advanced": "Advanced", + "startFrom": "Start from", + "defaultBranch": "Default branch", + "createFrom": "Create from {{branch}}", + "addRepository": "Add a Git repository before creating a Linear workspace.", + "repositoryNotFound": "Repository not found.", + "connectRepository": "Connect Repository" + }, + "workspaceOptionPickers": { + "baseBranchTitle": "Start From", + "baseBranchSubtitle": "Pick an existing branch or ref.", + "searchBranches": "Search branches", + "defaultBranch": "Default branch", + "defaultBranchSubtitle": "Use this repository's configured base", + "noBranches": "No branches match.", + "branchName": "Branch name: {{name}}", + "sparseCheckoutTitle": "Sparse Checkout", + "fullCheckout": "Full checkout", + "fullCheckoutSubtitle": "Use the whole repository", + "editPreset": "Edit {{name}}", + "newPreset": "New preset" + }, + "workspaceTrustDrawers": { + "newSparsePreset": "New Sparse Preset", + "editSparsePreset": "Edit Sparse Preset", + "nameLabel": "Name", + "namePlaceholder": "Renderer UI", + "directoriesLabel": "Directories", + "directories_one": "{{count}} directory", + "directories_other": "{{count}} directories", + "setupTitle": "Run Setup Script?", + "setupSubtitle": "{{name}} requires a setup choice before creating this workspace.", + "creating": "Creating...", + "runSetupAndCreate": "Run setup and create", + "skipSetupAndCreate": "Skip setup and create", + "setupChangedTitle": "{{name}}'s setup script changed", + "runSetupTitle": "Run setup from {{name}}?", + "trustSubtitle": "This repository's orca.yaml runs on your machine before the workspace starts. Only run it if you trust this repository.", + "newSetupScript": "New setup script", + "setupScript": "Setup script", + "trustFailed": "Failed to trust setup script.", + "runHooks": "Run hooks", + "alwaysTrustAndRun": "Always trust and run", + "dontRun": "Don't run" + }, + "sparsePresetDraft": { + "repoRelativeDirectoriesRequired": "Use repo-relative directories, not root, absolute paths, or parent segments.", + "directoryRequired": "Add at least one directory." + }, + "composerSource": { + "baseFailed": "Failed to resolve base branch.", + "forkPushWarning": "This PR has \"Allow edits from maintainers\" off; pushing to the fork may be rejected by GitHub." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Add a comment", + "sendComment": "Send comment", + "reopenThread": "Reopen thread", + "resolveThread": "Resolve thread", + "reply": "Reply", + "comments_one": "{{count}} comment", + "comments_other": "{{count}} comments", + "resolvedThreadBy": "Resolved thread by {{author}}", + "resolvedCommentBy": "Resolved comment by {{author}}", + "show": "Show" + }, + "pickerProjection": { + "sources_one": "{{count}} source", + "sources_other": "{{count}} sources", + "repos_one": "{{count}} repo", + "repos_other": "{{count}} repos", + "selectTarget": "Select target", + "allSites": "All sites", + "allRepos": "All repos", + "updatedSort": "Updated", + "fieldDescending": "{{field}} desc", + "fieldAscending": "{{field}} asc", + "viewOrder": "View order", + "selectedFields": "{{selected}}/{{total}} fields", + "fields": "Fields", + "usesFieldDescending": "Uses {{field}} desc", + "usesFieldAscending": "Uses {{field}} asc", + "usesGitHubRankOrder": "Uses GitHub rank order", + "currentlyDescending": "Currently desc · tap for ascending", + "currentlyAscending": "Currently asc · tap for descending", + "sortAscending": "Sort ascending", + "viewNumber": "View #{{number}}", + "unsupportedLayout": "Unsupported layout on mobile" + }, + "providerViewProjection": { + "defaultSubtitle": "{{subtitle}} · Default", + "default": "Default", + "openState": "Open", + "allSites": "All sites", + "all": "All", + "list": "List", + "noGrouping": "No grouping", + "priority": "Priority", + "allWorkspaces": "All workspaces", + "workspace": "Workspace", + "allTeams": "All teams", + "teams_one": "{{count}} team", + "teams_other": "{{count}} teams", + "projects": "Projects", + "pullRequests": "PRs", + "issues": "Issues", + "chooseProject": "Choose project" + }, + "workspaceCreateProjection": { + "nameRequired": "Name is required.", + "nameTooLong": "Name must be 80 characters or fewer.", + "nameAlreadyExists": "\"{{name}}\" already exists.", + "openShell": "Open a shell" + }, + "workspaceAgentSelection": { + "blankTerminal": "Blank Terminal" + }, + "workspaceSshGate": { + "connected": "Connected", + "connecting": "Connecting", + "deployingRelay": "Deploying relay", + "reconnecting": "Reconnecting", + "authenticationFailed": "Authentication failed", + "reconnectFailed": "Reconnect failed", + "connectionFailed": "Connection failed", + "disconnected": "Disconnected" + }, + "worktreeCreateRetry": { + "createFailed": "Failed to create workspace" } }, "terminal": { diff --git a/mobile/src/i18n/locales/es.json b/mobile/src/i18n/locales/es.json index d519ea78bbb..752df7be42f 100644 --- a/mobile/src/i18n/locales/es.json +++ b/mobile/src/i18n/locales/es.json @@ -119,7 +119,7 @@ "autocompleteOn": "Activado", "defaultText": "Predeterminado (100%)", "keepPhoneSize": "Mantener en tamaño de teléfono (predeterminado)", - "keyboardInputDescription": "El autocompletado, la autocorrección y las sugerencias ortográficas solo se aplican a los comandos que se editan antes de enviarlos. Usa el botón de doble flecha situado encima del teclado para salir del modo de entrada en directo y edita el comando antes de tocar Enviar. Estas funciones están desactivadas por defecto para evitar que se modifiquen comandos, opciones o rutas.", + "keyboardInputDescription": "El autocompletado, la autocorrección y las sugerencias ortográficas solo se aplican a los comandos que se editan antes de enviarlos. Usa el botón de doble flecha situado encima del teclado para salir del modo de entrada directa y edita el comando antes de tocar Enviar. Estas funciones están desactivadas por defecto para evitar que se modifiquen comandos, opciones o rutas.", "keyboardInputHeading": "ENTRADA DE TECLADO", "largeText": "Grande (125%)", "largerText": "Más grande (150%)", @@ -1532,7 +1532,21 @@ "workspace": "Espacio de trabajo" } }, + "newWorkspace": { + "hostPicker": { + "title": "Crear espacio de trabajo en" + }, + "loadingDrawer": { + "downloadProgress": "Descargando… {{progress}}", + "downloading": "Descargando", + "loading": "Cargando" + } + }, "notifications": { + "desktopChannel": { + "name": "Notificaciones del escritorio", + "silentName": "Notificaciones silenciosas de Orca" + }, "notificationDeliverySection": { "footer": "Los tipos de alerta dependen de la configuración de notificaciones de cada escritorio emparejado. Las notificaciones se pausan tras 7 días sin usar esta aplicación; ábrela y vuelve a conectarte para reanudarlas.", "onlyWhenAway": "Solo cuando no uses el escritorio", @@ -2278,7 +2292,7 @@ }, "terminalLiveInputStatus": { "listening": "Escuchando", - "liveInput": "Entrada en tiempo real", + "liveInput": "Entrada directa", "preparingMic": "Preparando micrófono", "processing": "Procesando", "releaseMicHint": "Suelta el micrófono para detener la grabación", @@ -2590,11 +2604,71 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "No hay una rama base sobre la que hacer rebase", + "waitingForDesktop": "Esperando al escritorio…" + }, "actions": { + "checkingReviewStatus": "Comprobando estado de revisión.", + "checkoutBeforePublish": "Haz checkout de una rama antes de publicar commits.", + "commitStagedChanges": "Haz commit de los cambios preparados.", "commits": "Commits", + "committing": "Commit en curso.", "createPr": "Crear PR", + "enterCommitMessage": "Introduce un mensaje de commit para hacer commit.", + "forcePushWithLease": "Haz force push con lease para actualizar la rama remota.", + "forcePushing": "Force push en curso.", + "linkedReviewUnavailable": "La rama de la revisión vinculada no está disponible.", + "publishToOrigin": "Publica esta rama en origin.", + "pullCommits_many": "Haz pull de {{count}} commits.", + "pullCommits_one": "Haz pull de {{count}} commit.", + "pullCommits_other": "Haz pull de {{count}} commits.", "pushAndCreatePr": "Push y crear PR", - "switchBranch": "Cambiar de rama" + "pushCommits_many": "Haz push de {{count}} commits.", + "pushCommits_one": "Haz push de {{count}} commit.", + "pushCommits_other": "Haz push de {{count}} commits.", + "pushLinkedReview": "Haz push de las actualizaciones a la rama de la revisión vinculada.", + "remoteOperationInProgress": "Operación remota en curso.", + "resolveConflicts": "Resuelve los conflictos antes de hacer commit.", + "reviewAlreadyMerged": "No hay nada para hacer commit. La revisión ya está mergeada.", + "stageAllChanges": "Agrega todos los cambios al stage.", + "stageFileToCommit": "Agrega al stage al menos un archivo para hacer commit.", + "switchBranch": "Cambiar de rama", + "syncCounts": "Haz pull de {{behind}} y push de {{ahead}}.", + "upToDate": "No hay nada para hacer commit. La rama está actualizada.", + "waitForRemoteOperation": "Vuelve a intentarlo cuando termine la operación remota." + }, + "branchBaseRef": { + "resolveFailed": "No se pudo determinar la base de la rama" + }, + "branchCard": { + "branchCount": "{{count}} en la rama", + "changedCount": "{{count}} con cambios", + "cherryPickState": "cherry-pick", + "mergeState": "merge", + "rebaseState": "rebase", + "stagedCount": "{{count}} en stage" + }, + "branchCompare": { + "commits_many": "{{count}} commits", + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commits", + "files_many": "{{count}} archivos", + "files_one": "{{count}} archivo", + "files_other": "{{count}} archivos", + "sectionTitle": "Commits en la rama", + "summary": "{{files}} - frente a {{baseRef}}", + "summaryWithCommits": "{{files}} - {{commits}} - frente a {{baseRef}}" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "No se pudo determinar la rama base para la comparación.", + "loadFailed": "No se pudieron cargar los cambios confirmados" + }, + "branchDiffPreviewDrawer": { + "closePreview": "Cerrar vista previa del diff de los commits", + "committedOnBranch": "Commits en la rama", + "loadFailed": "No se pudo cargar el diff", + "truncated": "Diff truncado para la vista previa móvil." }, "commitDropdown": { "checkOutBranchToPush": "Haz checkout de una rama antes de hacer push de commits", @@ -2619,8 +2693,49 @@ "stageFile": "Haz stage de al menos un archivo para crear un commit", "useCommitAndForcePush": "Usa Commit y Force Push — el remoto solo tiene copias antiguas de commits locales" }, + "commitFailurePanel": { + "fix": "Arreglar", + "fixWithAi": "Solucionar error de commit con IA", + "hideDetails": "Ocultar detalles", + "hideFailureDetails": "Ocultar detalles del error de commit", + "showDetails": "Mostrar detalles", + "showFailureDetails": "Mostrar detalles del error de commit", + "summary": "No se pudo hacer commit.", + "title": "No se pudo hacer commit" + }, + "commitMessageAi": { + "generateFailed": "No se pudo generar el mensaje de commit" + }, + "commitRunners": { + "actionFailed": "No se pudo realizar la acción de control de código fuente", + "commitFailed": "No se pudo hacer commit" + }, + "conflictAbort": { + "abortMerge": "Cancelar fusión", + "abortOperation": "Abortar {{operation}}", + "abortRebase": "Abortar rebase", + "aborting": "Abortando…" + }, + "content": { + "cancelGeneration": "Cancelar la generación del mensaje de commit", + "commitMessageDisabled": "Mensaje de commit deshabilitado. No hay archivos preparados.", + "commitMessagePlaceholder": "Mensaje de commit", + "emptyMessage": "El árbol de trabajo está limpio.", + "emptyTitle": "No hay cambios locales", + "generateMessage": "Generar mensaje de commit con IA", + "noStagedFiles": "No hay archivos preparados", + "openActions": "Abrir acciones de control de código fuente", + "reconnecting": "Reconectando con el escritorio…", + "regenerateHint": "Borre el mensaje para regenerar.", + "stageAll": "Hacer stage de todo", + "unstageAll": "Quitar todo del stage" + }, "createPrAction": { - "createReview": "Crear {{titleLabel}}" + "checkingStatus": "Comprobando estado de revisión…", + "createPullRequest": "Crear pull request", + "createReview": "Crear {{titleLabel}}", + "providerUnavailable": "Creación de revisiones no disponible para este proveedor", + "statusUnavailable": "Estado de revisión no disponible" }, "dropdownCounts": { "fastForwardCount_many": "Hacer fast-forward de {{count}} commits", @@ -2649,6 +2764,69 @@ "titleUnpublishedForcePushCount_one": "Haz force push con lease de {{count}} commit de la rama y configura un upstream si es necesario.", "titleUnpublishedForcePushCount_other": "Haz force push con lease de {{count}} commits de la rama y configura un upstream si es necesario." }, + "fileList": { + "committedSection": "Commits en la rama" + }, + "fileRows": { + "addedByThem": "Agregado por ellos", + "addedByUs": "Agregado por nosotros", + "bothAdded": "Agregado por ambos", + "bothDeleted": "Eliminado por ambos", + "bothModified": "Modificado por ambos", + "committedSection": "Commits en la rama", + "committedUnavailable": "Los cambios confirmados no están disponibles.", + "deletedByThem": "Eliminado por ellos", + "deletedByUs": "Eliminado por nosotros", + "discardFile": "Descartar {{path}}", + "loadingCommitted": "Cargando cambios confirmados…", + "openChangedFile": "Abrir archivo modificado {{path}}", + "openCommittedChange": "Abrir cambio confirmado en {{path}}", + "renamedFrom": "de {{path}}", + "stageFile": "Agregar {{path}} al stage", + "unresolvedConflict": "Conflicto sin resolver", + "unstageFile": "Quitar {{path}} del stage" + }, + "gitHistory": { + "days_many": "{{count}} d", + "days_one": "{{count}} d", + "days_other": "{{count}} d", + "hours_many": "{{count}} h", + "hours_one": "{{count}} h", + "hours_other": "{{count}} h", + "justNow": "ahora mismo", + "loadFailed": "No se pudo cargar el historial de commits", + "minutes_many": "{{count}} min", + "minutes_one": "{{count}} min", + "minutes_other": "{{count}} min", + "months_many": "{{count}} meses", + "months_one": "{{count}} mes", + "months_other": "{{count}} meses", + "noCommitMessage": "(sin mensaje de commit)", + "years_many": "{{count}} años", + "years_one": "{{count}} año", + "years_other": "{{count}} años" + }, + "gitHistoryList": { + "loadFailed": "No se pudo cargar el historial", + "loadFilesFailed": "No se pudieron cargar los archivos del commit", + "noCommits": "No hay commits.", + "noFileChanges": "No hay cambios en los archivos", + "retryFiles": "Reintentar la carga de los archivos del commit", + "waitingForDesktop": "Esperando al escritorio…" + }, + "gitStatus": { + "changes": "Cambios", + "conflicts": "Conflictos", + "stagedChanges": "Cambios preparados" + }, + "header": { + "backToSession": "Volver a la sesión", + "close": "Cerrar el control de código fuente", + "openNumberedPrWeb": "Abrir la pull request #{{number}} en la web", + "openPrWeb": "Abrir la pull request en la web", + "refresh": "Actualizar el control de código fuente", + "title": "Control de código fuente" + }, "hostedReview": { "mrCopy": { "reviewLabel": "solicitud de fusión", @@ -2661,9 +2839,82 @@ "titleLabel": "Solicitud de extracción" } }, + "hostedReviewCopy": { + "committingChanges": "Confirmando cambios…", + "creatingReview": "Creando revisión…", + "forcePushing": "Haciendo force push con lease…", + "generatingCommitMessage": "Generando mensaje de commit…", + "publishingBranch": "Publicando rama…", + "pushingCommits": "Haciendo push de commits…", + "stagingChanges": "Agregando cambios al stage…", + "updatingBranch": "Actualizando rama…" + }, "hostedReviewCreate": { "pushSucceeded": "El push se completó, pero no se pudo crear {{shortLabel}}: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "La rama cambió mientras se preparaba la pull request.", + "generateMessageFailed": "No se pudo generar un mensaje de commit. Añade uno en Control de código fuente y vuelve a intentarlo.", + "resolveConflicts": "Resuelve los conflictos antes de crear una pull request.", + "resolveOrStageChanges": "Resuelve los conflictos o agrega los cambios al stage antes de crear una pull request.", + "reviewCommitMessage": "Revisa el mensaje de commit y vuelve a intentar Crear PR." + }, + "hostedReviewGitPreparation": { + "commitFailed": "No se pudo hacer commit", + "refreshFailed": "No se pudo actualizar el control de código fuente", + "stageFailed": "No se pudieron agregar los cambios al stage", + "updateBranchFailed": "No se pudo actualizar la rama remota. Vuelve a intentar Crear PR." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "No se pudo hacer force push con lease", + "publishFailed": "No se pudo publicar la rama", + "pushFailed": "No se pudo hacer push de los commits" + }, + "hostedReviewService": { + "createFailed": "No se pudo crear la pull request", + "pushBeforeCreateFailed": "El push falló. Resuelve el error de push y vuelve a intentarlo." + }, + "hubTab": { + "changes": "Cambios", + "commits": "Commits", + "pullRequest": "Solicitud de extracción" + }, + "loaders": { + "connectingToDesktop": "Conectando con el escritorio…", + "loadFailed": "No se pudo cargar el control de código fuente", + "updateDesktop": "Actualiza Orca en el escritorio para usar el control de código fuente en el móvil.", + "waitingForDesktop": "Esperando al escritorio…" + }, + "modals": { + "actionsTitle": "Control de código fuente", + "currentBranch": "actual", + "discardButton": "Descartar", + "discardConfirmMessage": "¿Descartar los cambios de \"{{path}}\"? Esta acción no se puede deshacer.", + "discardTitle": "Descartar cambio", + "openPrMessage": "¿Abrirla en tu navegador?", + "openPrWithWarning": "¿Abrirla en tu navegador?\n\n{{warning}}", + "prCreatedTitle": "Solicitud de extracción creada", + "switchBranchTitle": "Cambiar de rama" + }, + "openers": { + "openDiffFailed": "No se pudo abrir el diff", + "tabNotReady": "El archivo se abrió, pero su pestaña aún no está lista. Vuelve a intentarlo.", + "waitingForDesktop": "Esperando al escritorio…" + }, + "panel": { + "loadFailedTitle": "No se pudo cargar", + "unavailableTitle": "Control de código fuente no disponible" + }, + "prChip": { + "createPr": "Crear pull request", + "loading": "Cargando pull request…", + "loadingLabel": "Cargando pull request", + "openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Abrir pull request.", + "openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentarios sin resolver. Abrir pull request.", + "openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentario sin resolver. Abrir pull request.", + "openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentarios sin resolver. Abrir pull request.", + "unavailableLabel": "Pull request no disponible: {{message}}" + }, "prCreate": { "authRequired": "Autentícate antes de crear una {{reviewLabel}}.", "baseNotOnRemote": "Haz push de la rama base antes de crear una {{reviewLabel}}.", @@ -2682,8 +2933,19 @@ "unsupportedMergeRequests": "No se pueden crear merge requests en este repositorio.", "unsupportedPullRequests": "No se pueden crear pull requests en este repositorio." }, + "prLink": { + "updatePullRequestFailed": "No se pudo actualizar la pull request vinculada", + "updateReviewFailed": "No se pudo actualizar la revisión vinculada" + }, "primaryAction": { - "forcePushFromDesktop": "Haz force push de la rama de esta pull request desde el escritorio" + "commit": "Commit", + "forcePush": "Force Push", + "forcePushFromDesktop": "Haz force push de la rama de esta pull request desde el escritorio", + "publishBranch": "Publicar rama", + "pull": "Pull", + "push": "Push", + "stageAll": "Hacer stage de todo", + "sync": "Sincronizar" }, "remoteDropdown": { "branchAlreadyPublished": "La rama ya está publicada", @@ -2733,6 +2995,600 @@ "tryFastForwardPull": "Intenta un pull con fast-forward; git puede rechazar los commits locales", "tryRegularPush": "Intenta un push normal; git puede requerir force push", "useForcePushToSync": "Usa Force Push — el remoto solo tiene copias antiguas de commits locales" + }, + "runners": { + "actionFailed": "No se pudo realizar la acción de control de código fuente" + }, + "screenState": { + "noBranch": "Sin rama" + }, + "state": { + "noUpstream": "Sin upstream", + "syncStatus": "{{ahead}} por delante, {{behind}} por detrás" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "No se pudo iniciar el agente", + "waitingForDesktop": "Esperando al escritorio…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "No se pudo generar el mensaje de commit" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Haz checkout de una rama antes de crear una pull request." + }, + "useMobileGitRequests": { + "actionFailed": "No se pudo realizar la acción de control de código fuente", + "branchUnavailable": "Estado de la rama no disponible", + "commitFailed": "No se pudo hacer commit", + "waitingForDesktop": "Esperando al escritorio…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "No se pudo resolver la rama base.", + "forkPushWarning": "Esta PR tiene desactivada la opción \"Allow edits from maintainers\"; GitHub podría rechazar el push al fork." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Agregar un comentario", + "comments_many": "{{count}} comentarios", + "comments_one": "{{count}} comentario", + "comments_other": "{{count}} comentarios", + "reopenThread": "Reabrir hilo", + "reply": "Responder", + "resolveThread": "Resolver hilo", + "resolvedCommentBy": "Comentario de {{author}} resuelto", + "resolvedThreadBy": "Hilo de {{author}} resuelto", + "sendComment": "Enviar comentario", + "show": "Mostrar" + }, + "filterPickers": { + "allTeams": "Todos los equipos", + "changeStatus": "Cambiar estado", + "fieldHidden": "Oculto en las tarjetas", + "fieldShown": "Visible en las tarjetas", + "fieldsSubtitle": "Elige qué campos del proyecto aparecen en las tarjetas de los elementos.", + "fieldsTitle": "Campos del proyecto", + "gitlabFilter": "Filtro de GitLab", + "gitlabView": "Vista de GitLab", + "jiraFilter": "Filtro de Jira", + "jiraSite": "Sitio de Jira", + "linearFilter": "Filtro de Linear", + "linearIssue": "Issue de Linear", + "linearWorkspace": "Espacio de trabajo de Linear", + "loadingStates": "Cargando estados…", + "noFields": "Esta vista no tiene campos adicionales que mostrar.", + "noStates": "No hay estados disponibles", + "switchWorkspaceFailed": "No se pudo cambiar de espacio de trabajo", + "teamsSubtitle": "Elige qué equipos aparecen en Tareas.", + "teamsTitle": "Equipos de Linear", + "teams_many": "{{count}} equipos", + "teams_one": "{{count}} equipo", + "teams_other": "{{count}} equipos" + }, + "githubProjectList": { + "browseProjects": "Explorar proyectos", + "chooseProject": "Elige un proyecto de GitHub", + "emptyField": "Vacío", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "Elemento del proyecto · {{repository}}{{number}}", + "items": "Elementos", + "moreFields_many": "+{{count}} campos", + "moreFields_one": "+{{count}} campo", + "moreFields_other": "+{{count}} campos", + "noItems": "No hay elementos en el proyecto", + "pullRequestSubtitle": "Pull request · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Agregar", + "addByUrlHint": "Usa Agregar por URL para acceder a los proyectos que faltan.", + "addPlaceholder": "Agregar por URL u owner/number", + "adding": "Agregando…", + "browseAll": "Explorar todo", + "browseLoading": "Explorar todo (cargando…)", + "chooseView": "Elegir vista del proyecto", + "loadFailed": "No se pudieron cargar los proyectos", + "noMatches": "No hay proyectos que coincidan.", + "noMoreProjects": "No hay más proyectos.", + "noProjects": "No hay proyectos cargados", + "organizationsError": "organizaciones: {{message}}", + "organizationsLoadFailed": "No se pudieron cargar algunas organizaciones ({{count}}).", + "ownerLoadFailed": "No se pudieron cargar los proyectos de {{owner}}.", + "pin": "Fijar", + "pinned": "Fijado", + "recent": "Recientes", + "retryHint": "Toca para reintentar.", + "searchProjects": "Buscar proyectos", + "sort": "Orden del proyecto", + "subtitle": "Elige una vista de proyecto para la página Tareas.", + "title": "GitHub Projects", + "unsupportedLayout": "Orca aún no admite este diseño de proyecto de GitHub.", + "view": "Vista del proyecto" + }, + "githubViewControls": { + "fields": "Campos: {{fields}}", + "openView": "Abrir vista en GitHub", + "sort": "Orden: {{sort}}", + "source": "Origen: {{source}}" + }, + "itemActions": { + "changeStatus": "Cambiar estado", + "copyGitHubLink": "Copiar enlace de GitHub", + "copyLinearLink": "Copiar enlace de Linear", + "createWorkspace": "Crear espacio de trabajo", + "creating": "Creando…", + "mergeConflicts": "GitHub informa de conflictos de merge.", + "mergeMergeRequest": "Hacer merge de la merge request", + "mergePullRequest": "Hacer merge del pull request" + }, + "itemDetailContent": { + "addSubIssue": "Añadir sub-issue", + "assignee": "Asignado", + "assignees": "Asignados", + "checks": "Checks", + "description": "Descripción", + "discussion": "Discusión", + "noChecks": "No se encontraron checks.", + "noComments": "No hay comentarios.", + "noPipelineRuns": "No hay ejecuciones de pipeline para este MR.", + "noSubIssues": "No hay sub-issues.", + "none": "Ninguno", + "pipeline": "Pipeline", + "pipelineJobs_many": "{{count}} trabajos", + "pipelineJobs_one": "{{count}} trabajo", + "pipelineJobs_other": "{{count}} trabajos", + "project": "Proyecto", + "rerunAll": "Reejecutar todos", + "rerunFailed": "Reejecutar fallidos", + "status": "Estado", + "subIssueTitle": "Título del sub-issue", + "subIssues": "Sub-issues", + "type": "Tipo" + }, + "itemDetailDrawer": { + "refreshDetails": "Actualizar detalles" + }, + "itemFieldEditors": { + "addLabels": "Añade etiquetas, separadas por comas", + "addUsernames": "Añade nombres de usuario, separados por comas", + "assignees": "Asignados", + "labels": "Etiquetas", + "loadingAssignees": "Cargando asignados…", + "loadingLabels": "Cargando etiquetas…", + "noAssignableUsers": "No se encontraron usuarios asignables en este repositorio.", + "noLabels": "No hay etiquetas en este repositorio.", + "none": "Sin selección", + "removeLabels": "Quita etiquetas, separadas por comas", + "removeUsernames": "Quita nombres de usuario, separados por comas", + "saveTitle": "Guardar título", + "title": "Título", + "updateAssignees": "Actualizar asignados", + "updateLabels": "Actualizar etiquetas" + }, + "itemReviewSections": { + "binaryFile": "Archivo binario.", + "changedFilesTitle": "Archivos modificados", + "descriptionPlaceholder": "Descripción", + "fileContentsUnavailable": "El contenido del archivo no está disponible.", + "hideFile": "Ocultar", + "loadingReviewers": "Cargando revisores…", + "markUnviewed": "Marcar no visto", + "markViewed": "Marcar visto", + "noDescription": "Sin descripción.", + "noReviewerSuggestions": "No se encontraron sugerencias de revisores.", + "noReviewersRequested": "No se solicitaron revisores.", + "requestReview": "Solicitar revisión", + "reviewersPlaceholder": "Solicitar revisores", + "reviewersTitle": "Revisores", + "saveDescription": "Guardar descripción", + "viewFile": "Ver" + }, + "legacySurface": { + "loadIssuesFailed": "No se pudieron cargar los issues de {{source}}.", + "mergeAction": "Merge", + "mergeMethodTitle": "Método de merge", + "mergePullRequestTitle": "Fusionar pull request", + "mergeRequestMergeMessage": "Elige cómo hacer merge de esta merge request.", + "mergeRequestTitle": "Solicitud de fusión", + "pullRequestMergeMessage": "Elige cómo hacer merge de esta pull request.", + "retryLoadingIssues": "Reintentar cargar los issues de {{source}}", + "retrying": "Reintentando…", + "sourceFallback": "La fuente de issues preferida, upstream, no está disponible para {{repo}}. Se usa origin.", + "subIssueDataUnavailable": "Los datos de sub-issues no están disponibles para tu token.", + "updateItemTitle": "Actualizar elemento" + }, + "linearList": { + "changeStatusFrom": "Cambiar el estado actual: {{status}}" + }, + "linearViewControls": { + "displayButton": "Mostrar", + "groupLabel": "Agrupar: {{group}}", + "orderLabel": "Orden: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Propiedades visibles", + "linearGroupTitle": "Agrupar issues de Linear", + "linearOrderTitle": "Ordenar issues de Linear", + "linearViewTitle": "Vista de Linear", + "sortTasksTitle": "Ordenar tareas" + }, + "listSurface": { + "connectLinearButton": "Conectar Linear", + "connectLinearMessage": "Consulta los issues de Linear que tienes asignados y empieza a trabajar en ellos directamente desde Tareas.", + "connectLinearTitle": "Conecta tu cuenta Linear", + "jiraStatusFailed": "No se pudo leer el estado de Jira", + "updateDesktopMessage": "Esta vista móvil de Tareas necesita un entorno de ejecución de escritorio más reciente.", + "updateDesktopTitle": "Actualiza Orca en el escritorio" + }, + "options": { + "all": "Todo", + "assignedToMe": "Asignado a mí", + "assignee": "Asignado", + "board": "Tablero", + "boardDescription": "Columnas agrupadas", + "closedState": "Cerrado", + "completedState": "Completado", + "createdState": "Creado", + "githubAssignedIssuesDescription": "Issues abiertos asignados a ti", + "githubDescription": "Issues y pull requests", + "githubIssuesDescription": "Issues de GitHub", + "githubOpenIssuesDescription": "Issues abiertos de GitHub", + "githubProjectsDescription": "Vistas de GitHub Projects", + "githubPullRequestsDescription": "Pull requests de GitHub", + "gitlabAllDescription": "Cualquier estado de GitLab", + "gitlabClosedDescription": "Issues y merge requests cerrados", + "gitlabDescription": "Issues y merge requests", + "gitlabMergedDescription": "Merge requests mergeados", + "gitlabOpenDescription": "Issues y merge requests abiertos", + "identifier": "Identificador", + "issues": "Issues", + "jiraDescription": "Issues asignados y reportados", + "labels": "Etiquetas", + "linearAllDescription": "Issues abiertos en los espacios de trabajo conectados", + "linearAssignedDescription": "Issues que tienes asignados", + "linearCompletedDescription": "Issues completados recientemente", + "linearCreatedDescription": "Issues que has creado", + "linearDescription": "Issues asignados y del equipo", + "list": "Lista", + "listDescription": "Filas compactas de issues", + "mergedState": "Mergeado", + "mine": "Mío", + "myIssues": "Mis issues", + "myPullRequestsDescription": "Pull requests creadas por ti", + "myTodos": "Mis pendientes", + "myTodosDescription": "Tareas pendientes de GitLab", + "needsReview": "Necesita revisión", + "noGrouping": "Sin agrupación", + "openPullRequestsDescription": "Pull requests abiertas", + "openState": "Abierto", + "priority": "Prioridad", + "projectMergeRequests": "MRs del proyecto", + "projectMergeRequestsDescription": "Solicitudes de fusión e issues por repositorio", + "projects": "Proyectos", + "pullRequests": "PRs", + "repository": "Repositorio", + "repositorySortDescription": "Agrupar por repositorio y luego por actividad más reciente", + "reviewRequestsDescription": "Solicitudes de revisión asignadas a ti", + "status": "Estado", + "team": "Equipo", + "updated": "Actualizado", + "updatedSortDescription": "Actividad más reciente primero" + }, + "pickerProjection": { + "allRepos": "Todos los repositorios", + "allSites": "Todos los sitios", + "currentlyAscending": "Ascendente · toca para cambiar a descendente", + "currentlyDescending": "Descendente · toca para cambiar a ascendente", + "fieldAscending": "{{field}} ascendente", + "fieldDescending": "{{field}} descendente", + "fields": "Campos", + "repos_many": "{{count}} repositorios", + "repos_one": "{{count}} repositorio", + "repos_other": "{{count}} repositorios", + "selectTarget": "Seleccionar destino", + "selectedFields": "{{selected}}/{{total}} campos", + "sortAscending": "Ordenar de forma ascendente", + "sources_many": "{{count}} orígenes", + "sources_one": "{{count}} origen", + "sources_other": "{{count}} orígenes", + "unsupportedLayout": "Diseño no compatible en móviles", + "updatedSort": "Actualizado", + "usesFieldAscending": "Usa {{field}} en orden ascendente", + "usesFieldDescending": "Usa {{field}} en orden descendente", + "usesGitHubRankOrder": "Usa el orden de clasificación de GitHub", + "viewNumber": "Vista #{{number}}", + "viewOrder": "Orden de la vista" + }, + "prFileDiff": { + "commentOnLine": "Comentar en la línea {{line}}", + "commentPlaceholder": "Añade un comentario de revisión", + "noTextChanges": "No se encontraron cambios de texto.", + "showingDiffLines": "Se muestran las primeras {{limit}} de {{total}} líneas del diff." + }, + "projectComments": { + "comments_many": "{{count}} comentarios", + "comments_one": "{{count}} comentario", + "comments_other": "{{count}} comentarios", + "discussion": "Conversación", + "editComment": "Editar comentario", + "noComments": "No hay comentarios.", + "reopenThread": "Reabrir hilo", + "reply": "Responder", + "resolveThread": "Resolver hilo", + "resolvedCommentBy": "Comentario de {{author}} resuelto", + "resolvedThreadBy": "Hilo de {{author}} resuelto", + "show": "Mostrar" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} no se ha añadido a Orca. Añade este repositorio desde la aplicación de escritorio y luego actualiza Tareas en el móvil.", + "clearType": "Quitar tipo", + "closeItem": "Cerrar elemento", + "copyGitHubLink": "Copiar enlace de GitHub", + "copyRepository": "Copiar repositorio", + "createWorkspace": "Crear espacio de trabajo", + "draftIssue": "Issue en borrador", + "issue": "Issue", + "issueType": "Tipo de issue", + "loadingIssueTypes": "Cargando tipos de issue…", + "mergePullRequest": "Hacer merge de la pull request", + "mergeRepositoryRequirement": "Para hacer merge, el repositorio debe estar en Orca.", + "noIssueTypes": "No hay tipos de issue configurados para este repositorio.", + "noType": "Sin tipo", + "openInGitHub": "Abrir en GitHub", + "projectItem": "Elemento del proyecto", + "projectSubtitle": "Proyecto de GitHub · {{repository}}{{itemNumber}}", + "pullRequest": "Pull request", + "reopenItem": "Reabrir elemento", + "repositoryNotInOrca": "Repositorio no está en Orca", + "status": "Estado", + "type": "Tipo", + "workspaceCreationRequirement": "Solo se pueden crear espacios de trabajo a partir de issues y pull requests de GitHub." + }, + "projectFieldEditors": { + "clearField": "Vaciar campo", + "completedIteration": "Completada · {{startDate}} · {{duration}}d", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "Introduce una fecha con el formato YYYY-MM-DD.", + "invalidNumber": "Introduce un número válido.", + "noIterations": "No hay iteraciones disponibles.", + "numberPlaceholder": "Número", + "projectFields": "Campos del proyecto", + "saveField": "Guardar campo", + "textPlaceholder": "Texto", + "upcomingIteration": "En curso o próxima · {{startDate}} · {{duration}}d" + }, + "projectMetadataEditors": { + "assignees": "Asignados", + "description": "Descripción", + "labels": "Etiquetas", + "loadingAssignees": "Cargando asignados…", + "loadingLabels": "Cargando etiquetas…", + "noAssignableUsers": "No se encontraron usuarios asignables en este repositorio.", + "noDescription": "Sin descripción.", + "noLabels": "No hay etiquetas en este repositorio.", + "none": "Sin selección", + "saveDescription": "Guardar descripción", + "saveTitle": "Guardar título", + "title": "Título" + }, + "projectReviewPanels": { + "binaryFile": "Archivo binario.", + "changedFiles": "Archivos modificados", + "checks": "Checks", + "fileUnavailable": "Contenido del archivo no disponible.", + "hideFile": "Ocultar", + "loadingReviewers": "Cargando revisores…", + "markUnviewed": "Marcar no visto", + "markViewed": "Marcar visto", + "noChecks": "No se encontraron checks.", + "noReviewers": "No se solicitaron revisores.", + "noSuggestions": "No se encontraron sugerencias de revisores.", + "requestReview": "Solicitar revisión", + "requestReviewers": "Solicitar revisores", + "rerunAll": "Reejecutar todos", + "rerunFailed": "Reejecutar fallidos", + "reviewers": "Revisores", + "viewFile": "Ver" + }, + "providerControls": { + "myTodos": "Mis tareas pendientes", + "projectMergeRequests": "MR del proyecto", + "sort": "Ordenar: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "en {{base}}", + "nextPage": "Página siguiente", + "page": "Página {{page}}", + "pageOfTotal": "Página {{page}} de {{total}}", + "previousPage": "Página anterior", + "selectPage": "Seleccionar página, página {{page}}", + "selectPageOfTotal": "Seleccionar página, página {{page}} de {{total}}" + }, + "providerPickers": { + "allRepositories": "Todos los repositorios", + "githubView": "Vista de GitHub", + "issueSources": "Fuentes de issues de GitHub", + "issueSourcesDescription": "Elige si usar upstream u origin para consultar y crear issues en cada repositorio.", + "issues": "Issues", + "noIssueSources": "No hay fuentes alternativas de issues disponibles.", + "origin": "Origen", + "pageHint": "Ve a una página de resultados cargada o disponible.", + "pageLoaded": "Cargada", + "pageNotLoaded": "Carga resultados anteriores", + "pageNumber": "Página {{page}}", + "pages": "Páginas de GitHub", + "pullRequests": "Pull requests", + "queryingSource": "Consultando {{source}}", + "repoDescription": "Elige qué repositorios consultar.", + "repos": "Repositorios", + "taskSource": "Fuente de tareas", + "upstream": "Upstream" + }, + "providerViewProjection": { + "all": "Todo", + "allSites": "Todos los sitios", + "allTeams": "Todos los equipos", + "allWorkspaces": "Todos los espacios de trabajo", + "chooseProject": "Elige proyecto", + "default": "Predeterminado", + "defaultSubtitle": "{{subtitle}} · Predeterminado", + "issues": "Issues", + "list": "Lista", + "noGrouping": "Sin agrupación", + "openState": "Abierto", + "priority": "Prioridad", + "projects": "Proyectos", + "pullRequests": "PRs", + "teams_many": "{{count}} equipos", + "teams_one": "{{count}} equipo", + "teams_other": "{{count}} equipos", + "workspace": "Espacio de trabajo" + }, + "reviewerLinear": { + "issues": "Issues", + "unassigned": "Sin asignar" + }, + "screenChrome": { + "connectLinear": "Conectar Linear", + "newGitHubIssue": "Nuevo issue de GitHub", + "newLinearIssue": "Nuevo issue de Linear", + "refreshGitHub": "Actualizar trabajo de GitHub", + "refreshGitLab": "Actualizar elementos de trabajo de GitLab", + "refreshJira": "Actualizar issues de Jira", + "refreshLinear": "Actualizar Linear", + "title": "Tareas" + }, + "searchControl": { + "jiraPlaceholder": "JQL de Jira, p. ej. project = ABC AND statusCategory != Done", + "projectPlaceholder": "Buscar en la vista del proyecto…", + "providerPlaceholder": "Buscar tareas de {{provider}}…" + }, + "smartSourceModes": { + "allStates": "Todo", + "branch": "Rama", + "closedState": "Cerrado", + "mergedState": "Mergeado", + "name": "Nombre", + "openState": "Abierto", + "smart": "Inteligente" + }, + "sparsePresetDraft": { + "directoryRequired": "Agrega al menos un directorio.", + "repoRelativeDirectoriesRequired": "Usa directorios relativos al repositorio, no la raíz, rutas absolutas ni segmentos padre." + }, + "taskViewOptions": { + "allSubtitle": "Issues sin resolver en los sitios seleccionados", + "assignedSubtitle": "Issues sin resolver asignados a ti", + "doneSubtitle": "Tus issues resueltos recientemente", + "noGitHubTasks": "No hay tareas de GitHub", + "noGitLabTasks": "No hay tareas de GitLab", + "noJiraTasks": "No hay tareas de Jira", + "noLinearTasks": "No hay tareas de Linear", + "reportedSubtitle": "Issues sin resolver que has reportado" + }, + "tasksCreateDrawers": { + "connect": "Conectar", + "connectLinearWorkspace": "Conectar espacio de trabajo de Linear", + "createIssue": "Crear issue", + "createWorkspaceIn": "Crear espacio de trabajo en", + "description": "Descripción", + "descriptionPlaceholder": "Añade contexto", + "fileIn": "Crear en {{slug}}", + "issueSource": "Fuente de issues", + "keySecurityHint": "Tu clave se cifra con el llavero del sistema operativo del host y se guarda localmente.", + "linearConnectSubtitle": "Pega una clave API personal para consultar los issues de ese espacio de trabajo.", + "linearSettingsLink": "Ajustes de Linear / Seguridad / Nueva clave API", + "linearTeam": "Equipo de Linear", + "linearTeamSubtitle": "Crea un issue en el equipo de Linear seleccionado.", + "newIssueTitle": "Nuevo issue de {{providerLabel}}", + "origin": "Origen", + "personalApiKey": "Clave API personal", + "repository": "Repositorio", + "repositorySubtitle": "Crea un issue en el repositorio seleccionado.", + "team": "Equipo", + "title": "Título", + "titlePlaceholder": "Título de la tarea", + "upstream": "Upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "Terminal en blanco" + }, + "workspaceCreateDrawer": { + "addRepository": "Añade un repositorio Git antes de crear un espacio de trabajo de Linear.", + "advanced": "Avanzado", + "agent": "Agente", + "connect": "Conectar", + "connectFirst": "Conecta primero el repositorio", + "connectRepository": "Conectar repositorio", + "connecting": "Conectando…", + "createFrom": "Crear desde {{branch}}", + "defaultBranch": "Rama predeterminada", + "detectingAgents": "Detectando agentes…", + "optional": "[Opcional]", + "remoteRepository": "Repositorio remoto", + "repository": "Repositorio", + "repositoryNotFound": "No se encontró el repositorio.", + "selectRepository": "Selecciona un repositorio", + "sshConnection": "Conexión SSH", + "startFrom": "Iniciar desde", + "title": "Crear espacio de trabajo", + "workspaceName": "Nombre del espacio de trabajo" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "\"{{name}}\" ya existe.", + "nameRequired": "El nombre es obligatorio.", + "nameTooLong": "El nombre debe tener 80 caracteres o menos.", + "openShell": "Abrir un shell" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Elige una rama o referencia existente.", + "baseBranchTitle": "Iniciar desde", + "branchName": "Nombre de la rama: {{name}}", + "defaultBranch": "Rama predeterminada", + "defaultBranchSubtitle": "Usar la rama base configurada para este repositorio", + "editPreset": "Editar {{name}}", + "fullCheckout": "Checkout completo", + "fullCheckoutSubtitle": "Usar todo el repositorio", + "newPreset": "Nuevo preset", + "noBranches": "No hay ramas que coincidan.", + "searchBranches": "Buscar ramas", + "sparseCheckoutTitle": "Checkout disperso" + }, + "workspaceSshGate": { + "authenticationFailed": "Autenticación fallida", + "connected": "Conectado", + "connecting": "Conectando", + "connectionFailed": "La conexión falló", + "deployingRelay": "Desplegando Relay", + "disconnected": "Desconectado", + "reconnectFailed": "Falló la reconexión", + "reconnecting": "Reconectando" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Confiar siempre y ejecutar", + "creating": "Creando…", + "directoriesLabel": "Directorios", + "directories_many": "{{count}} directorios", + "directories_one": "{{count}} directorio", + "directories_other": "{{count}} directorios", + "dontRun": "No ejecutar", + "editSparsePreset": "Editar preajuste de checkout disperso", + "nameLabel": "Nombre", + "namePlaceholder": "Interfaz del renderizador", + "newSetupScript": "Nuevo script de configuración", + "newSparsePreset": "Nuevo preajuste de checkout disperso", + "runHooks": "Ejecutar hooks", + "runSetupAndCreate": "Ejecutar configuración y crear", + "runSetupTitle": "¿Ejecutar la configuración de {{name}}?", + "setupChangedTitle": "El script de configuración de {{name}} ha cambiado", + "setupScript": "Script de configuración", + "setupSubtitle": "{{name}} requiere que decidas si ejecutar la configuración antes de crear este espacio de trabajo.", + "setupTitle": "¿Ejecutar script de configuración?", + "skipSetupAndCreate": "Omitir configuración y crear", + "trustFailed": "No se pudo marcar el script de configuración como de confianza.", + "trustSubtitle": "El archivo orca.yaml de este repositorio se ejecuta en tu equipo antes de iniciar el espacio de trabajo. Ejecútalo solo si confías en este repositorio." + }, + "worktreeCreateRetry": { + "createFailed": "No se pudo crear el espacio de trabajo" } }, "terminal": { diff --git a/mobile/src/i18n/locales/fr.json b/mobile/src/i18n/locales/fr.json index c54c8338666..72e605e9af3 100644 --- a/mobile/src/i18n/locales/fr.json +++ b/mobile/src/i18n/locales/fr.json @@ -623,7 +623,7 @@ "moreKeys": "Autres touches — Tab, flèches, F1–F12…", "navigation": "Navigation", "pickKey": "Choisir une touche", - "pressEnter": "Appuyer sur Enter", + "pressEnter": "Appuyer sur Entrée", "shortcutCombo": "Combinaison de touches", "shortcutComboHint": "Créer des combinaisons avec Ctrl, Alt et Shift", "textMacro": "Macro de texte", @@ -1532,7 +1532,21 @@ "workspace": "Espace de travail" } }, + "newWorkspace": { + "hostPicker": { + "title": "Créer un espace de travail sur" + }, + "loadingDrawer": { + "downloadProgress": "Téléchargement… {{progress}}", + "downloading": "Téléchargement", + "loading": "Chargement" + } + }, "notifications": { + "desktopChannel": { + "name": "Notifications de l'ordinateur", + "silentName": "Notifications silencieuses Orca" + }, "notificationDeliverySection": { "footer": "Les types d'alertes suivent les paramètres de notification de chaque ordinateur appairé. Les notifications sont suspendues après 7 jours sans utilisation de cette application ; ouvrez-la et reconnectez-vous pour les réactiver.", "onlyWhenAway": "Uniquement si vous n'êtes pas à l'ordinateur", @@ -2148,7 +2162,7 @@ "advanced": "Avancé", "agent": "Agent", "agentPrompt": "Prompt d'agent", - "appendEnter": "Ajouter Enter", + "appendEnter": "Ajouter Entrée", "appendEnterDescription": "Envoie immédiatement au lieu de simplement insérer le texte.", "chooseAgent": "Choisir un agent", "commandText": "Texte de la commande", @@ -2521,7 +2535,7 @@ "defaultViewHeading": "VUE PAR DÉFAUT", "off": "Désactivé", "on": "Activé", - "openInChatUi": "Ouvrir les sessions dans Chat UI", + "openInChatUi": "Ouvrir les sessions dans l'interface de chat", "title": "Chat UI" }, "nativeNotificationDeliverySettings": { @@ -2590,11 +2604,71 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "Aucune branche de base sur laquelle rebaser", + "waitingForDesktop": "En attente de l'ordinateur…" + }, "actions": { + "checkingReviewStatus": "Vérification du statut de revue.", + "checkoutBeforePublish": "Effectuez un checkout d'une branche avant de publier des commits.", + "commitStagedChanges": "Committer les modifications indexées.", "commits": "Commits", + "committing": "Commit en cours.", "createPr": "Créer une PR", + "enterCommitMessage": "Saisissez un message de commit pour committer.", + "forcePushWithLease": "Faites un force push avec lease pour mettre à jour la branche distante.", + "forcePushing": "Force Push en cours.", + "linkedReviewUnavailable": "La branche de la revue liée est indisponible.", + "publishToOrigin": "Publier cette branche sur origin.", + "pullCommits_many": "Tirer {{count}} commits.", + "pullCommits_one": "Tirer {{count}} commit.", + "pullCommits_other": "Tirer {{count}} commits.", "pushAndCreatePr": "Pousser et créer une PR", - "switchBranch": "Changer de branche" + "pushCommits_many": "Pousser {{count}} commits.", + "pushCommits_one": "Pousser {{count}} commit.", + "pushCommits_other": "Pousser {{count}} commits.", + "pushLinkedReview": "Pousser les mises à jour vers la branche de la revue liée.", + "remoteOperationInProgress": "Opération distante en cours.", + "resolveConflicts": "Résolvez les conflits avant de committer.", + "reviewAlreadyMerged": "Rien à committer. La revue est déjà fusionnée.", + "stageAllChanges": "Indexer toutes les modifications.", + "stageFileToCommit": "Indexez au moins un fichier pour committer.", + "switchBranch": "Changer de branche", + "syncCounts": "Tirer {{behind}}, pousser {{ahead}}.", + "upToDate": "Rien à commiter. La branche est à jour.", + "waitForRemoteOperation": "Réessayez une fois l'opération distante terminée." + }, + "branchBaseRef": { + "resolveFailed": "Impossible de déterminer la base de la branche" + }, + "branchCard": { + "branchCount": "{{count}} sur la branche", + "changedCount": "Modifiés : {{count}}", + "cherryPickState": "cherry-pick", + "mergeState": "merge", + "rebaseState": "rebase", + "stagedCount": "Indexés : {{count}}" + }, + "branchCompare": { + "commits_many": "{{count}} commits", + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commits", + "files_many": "{{count}} fichiers", + "files_one": "{{count}} fichier", + "files_other": "{{count}} fichiers", + "sectionTitle": "Committé sur la branche", + "summary": "{{files}} - par rapport à {{baseRef}}", + "summaryWithCommits": "{{files}} - {{commits}} - par rapport à {{baseRef}}" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Impossible de déterminer la branche de base pour la comparaison.", + "loadFailed": "Impossible de charger les modifications committées" + }, + "branchDiffPreviewDrawer": { + "closePreview": "Fermer l'aperçu du diff committé", + "committedOnBranch": "Committé sur la branche", + "loadFailed": "Impossible de charger le diff", + "truncated": "Diff tronqué pour l'aperçu mobile." }, "commitDropdown": { "checkOutBranchToPush": "Effectuez un checkout d'une branche avant de pousser des commits", @@ -2619,8 +2693,49 @@ "stageFile": "Indexez au moins un fichier pour commiter", "useCommitAndForcePush": "Utilisez Commit & Force Push — le remote n'a que d'anciennes copies des commits locaux" }, + "commitFailurePanel": { + "fix": "Corriger", + "fixWithAi": "Corriger l'échec du commit avec l'IA", + "hideDetails": "Masquer les détails", + "hideFailureDetails": "Masquer les détails de l'échec du commit", + "showDetails": "Afficher les détails", + "showFailureDetails": "Afficher les détails de l'échec du commit", + "summary": "Échec du commit.", + "title": "Échec du commit" + }, + "commitMessageAi": { + "generateFailed": "Impossible de générer le message de commit" + }, + "commitRunners": { + "actionFailed": "Échec de l'action de contrôle de code source", + "commitFailed": "Échec du commit" + }, + "conflictAbort": { + "abortMerge": "Abandonner le merge", + "abortOperation": "Abandonner {{operation}}", + "abortRebase": "Abandonner le rebase", + "aborting": "Abandon en cours…" + }, + "content": { + "cancelGeneration": "Annuler la génération du message de commit", + "commitMessageDisabled": "Message de commit désactivé. Aucun fichier indexé.", + "commitMessagePlaceholder": "Message de commit", + "emptyMessage": "Le worktree est propre.", + "emptyTitle": "Aucune modification locale", + "generateMessage": "Générer le message de commit avec l'IA", + "noStagedFiles": "Aucun fichier indexé", + "openActions": "Ouvrir les actions de contrôle de code source", + "reconnecting": "Reconnexion à l'ordinateur…", + "regenerateHint": "Effacez le message pour le régénérer.", + "stageAll": "Tout indexer", + "unstageAll": "Tout désindexer" + }, "createPrAction": { - "createReview": "Créer une {{titleLabel}}" + "checkingStatus": "Vérification du statut de revue…", + "createPullRequest": "Créer la pull request", + "createReview": "Créer une {{titleLabel}}", + "providerUnavailable": "Création de revue indisponible pour ce fournisseur", + "statusUnavailable": "Statut de revue indisponible" }, "dropdownCounts": { "fastForwardCount_many": "Faire un fast-forward de {{count}} commits", @@ -2649,6 +2764,69 @@ "titleUnpublishedForcePushCount_one": "Faites un force push avec lease de {{count}} commit de la branche et définissez un upstream si nécessaire.", "titleUnpublishedForcePushCount_other": "Faites un force push avec lease de {{count}} commits de la branche et définissez un upstream si nécessaire." }, + "fileList": { + "committedSection": "Committé sur la branche" + }, + "fileRows": { + "addedByThem": "Ajouté chez eux", + "addedByUs": "Ajouté chez nous", + "bothAdded": "Ajouté des deux côtés", + "bothDeleted": "Supprimé des deux côtés", + "bothModified": "Modifié des deux côtés", + "committedSection": "Committé sur la branche", + "committedUnavailable": "Modifications committées indisponibles.", + "deletedByThem": "Supprimé chez eux", + "deletedByUs": "Supprimé chez nous", + "discardFile": "Abandonner les modifications de {{path}}", + "loadingCommitted": "Chargement des modifications committées…", + "openChangedFile": "Ouvrir le fichier modifié {{path}}", + "openCommittedChange": "Ouvrir la modification committée de {{path}}", + "renamedFrom": "anciennement {{path}}", + "stageFile": "Indexer {{path}}", + "unresolvedConflict": "Conflit non résolu", + "unstageFile": "Désindexer {{path}}" + }, + "gitHistory": { + "days_many": "{{count}} j", + "days_one": "{{count}} j", + "days_other": "{{count}} j", + "hours_many": "{{count}} h", + "hours_one": "{{count}} h", + "hours_other": "{{count}} h", + "justNow": "à l'instant", + "loadFailed": "Impossible de charger l'historique des commits", + "minutes_many": "{{count}} m", + "minutes_one": "{{count}} m", + "minutes_other": "{{count}} m", + "months_many": "{{count}} mois", + "months_one": "{{count}} mois", + "months_other": "{{count}} mois", + "noCommitMessage": "(aucun message de commit)", + "years_many": "{{count}} ans", + "years_one": "{{count}} an", + "years_other": "{{count}} ans" + }, + "gitHistoryList": { + "loadFailed": "Échec du chargement de l'historique", + "loadFilesFailed": "Impossible de charger les fichiers du commit", + "noCommits": "Aucun commit.", + "noFileChanges": "Aucun fichier modifié", + "retryFiles": "Réessayer de charger les fichiers du commit", + "waitingForDesktop": "En attente de l'ordinateur…" + }, + "gitStatus": { + "changes": "Modifications", + "conflicts": "Conflits", + "stagedChanges": "Modifications stagées" + }, + "header": { + "backToSession": "Retour à la session", + "close": "Fermer le contrôle de code source", + "openNumberedPrWeb": "Ouvrir la pull request #{{number}} sur le Web", + "openPrWeb": "Ouvrir la pull request sur le Web", + "refresh": "Actualiser le contrôle de code source", + "title": "Contrôle de code source" + }, "hostedReview": { "mrCopy": { "reviewLabel": "merge request", @@ -2661,9 +2839,82 @@ "titleLabel": "Pull Request" } }, + "hostedReviewCopy": { + "committingChanges": "Commit des modifications…", + "creatingReview": "Création de la revue…", + "forcePushing": "Force push avec lease…", + "generatingCommitMessage": "Génération du message de commit…", + "publishingBranch": "Publication de la branche…", + "pushingCommits": "Push des commits…", + "stagingChanges": "Indexation des modifications…", + "updatingBranch": "Mise à jour de la branche…" + }, "hostedReviewCreate": { "pushSucceeded": "Le push a réussi, mais la création de la {{shortLabel}} a échoué : {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "La branche a changé pendant la préparation de la pull request.", + "generateMessageFailed": "Impossible de générer un message de commit. Ajoutez-en un dans « Contrôle de code source », puis réessayez.", + "resolveConflicts": "Résolvez les conflits avant de créer une pull request.", + "resolveOrStageChanges": "Résolvez les conflits ou indexez les modifications avant de créer une pull request.", + "reviewCommitMessage": "Relisez le message de commit, puis réessayez Créer une PR." + }, + "hostedReviewGitPreparation": { + "commitFailed": "Échec du commit", + "refreshFailed": "Impossible d'actualiser le contrôle de code source", + "stageFailed": "Impossible d'indexer les modifications", + "updateBranchFailed": "Impossible de mettre à jour la branche distante. Réessayez Créer une PR." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "Échec du force push avec lease", + "publishFailed": "Impossible de publier la branche", + "pushFailed": "Impossible de pousser les commits" + }, + "hostedReviewService": { + "createFailed": "Impossible de créer la pull request", + "pushBeforeCreateFailed": "Le push a échoué. Résolvez l'erreur de push, puis réessayez." + }, + "hubTab": { + "changes": "Modifications", + "commits": "Commits", + "pullRequest": "Pull Request" + }, + "loaders": { + "connectingToDesktop": "Connexion à l'ordinateur…", + "loadFailed": "Impossible de charger le contrôle de code source", + "updateDesktop": "Mettez à jour Orca sur votre ordinateur pour utiliser le contrôle de code source sur mobile.", + "waitingForDesktop": "En attente de l'ordinateur…" + }, + "modals": { + "actionsTitle": "Contrôle de code source", + "currentBranch": "actuelle", + "discardButton": "Abandonner", + "discardConfirmMessage": "Abandonner les modifications de « {{path}} » ? Cette action est irréversible.", + "discardTitle": "Abandonner la modification", + "openPrMessage": "L'ouvrir dans votre navigateur ?", + "openPrWithWarning": "L'ouvrir dans votre navigateur ?\n\n{{warning}}", + "prCreatedTitle": "Pull request créée", + "switchBranchTitle": "Changer de branche" + }, + "openers": { + "openDiffFailed": "Impossible d'ouvrir le diff", + "tabNotReady": "Le fichier est ouvert, mais son onglet n'est pas encore prêt. Réessayez.", + "waitingForDesktop": "En attente de l'ordinateur…" + }, + "panel": { + "loadFailedTitle": "Chargement impossible", + "unavailableTitle": "Contrôle de code source indisponible" + }, + "prChip": { + "createPr": "Créer la pull request", + "loading": "Chargement de la pull request…", + "loadingLabel": "Chargement de la pull request", + "openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Ouvrir la pull request.", + "openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaires non résolus. Ouvrir la pull request.", + "openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaire non résolu. Ouvrir la pull request.", + "openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaires non résolus. Ouvrir la pull request.", + "unavailableLabel": "Pull request indisponible : {{message}}" + }, "prCreate": { "authRequired": "Authentifiez-vous avant de créer une {{reviewLabel}}.", "baseNotOnRemote": "Poussez la branche de base avant de créer une {{reviewLabel}}.", @@ -2682,8 +2933,19 @@ "unsupportedMergeRequests": "La création de merge requests n'est pas prise en charge pour ce dépôt.", "unsupportedPullRequests": "La création de pull requests n'est pas prise en charge pour ce dépôt." }, + "prLink": { + "updatePullRequestFailed": "Impossible de mettre à jour la pull request liée", + "updateReviewFailed": "Impossible de mettre à jour la revue liée" + }, "primaryAction": { - "forcePushFromDesktop": "Faites un force push de la branche de cette pull request depuis l'ordinateur" + "commit": "Commit", + "forcePush": "Force Push", + "forcePushFromDesktop": "Faites un force push de la branche de cette pull request depuis l'ordinateur", + "publishBranch": "Publier la branche", + "pull": "Pull", + "push": "Push", + "stageAll": "Tout indexer", + "sync": "Synchroniser" }, "remoteDropdown": { "branchAlreadyPublished": "La branche est déjà publiée", @@ -2733,6 +2995,600 @@ "tryFastForwardPull": "Tentez un pull en fast-forward ; git peut rejeter les commits locaux", "tryRegularPush": "Tentez un push normal ; git peut exiger un force push", "useForcePushToSync": "Utilisez Force Push — le remote n'a que d'anciennes copies des commits locaux" + }, + "runners": { + "actionFailed": "Échec de l'action de contrôle de code source" + }, + "screenState": { + "noBranch": "Aucune branche" + }, + "state": { + "noUpstream": "Aucune branche de suivi", + "syncStatus": "{{ahead}} en avance, {{behind}} en retard" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Échec du lancement de l'agent", + "waitingForDesktop": "En attente de l'ordinateur…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Impossible de générer le message de commit" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Effectuez un checkout sur une branche avant de créer une pull request." + }, + "useMobileGitRequests": { + "actionFailed": "Échec de l'action de contrôle de code source", + "branchUnavailable": "État de la branche indisponible", + "commitFailed": "Échec du commit", + "waitingForDesktop": "En attente de l'ordinateur…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "Échec de la résolution de la branche de base.", + "forkPushWarning": "L'option « Autoriser les modifications des mainteneurs » est désactivée pour cette PR ; le push vers le fork peut être refusé par GitHub." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Ajouter un commentaire", + "comments_many": "{{count}} commentaires", + "comments_one": "{{count}} commentaire", + "comments_other": "{{count}} commentaires", + "reopenThread": "Rouvrir le fil", + "reply": "Répondre", + "resolveThread": "Résoudre le fil", + "resolvedCommentBy": "Commentaire de {{author}} résolu", + "resolvedThreadBy": "Fil de {{author}} résolu", + "sendComment": "Envoyer le commentaire", + "show": "Afficher" + }, + "filterPickers": { + "allTeams": "Toutes les équipes", + "changeStatus": "Changer le statut", + "fieldHidden": "Masqué sur les cartes", + "fieldShown": "Affiché sur les cartes", + "fieldsSubtitle": "Choisissez les champs du projet à afficher sur les cartes des éléments.", + "fieldsTitle": "Champs du projet", + "gitlabFilter": "Filtre GitLab", + "gitlabView": "Vue GitLab", + "jiraFilter": "Filtre Jira", + "jiraSite": "Site Jira", + "linearFilter": "Filtre Linear", + "linearIssue": "Ticket Linear", + "linearWorkspace": "Espace de travail Linear", + "loadingStates": "Chargement des statuts…", + "noFields": "Cette vue n'a aucun champ supplémentaire à afficher.", + "noStates": "Aucun statut disponible", + "switchWorkspaceFailed": "Impossible de changer d'espace de travail", + "teamsSubtitle": "Choisissez les équipes à afficher dans Tâches.", + "teamsTitle": "Équipes Linear", + "teams_many": "{{count}} équipes", + "teams_one": "{{count}} équipe", + "teams_other": "{{count}} équipes" + }, + "githubProjectList": { + "browseProjects": "Parcourir les projets", + "chooseProject": "Choisissez un projet GitHub", + "emptyField": "Vide", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "Élément de projet · {{repository}}{{number}}", + "items": "Éléments", + "moreFields_many": "+{{count}} champs", + "moreFields_one": "+{{count}} champ", + "moreFields_other": "+{{count}} champs", + "noItems": "Aucun élément de projet", + "pullRequestSubtitle": "Pull request · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Ajouter", + "addByUrlHint": "Utilisez « Ajouter par URL » pour accéder aux projets manquants.", + "addPlaceholder": "Ajouter par URL ou propriétaire/numéro", + "adding": "Ajout…", + "browseAll": "Tout parcourir", + "browseLoading": "Tout parcourir (chargement…)", + "chooseView": "Choisir une vue de projet", + "loadFailed": "Échec du chargement des projets", + "noMatches": "Aucun projet correspondant.", + "noMoreProjects": "Aucun autre projet.", + "noProjects": "Aucun projet chargé", + "organizationsError": "organisations : {{message}}", + "organizationsLoadFailed": "Certaines organisations n'ont pas pu être chargées ({{count}}).", + "ownerLoadFailed": "Impossible de charger les projets de {{owner}}.", + "pin": "Épingler", + "pinned": "Épinglés", + "recent": "Récents", + "retryHint": "Touchez pour réessayer.", + "searchProjects": "Rechercher des projets", + "sort": "Tri du projet", + "subtitle": "Choisissez une vue de projet pour la page Tâches.", + "title": "GitHub Projects", + "unsupportedLayout": "Orca ne prend pas encore en charge cette disposition de projet GitHub.", + "view": "Vue de projet" + }, + "githubViewControls": { + "fields": "Champs : {{fields}}", + "openView": "Ouvrir la vue dans GitHub", + "sort": "Tri : {{sort}}", + "source": "Source : {{source}}" + }, + "itemActions": { + "changeStatus": "Changer le statut", + "copyGitHubLink": "Copier le lien GitHub", + "copyLinearLink": "Copier le lien Linear", + "createWorkspace": "Créer un espace de travail", + "creating": "Création…", + "mergeConflicts": "GitHub signale des conflits de fusion.", + "mergeMergeRequest": "Fusionner la merge request", + "mergePullRequest": "Fusionner la pull request" + }, + "itemDetailContent": { + "addSubIssue": "Ajouter un sous-ticket", + "assignee": "Assigné", + "assignees": "Assignés", + "checks": "Vérifications", + "description": "Description", + "discussion": "Discussion", + "noChecks": "Aucune vérification trouvée.", + "noComments": "Aucun commentaire.", + "noPipelineRuns": "Aucune exécution de pipeline pour cette MR.", + "noSubIssues": "Aucun sous-ticket.", + "none": "Aucun", + "pipeline": "Pipeline", + "pipelineJobs_many": "{{count}} jobs", + "pipelineJobs_one": "{{count}} job", + "pipelineJobs_other": "{{count}} jobs", + "project": "Projet", + "rerunAll": "Tout relancer", + "rerunFailed": "Relancer les vérifications échouées", + "status": "Statut", + "subIssueTitle": "Titre du sous-ticket", + "subIssues": "Sous-tickets", + "type": "Type" + }, + "itemDetailDrawer": { + "refreshDetails": "Actualiser les détails" + }, + "itemFieldEditors": { + "addLabels": "Étiquettes à ajouter, séparées par des virgules", + "addUsernames": "Noms d'utilisateur à ajouter, séparés par des virgules", + "assignees": "Assignés", + "labels": "Étiquettes", + "loadingAssignees": "Chargement des assignés…", + "loadingLabels": "Chargement des étiquettes…", + "noAssignableUsers": "Aucun utilisateur assignable trouvé pour ce dépôt.", + "noLabels": "Aucune étiquette dans ce dépôt.", + "none": "Aucun élément", + "removeLabels": "Étiquettes à supprimer, séparées par des virgules", + "removeUsernames": "Noms d'utilisateur à supprimer, séparés par des virgules", + "saveTitle": "Enregistrer le titre", + "title": "Titre", + "updateAssignees": "Mettre à jour les assignés", + "updateLabels": "Mettre à jour les étiquettes" + }, + "itemReviewSections": { + "binaryFile": "Fichier binaire.", + "changedFilesTitle": "Fichiers modifiés", + "descriptionPlaceholder": "Description", + "fileContentsUnavailable": "Contenu du fichier indisponible.", + "hideFile": "Masquer", + "loadingReviewers": "Chargement des reviewers…", + "markUnviewed": "Marquer comme non consulté", + "markViewed": "Marquer comme consulté", + "noDescription": "Aucune description.", + "noReviewerSuggestions": "Aucune suggestion de reviewer trouvée.", + "noReviewersRequested": "Aucun reviewer demandé.", + "requestReview": "Demander une revue", + "reviewersPlaceholder": "Demander des reviewers", + "reviewersTitle": "Reviewers", + "saveDescription": "Enregistrer la description", + "viewFile": "Afficher" + }, + "legacySurface": { + "loadIssuesFailed": "Impossible de charger les issues de {{source}}.", + "mergeAction": "Merge", + "mergeMethodTitle": "Méthode de merge", + "mergePullRequestTitle": "Merger la pull request", + "mergeRequestMergeMessage": "Choisissez comment fusionner cette merge request.", + "mergeRequestTitle": "Merge Request", + "pullRequestMergeMessage": "Choisissez comment merger cette pull request.", + "retryLoadingIssues": "Réessayer de charger les issues de {{source}}", + "retrying": "Nouvelle tentative…", + "sourceFallback": "La source d'issues privilégiée upstream est indisponible pour {{repo}}. Utilisation d'origin.", + "subIssueDataUnavailable": "Les données de sub-issues ne sont pas disponibles avec votre token.", + "updateItemTitle": "Mettre à jour l'élément" + }, + "linearList": { + "changeStatusFrom": "Changer le statut actuel : {{status}}" + }, + "linearViewControls": { + "displayButton": "Affichage", + "groupLabel": "Grouper par : {{group}}", + "orderLabel": "Trier par : {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Propriétés affichées", + "linearGroupTitle": "Grouper les issues Linear", + "linearOrderTitle": "Trier les issues Linear", + "linearViewTitle": "Vue Linear", + "sortTasksTitle": "Trier les tâches" + }, + "listSurface": { + "connectLinearButton": "Connecter Linear", + "connectLinearMessage": "Parcourez les issues Linear qui vous sont assignées et commencez à y travailler directement depuis Tâches.", + "connectLinearTitle": "Connectez votre compte Linear", + "jiraStatusFailed": "Impossible de lire le statut Jira", + "updateDesktopMessage": "Cette vue Tâches sur mobile nécessite une version plus récente d'Orca Desktop.", + "updateDesktopTitle": "Mettre à jour Orca Desktop" + }, + "options": { + "all": "Tous", + "assignedToMe": "Assignés à moi", + "assignee": "Assigné", + "board": "Tableau", + "boardDescription": "Issues regroupées en colonnes", + "closedState": "Fermé", + "completedState": "Terminé", + "createdState": "Créé", + "githubAssignedIssuesDescription": "Issues ouvertes qui vous sont assignées", + "githubDescription": "Issues et pull requests", + "githubIssuesDescription": "Issues GitHub", + "githubOpenIssuesDescription": "Issues GitHub ouvertes", + "githubProjectsDescription": "Vues GitHub Projects", + "githubPullRequestsDescription": "Pull requests GitHub", + "gitlabAllDescription": "Tous les états GitLab", + "gitlabClosedDescription": "Issues et merge requests fermées", + "gitlabDescription": "Issues et merge requests", + "gitlabMergedDescription": "Merge requests fusionnées", + "gitlabOpenDescription": "Issues et merge requests ouvertes", + "identifier": "Identifiant", + "issues": "Tickets", + "jiraDescription": "Tickets assignés et signalés", + "labels": "Étiquettes", + "linearAllDescription": "Issues ouvertes dans les espaces de travail connectés", + "linearAssignedDescription": "Issues qui vous sont assignées", + "linearCompletedDescription": "Issues récemment terminées", + "linearCreatedDescription": "Issues créées par vous", + "linearDescription": "Issues assignées et issues d'équipe", + "list": "Liste", + "listDescription": "Lignes d'issues compactes", + "mergedState": "Fusionnés", + "mine": "À moi", + "myIssues": "Mes issues", + "myPullRequestsDescription": "Pull requests créées par vous", + "myTodos": "Mes tâches à faire", + "myTodosDescription": "Tâches à faire GitLab en attente", + "needsReview": "En attente de relecture", + "noGrouping": "Aucun regroupement", + "openPullRequestsDescription": "Pull requests ouvertes", + "openState": "Ouvert", + "priority": "Priorité", + "projectMergeRequests": "MR du projet", + "projectMergeRequestsDescription": "Merge requests et issues par dépôt", + "projects": "Projets", + "pullRequests": "PRs", + "repository": "Dépôt", + "repositorySortDescription": "Par dépôt, puis par activité la plus récente", + "reviewRequestsDescription": "Demandes de revue qui vous sont assignées", + "status": "Statut", + "team": "Équipe", + "updated": "Mis à jour", + "updatedSortDescription": "Activité la plus récente d'abord" + }, + "pickerProjection": { + "allRepos": "Tous les dépôts", + "allSites": "Tous les sites", + "currentlyAscending": "Tri croissant · touchez pour passer en décroissant", + "currentlyDescending": "Tri décroissant · touchez pour passer en croissant", + "fieldAscending": "{{field}} · ordre croissant", + "fieldDescending": "{{field}} · ordre décroissant", + "fields": "Champs", + "repos_many": "{{count}} dépôts", + "repos_one": "{{count}} dépôt", + "repos_other": "{{count}} dépôts", + "selectTarget": "Sélectionner la cible", + "selectedFields": "{{selected}}/{{total}} champs", + "sortAscending": "Trier par ordre croissant", + "sources_many": "{{count}} sources", + "sources_one": "{{count}} source", + "sources_other": "{{count}} sources", + "unsupportedLayout": "Disposition non prise en charge sur mobile", + "updatedSort": "Mis à jour", + "usesFieldAscending": "Tri croissant par {{field}}", + "usesFieldDescending": "Tri décroissant par {{field}}", + "usesGitHubRankOrder": "Utilise l'ordre de classement GitHub", + "viewNumber": "Vue n° {{number}}", + "viewOrder": "Ordre de la vue" + }, + "prFileDiff": { + "commentOnLine": "Commenter la ligne {{line}}", + "commentPlaceholder": "Ajouter un commentaire de revue", + "noTextChanges": "Aucune modification de texte trouvée.", + "showingDiffLines": "Affichage des {{limit}} premières lignes du diff sur {{total}}." + }, + "projectComments": { + "comments_many": "{{count}} commentaires", + "comments_one": "{{count}} commentaire", + "comments_other": "{{count}} commentaires", + "discussion": "Discussion", + "editComment": "Modifier le commentaire", + "noComments": "Aucun commentaire.", + "reopenThread": "Rouvrir le fil", + "reply": "Répondre", + "resolveThread": "Résoudre le fil", + "resolvedCommentBy": "Commentaire de {{author}} résolu", + "resolvedThreadBy": "Fil de {{author}} résolu", + "show": "Afficher" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} n'a pas été ajouté à Orca. Ajoutez ce dépôt depuis l'application de bureau, puis actualisez la section Tâches sur mobile.", + "clearType": "Effacer le type", + "closeItem": "Fermer l'élément", + "copyGitHubLink": "Copier le lien GitHub", + "copyRepository": "Copier le nom du dépôt", + "createWorkspace": "Créer un espace de travail", + "draftIssue": "Issue en brouillon", + "issue": "Issue", + "issueType": "Type de ticket", + "loadingIssueTypes": "Chargement des types de tickets…", + "mergePullRequest": "Merger la pull request", + "mergeRepositoryRequirement": "Ce dépôt doit être ajouté à Orca pour effectuer le merge.", + "noIssueTypes": "Aucun type de ticket configuré pour ce dépôt.", + "noType": "Aucun type", + "openInGitHub": "Ouvrir dans GitHub", + "projectItem": "Élément du projet", + "projectSubtitle": "Projet GitHub · {{repository}}{{itemNumber}}", + "pullRequest": "Pull request", + "reopenItem": "Rouvrir l'élément", + "repositoryNotInOrca": "Dépôt absent d'Orca", + "status": "Statut", + "type": "Type", + "workspaceCreationRequirement": "Les espaces de travail ne peuvent être créés qu'à partir d'issues et de pull requests GitHub." + }, + "projectFieldEditors": { + "clearField": "Effacer le champ", + "completedIteration": "Terminée · {{startDate}} · {{duration}} j", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "Saisissez une date au format YYYY-MM-DD.", + "invalidNumber": "Saisissez un nombre valide.", + "noIterations": "Aucune itération disponible.", + "numberPlaceholder": "Nombre", + "projectFields": "Champs du projet", + "saveField": "Enregistrer le champ", + "textPlaceholder": "Texte", + "upcomingIteration": "En cours et à venir · {{startDate}} · {{duration}} j" + }, + "projectMetadataEditors": { + "assignees": "Assignés", + "description": "Description", + "labels": "Étiquettes", + "loadingAssignees": "Chargement des assignés…", + "loadingLabels": "Chargement des étiquettes…", + "noAssignableUsers": "Aucun utilisateur à qui assigner des éléments dans ce dépôt.", + "noDescription": "Aucune description.", + "noLabels": "Aucune étiquette dans ce dépôt.", + "none": "Aucun élément", + "saveDescription": "Enregistrer la description", + "saveTitle": "Enregistrer le titre", + "title": "Titre" + }, + "projectReviewPanels": { + "binaryFile": "Fichier binaire.", + "changedFiles": "Fichiers modifiés", + "checks": "Vérifications", + "fileUnavailable": "Contenu du fichier indisponible.", + "hideFile": "Masquer", + "loadingReviewers": "Chargement des reviewers…", + "markUnviewed": "Marquer comme non consulté", + "markViewed": "Marquer comme consulté", + "noChecks": "Aucune vérification trouvée.", + "noReviewers": "Aucun reviewer demandé.", + "noSuggestions": "Aucune suggestion de reviewer trouvée.", + "requestReview": "Demander une revue", + "requestReviewers": "Demander des reviewers", + "rerunAll": "Tout relancer", + "rerunFailed": "Relancer celles en échec", + "reviewers": "Reviewers", + "viewFile": "Afficher" + }, + "providerControls": { + "myTodos": "Mes tâches à faire", + "projectMergeRequests": "MR du projet", + "sort": "Tri : {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "vers {{base}}", + "nextPage": "Page suivante", + "page": "Page {{page}}", + "pageOfTotal": "Page {{page}} sur {{total}}", + "previousPage": "Page précédente", + "selectPage": "Sélectionner une page, page {{page}}", + "selectPageOfTotal": "Sélectionner une page, page {{page}} sur {{total}}" + }, + "providerPickers": { + "allRepositories": "Tous les dépôts", + "githubView": "Vue GitHub", + "issueSources": "Sources des tickets GitHub", + "issueSourcesDescription": "Pour chaque dépôt, choisissez upstream ou origin pour rechercher et créer des tickets.", + "issues": "Tickets", + "noIssueSources": "Aucune autre source de tickets disponible.", + "origin": "Origine", + "pageHint": "Accédez à une page de résultats chargée ou disponible.", + "pageLoaded": "Chargée", + "pageNotLoaded": "Charge des résultats plus anciens", + "pageNumber": "Page {{page}}", + "pages": "Pages GitHub", + "pullRequests": "Pull requests", + "queryingSource": "Recherche dans {{source}}", + "repoDescription": "Choisissez les dépôts à interroger.", + "repos": "Dépôts", + "taskSource": "Source des tâches", + "upstream": "Upstream" + }, + "providerViewProjection": { + "all": "Tous", + "allSites": "Tous les sites", + "allTeams": "Toutes les équipes", + "allWorkspaces": "Tous les espaces de travail", + "chooseProject": "Choisir le projet", + "default": "Par défaut", + "defaultSubtitle": "{{subtitle}} · Par défaut", + "issues": "Tickets", + "list": "Liste", + "noGrouping": "Aucun regroupement", + "openState": "Ouvert", + "priority": "Priorité", + "projects": "Projets", + "pullRequests": "PRs", + "teams_many": "{{count}} équipes", + "teams_one": "{{count}} équipe", + "teams_other": "{{count}} équipes", + "workspace": "Espace de travail" + }, + "reviewerLinear": { + "issues": "Tickets", + "unassigned": "Non assigné" + }, + "screenChrome": { + "connectLinear": "Connecter Linear", + "newGitHubIssue": "Nouveau ticket GitHub", + "newLinearIssue": "Nouveau ticket Linear", + "refreshGitHub": "Actualiser le travail GitHub", + "refreshGitLab": "Actualiser les éléments de travail GitLab", + "refreshJira": "Actualiser les tickets Jira", + "refreshLinear": "Actualiser Linear", + "title": "Tâches" + }, + "searchControl": { + "jiraPlaceholder": "JQL Jira, p. ex. project = ABC AND statusCategory != Done", + "projectPlaceholder": "Rechercher dans la vue du projet…", + "providerPlaceholder": "Rechercher des tâches {{provider}}…" + }, + "smartSourceModes": { + "allStates": "Toutes", + "branch": "Branche", + "closedState": "Fermées", + "mergedState": "Fusionnées", + "name": "Nom", + "openState": "Ouvertes", + "smart": "Intelligent" + }, + "sparsePresetDraft": { + "directoryRequired": "Ajoutez au moins un répertoire.", + "repoRelativeDirectoriesRequired": "Utilisez des répertoires relatifs au dépôt, pas la racine, des chemins absolus ni des segments parent." + }, + "taskViewOptions": { + "allSubtitle": "Tickets non résolus sur les sites sélectionnés", + "assignedSubtitle": "Tickets non résolus qui vous sont assignés", + "doneSubtitle": "Vos tickets récemment résolus", + "noGitHubTasks": "Aucune tâche GitHub", + "noGitLabTasks": "Aucune tâche GitLab", + "noJiraTasks": "Aucune tâche Jira", + "noLinearTasks": "Aucune tâche Linear", + "reportedSubtitle": "Tickets non résolus que vous avez signalés" + }, + "tasksCreateDrawers": { + "connect": "Se connecter", + "connectLinearWorkspace": "Connecter un espace de travail Linear", + "createIssue": "Créer un ticket", + "createWorkspaceIn": "Créer un espace de travail dans", + "description": "Description", + "descriptionPlaceholder": "Ajouter du contexte", + "fileIn": "Créer dans {{slug}}", + "issueSource": "Source des issues", + "keySecurityHint": "Votre clé est chiffrée via le trousseau du système d'exploitation de l'hôte et stockée localement.", + "linearConnectSubtitle": "Collez une clé d'API personnelle pour parcourir les tickets de cet espace de travail.", + "linearSettingsLink": "Paramètres Linear / Sécurité / Nouvelle clé d'API", + "linearTeam": "Équipe Linear", + "linearTeamSubtitle": "Créez un ticket dans l'équipe Linear sélectionnée.", + "newIssueTitle": "Nouveau ticket {{providerLabel}}", + "origin": "Origine", + "personalApiKey": "Clé d'API personnelle", + "repository": "Dépôt", + "repositorySubtitle": "Créez un ticket dans le dépôt sélectionné.", + "team": "Équipe", + "title": "Titre", + "titlePlaceholder": "Titre de la tâche", + "upstream": "Upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "Terminal vierge" + }, + "workspaceCreateDrawer": { + "addRepository": "Ajoutez un dépôt Git avant de créer un espace de travail Linear.", + "advanced": "Avancé", + "agent": "Agent", + "connect": "Se connecter", + "connectFirst": "Connectez d'abord le dépôt", + "connectRepository": "Connecter le dépôt", + "connecting": "Connexion…", + "createFrom": "Créer à partir de {{branch}}", + "defaultBranch": "Branche par défaut", + "detectingAgents": "Détection des agents…", + "optional": "[Optionnel]", + "remoteRepository": "Dépôt distant", + "repository": "Dépôt", + "repositoryNotFound": "Dépôt introuvable.", + "selectRepository": "Sélectionner un dépôt", + "sshConnection": "Connexion SSH", + "startFrom": "À partir de", + "title": "Créer un espace de travail", + "workspaceName": "Nom de l'espace de travail" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "Un préréglage nommé « {{name}} » existe déjà.", + "nameRequired": "Le nom est obligatoire.", + "nameTooLong": "Le nom doit contenir au maximum 80 caractères.", + "openShell": "Ouvrir un shell" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Choisissez une branche ou une référence existante.", + "baseBranchTitle": "À partir de", + "branchName": "Nom de la branche : {{name}}", + "defaultBranch": "Branche par défaut", + "defaultBranchSubtitle": "Utiliser la branche de base configurée pour ce dépôt", + "editPreset": "Modifier {{name}}", + "fullCheckout": "Extraction complète", + "fullCheckoutSubtitle": "Utiliser l'ensemble du dépôt", + "newPreset": "Nouveau préréglage", + "noBranches": "Aucune branche correspondante.", + "searchBranches": "Rechercher des branches", + "sparseCheckoutTitle": "Extraction partielle" + }, + "workspaceSshGate": { + "authenticationFailed": "Échec de l'authentification", + "connected": "Connecté", + "connecting": "Connexion", + "connectionFailed": "Échec de la connexion", + "deployingRelay": "Déploiement du relais", + "disconnected": "Déconnecté", + "reconnectFailed": "Échec de la reconnexion", + "reconnecting": "Reconnexion" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Toujours faire confiance et exécuter", + "creating": "Création…", + "directoriesLabel": "Répertoires", + "directories_many": "{{count}} répertoires", + "directories_one": "{{count}} répertoire", + "directories_other": "{{count}} répertoires", + "dontRun": "Ne pas exécuter", + "editSparsePreset": "Modifier le préréglage de checkout partiel", + "nameLabel": "Nom", + "namePlaceholder": "Interface de rendu", + "newSetupScript": "Nouveau script de setup", + "newSparsePreset": "Nouveau préréglage de checkout partiel", + "runHooks": "Exécuter les hooks", + "runSetupAndCreate": "Exécuter le setup et créer", + "runSetupTitle": "Exécuter le setup de {{name}} ?", + "setupChangedTitle": "Le script de setup de {{name}} a changé", + "setupScript": "Script de setup", + "setupSubtitle": "Choisissez si vous souhaitez exécuter le setup de {{name}} avant de créer cet espace de travail.", + "setupTitle": "Exécuter le script de setup ?", + "skipSetupAndCreate": "Ignorer le setup et créer", + "trustFailed": "Échec de l'approbation du script de setup.", + "trustSubtitle": "Le fichier orca.yaml de ce dépôt s'exécute sur votre machine avant le démarrage de l'espace de travail. Ne l'exécutez que si vous faites confiance à ce dépôt." + }, + "worktreeCreateRetry": { + "createFailed": "Échec de la création de l'espace de travail" } }, "terminal": { diff --git a/mobile/src/i18n/locales/ja.json b/mobile/src/i18n/locales/ja.json index 83eabcfa7d6..64388bf8786 100644 --- a/mobile/src/i18n/locales/ja.json +++ b/mobile/src/i18n/locales/ja.json @@ -117,7 +117,7 @@ "autocompleteOn": "オン", "defaultText": "標準(100%)", "keepPhoneSize": "スマートフォンサイズを維持(デフォルト)", - "keyboardInputDescription": "自動補完、自動修正、スペル候補は、バッファー方式のコマンド入力にのみ適用されます。キーボード上部の二重矢印ボタンでライブ入力から切り替えると、「送信」をタップする前にコマンドを編集できます。コマンド、フラグ、パスが書き換わるのを防ぐため、デフォルトではオフです。", + "keyboardInputDescription": "自動補完、自動修正、スペル候補は、バッファー方式のコマンド入力にのみ適用されます。キーボード上部の二重矢印ボタンでリアルタイム入力から切り替えると、「送信」をタップする前にコマンドを編集できます。コマンド、フラグ、パスが書き換わるのを防ぐため、デフォルトではオフです。", "keyboardInputHeading": "キーボード入力", "largeText": "大(125%)", "largerText": "特大(150%)", @@ -277,7 +277,7 @@ "notice": { "compaction": "コンテキストを圧縮しました", "contextCleared": "コンテキストをクリアしました", - "plan": "計画", + "plan": "プラン", "stoppedManually": "手動で停止しました" }, "orcaStop": { @@ -388,10 +388,10 @@ "empty": "タスクがありません", "finished": "{{task}} を完了しました", "inProgress": "進行中", - "pending": "未着手", + "pending": "保留中", "progress": "{{total}} 件中 {{completed}} 件のタスクが完了しました", "removed": "{{task}} を削除しました", - "reset": "未着手に変更しました:{{task}}", + "reset": "保留中としてマーク: {{task}}", "showAll": "完全なタスクリスト", "started": "{{task}} を開始しました", "taskStatus": "{{status}}:{{task}}", @@ -1491,7 +1491,21 @@ "workspace": "ワークスペース" } }, + "newWorkspace": { + "hostPicker": { + "title": "ワークスペースの作成先ホスト" + }, + "loadingDrawer": { + "downloadProgress": "ダウンロード中… {{progress}}", + "downloading": "ダウンロード中", + "loading": "読み込み中" + } + }, "notifications": { + "desktopChannel": { + "name": "デスクトップ通知", + "silentName": "Orca のサイレント通知" + }, "notificationDeliverySection": { "footer": "通知の種類は、ペアリング済みの各デスクトップの通知設定に従います。このアプリを7日間使用しないと通知が一時停止します。再開するには、アプリを開いて再接続してください。", "onlyWhenAway": "デスクトップから離れているときのみ", @@ -1700,7 +1714,7 @@ "stackChangesRequested": "#{{number}} で変更が要求されています。", "stackClosed": "#{{number}} はクローズされています。", "stackConflicts": "#{{number}} にマージの競合があります。", - "stackDraft": "#{{number}} はまだドラフトです。", + "stackDraft": "#{{number}} はまだ下書きです。", "stackReviewRequired": "#{{number}} はまだレビューの承認が必要です。" }, "prCheckDetail": { @@ -2162,7 +2176,7 @@ "draftsHint": "画面を離れる前に、スマートフォンの下書きをコピーするか破棄してください。", "file": "ファイル", "markdown": "Markdown", - "markdownNote": "Markdown メモ", + "markdownNote": "Markdown ノート", "newBrowser": "新規ブラウザ", "newTab": "新規タブ", "notesCopied": "メモをコピーしました。", @@ -2452,7 +2466,7 @@ "defaultViewHeading": "デフォルトの表示", "off": "オフ", "on": "オン", - "openInChatUi": "セッションを Chat UI で開く", + "openInChatUi": "セッションをチャット UI で開く", "title": "Chat UI" }, "nativeNotificationDeliverySettings": { @@ -2520,11 +2534,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "リベース先のベースブランチがありません。", + "waitingForDesktop": "デスクトップへの接続を待機中…" + }, "actions": { + "checkingReviewStatus": "レビュー状態を確認中です。", + "checkoutBeforePublish": "コミットを公開する前にブランチをチェックアウトしてください。", + "commitStagedChanges": "ステージ済みの変更をコミットします。", "commits": "コミット", + "committing": "コミット中です。", "createPr": "PR を作成", + "enterCommitMessage": "コミットするには、コミットメッセージを入力してください。", + "forcePushWithLease": "lease 付きで強制プッシュしてリモートブランチを更新します。", + "forcePushing": "強制プッシュ中です。", + "linkedReviewUnavailable": "リンクされたレビューのブランチを利用できません。", + "publishToOrigin": "このブランチを origin に公開します。", + "pullCommits_one": "{{count}} 件のコミットをプルします。", + "pullCommits_other": "{{count}} 件のコミットをプルします。", "pushAndCreatePr": "プッシュして PR を作成", - "switchBranch": "ブランチを切り替え" + "pushCommits_one": "{{count}} 件のコミットをプッシュします。", + "pushCommits_other": "{{count}} 件のコミットをプッシュします。", + "pushLinkedReview": "リンクされたレビューのブランチに更新をプッシュします。", + "remoteOperationInProgress": "リモート操作を実行中です。", + "resolveConflicts": "コミットする前に競合を解決してください。", + "reviewAlreadyMerged": "コミットするものがありません。レビューはすでにマージ済みです。", + "stageAllChanges": "すべての変更をステージします。", + "stageFileToCommit": "コミットするには、ファイルを 1 つ以上ステージしてください。", + "switchBranch": "ブランチを切り替え", + "syncCounts": "{{behind}} 件をプルし、{{ahead}} 件をプッシュします。", + "upToDate": "コミットするものがありません。ブランチは最新です。", + "waitForRemoteOperation": "リモート操作が完了してから再試行してください。" + }, + "branchBaseRef": { + "resolveFailed": "ベースブランチを特定できませんでした。" + }, + "branchCard": { + "branchCount": "ブランチ内 {{count}} 件", + "changedCount": "変更 {{count}} 件", + "cherryPickState": "チェリーピック", + "mergeState": "マージ", + "rebaseState": "リベース", + "stagedCount": "ステージ済み {{count}} 件" + }, + "branchCompare": { + "commits_one": "{{count}} 件のコミット", + "commits_other": "{{count}} 件のコミット", + "files_one": "{{count}} 個のファイル", + "files_other": "{{count}} 個のファイル", + "sectionTitle": "ブランチのコミット済み変更", + "summary": "{{files}} - {{baseRef}} との比較", + "summaryWithCommits": "{{files}} - {{commits}} - {{baseRef}} との比較" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "比較用のベースブランチを特定できませんでした。", + "loadFailed": "コミット済みの変更を読み込めませんでした。" + }, + "branchDiffPreviewDrawer": { + "closePreview": "コミット済みの差分プレビューを閉じる", + "committedOnBranch": "ブランチでコミット済み", + "loadFailed": "差分を読み込めません", + "truncated": "モバイルでのプレビュー用に差分を一部省略しています。" }, "commitDropdown": { "checkOutBranchToPush": "コミットをプッシュする前にブランチをチェックアウトしてください", @@ -2549,8 +2619,49 @@ "stageFile": "コミットするには、少なくとも 1 つのファイルをステージングしてください", "useCommitAndForcePush": "「コミットとフォースプッシュ」を使用してください — リモートにはローカルコミットの古いコピーしかありません" }, + "commitFailurePanel": { + "fix": "修正", + "fixWithAi": "AI によるコミット失敗の修正", + "hideDetails": "詳細を非表示", + "hideFailureDetails": "コミット失敗の詳細を非表示", + "showDetails": "詳細を表示", + "showFailureDetails": "コミット失敗の詳細を表示", + "summary": "コミットに失敗しました。", + "title": "コミットに失敗しました" + }, + "commitMessageAi": { + "generateFailed": "コミットメッセージの生成に失敗しました。" + }, + "commitRunners": { + "actionFailed": "ソース管理の操作に失敗しました。", + "commitFailed": "コミットに失敗しました。" + }, + "conflictAbort": { + "abortMerge": "マージを中止する", + "abortOperation": "{{operation}} を中止する", + "abortRebase": "リベースを中止する", + "aborting": "中止中…" + }, + "content": { + "cancelGeneration": "コミットメッセージの生成をキャンセル", + "commitMessageDisabled": "コミットメッセージは入力できません。ステージ済みのファイルがありません。", + "commitMessagePlaceholder": "コミットメッセージ", + "emptyMessage": "ワークツリーに変更はありません。", + "emptyTitle": "ローカルの変更なし", + "generateMessage": "AIでコミットメッセージを生成", + "noStagedFiles": "ステージ済みのファイルなし", + "openActions": "ソース管理の操作を開く", + "reconnecting": "デスクトップに再接続中…", + "regenerateHint": "再生成するには、メッセージをクリアしてください。", + "stageAll": "ステージオール", + "unstageAll": "すべてステージ解除" + }, "createPrAction": { - "createReview": "{{titleLabel}} を作成" + "checkingStatus": "レビュー状態を確認中…", + "createPullRequest": "PR の作成", + "createReview": "{{titleLabel}} を作成", + "providerUnavailable": "このプロバイダーではレビューを作成できません", + "statusUnavailable": "レビュー状態を取得できません" }, "dropdownCounts": { "fastForwardCount_one": "{{count}} 件のコミットを fast-forward", @@ -2572,6 +2683,64 @@ "titleUnpublishedForcePushCount_one": "{{count}} 件のブランチコミットを lease 付きで強制プッシュし、必要に応じてアップストリームを設定します。", "titleUnpublishedForcePushCount_other": "{{count}} 件のブランチコミットを lease 付きで強制プッシュし、必要に応じてアップストリームを設定します。" }, + "fileList": { + "committedSection": "ブランチのコミット済み変更" + }, + "fileRows": { + "addedByThem": "相手側で追加", + "addedByUs": "こちら側で追加", + "bothAdded": "双方で追加", + "bothDeleted": "双方で削除", + "bothModified": "双方で変更", + "committedSection": "ブランチのコミット済み変更", + "committedUnavailable": "コミット済みの変更を表示できません。", + "deletedByThem": "相手側で削除", + "deletedByUs": "こちら側で削除", + "discardFile": "{{path}} の変更を破棄", + "loadingCommitted": "コミット済みの変更を読み込み中…", + "openChangedFile": "変更されたファイル {{path}} を開く", + "openCommittedChange": "{{path}} のコミット済みの変更を開く", + "renamedFrom": "変更前: {{path}}", + "stageFile": "{{path}} をステージ", + "unresolvedConflict": "未解決の競合", + "unstageFile": "{{path}} のステージを解除" + }, + "gitHistory": { + "days_one": "{{count}}日", + "days_other": "{{count}}日", + "hours_one": "{{count}}時間", + "hours_other": "{{count}}時間", + "justNow": "たった今", + "loadFailed": "コミット履歴の読み込みに失敗しました。", + "minutes_one": "{{count}}分", + "minutes_other": "{{count}}分", + "months_one": "{{count}}か月", + "months_other": "{{count}}か月", + "noCommitMessage": "(コミットメッセージなし)", + "years_one": "{{count}}年", + "years_other": "{{count}}年" + }, + "gitHistoryList": { + "loadFailed": "履歴の読み込みに失敗しました。", + "loadFilesFailed": "コミット内のファイルを読み込めません。", + "noCommits": "コミットがありません。", + "noFileChanges": "ファイルの変更なし", + "retryFiles": "コミット内のファイルの読み込みを再試行", + "waitingForDesktop": "デスクトップからの応答を待機中…" + }, + "gitStatus": { + "changes": "変更点", + "conflicts": "競合", + "stagedChanges": "ステージ済みの変更" + }, + "header": { + "backToSession": "セッションに戻る", + "close": "ソース管理を閉じる", + "openNumberedPrWeb": "PR #{{number}} をウェブで開く", + "openPrWeb": "PR をウェブで開く", + "refresh": "ソース管理を更新", + "title": "ソース管理" + }, "hostedReview": { "mrCopy": { "reviewLabel": "MR", @@ -2584,9 +2753,81 @@ "titleLabel": "PR" } }, + "hostedReviewCopy": { + "committingChanges": "変更をコミット中…", + "creatingReview": "レビューを作成中…", + "forcePushing": "lease 付きで強制プッシュ中…", + "generatingCommitMessage": "コミットメッセージを生成中…", + "publishingBranch": "ブランチを公開中…", + "pushingCommits": "コミットをプッシュ中…", + "stagingChanges": "変更をステージング中…", + "updatingBranch": "ブランチを更新中…" + }, "hostedReviewCreate": { "pushSucceeded": "プッシュは成功しましたが、{{shortLabel}} の作成に失敗しました: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "PR の準備中にブランチが変更されました。", + "generateMessageFailed": "コミットメッセージを生成できませんでした。「ソース管理」で入力してから再試行してください。", + "resolveConflicts": "PR を作成する前に、競合を解決してください。", + "resolveOrStageChanges": "PR を作成する前に、競合を解決するか、変更をステージングしてください。", + "reviewCommitMessage": "コミットメッセージを確認してから、「PR を作成」を再試行してください。" + }, + "hostedReviewGitPreparation": { + "commitFailed": "コミットに失敗しました。", + "refreshFailed": "ソース管理を更新できませんでした。", + "stageFailed": "変更のステージングに失敗しました。", + "updateBranchFailed": "リモートブランチを更新できませんでした。「PR を作成」を再試行してください。" + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "lease 付きの強制プッシュに失敗しました。", + "publishFailed": "ブランチの公開に失敗しました。", + "pushFailed": "コミットのプッシュに失敗しました。" + }, + "hostedReviewService": { + "createFailed": "PR の作成に失敗しました。", + "pushBeforeCreateFailed": "プッシュに失敗しました。プッシュのエラーを解決してから、もう一度お試しください。" + }, + "hubTab": { + "changes": "変更点", + "commits": "コミット", + "pullRequest": "PR" + }, + "loaders": { + "connectingToDesktop": "デスクトップに接続中…", + "loadFailed": "ソース管理を読み込めませんでした。", + "updateDesktop": "モバイルでソース管理を使うには、デスクトップ版 Orca を更新してください。", + "waitingForDesktop": "デスクトップへの接続を待機中…" + }, + "modals": { + "actionsTitle": "ソース管理", + "currentBranch": "現在", + "discardButton": "破棄", + "discardConfirmMessage": "「{{path}}」への変更を破棄しますか?この操作は取り消せません。", + "discardTitle": "変更を破棄", + "openPrMessage": "ブラウザで開きますか?", + "openPrWithWarning": "ブラウザで開きますか?\n\n{{warning}}", + "prCreatedTitle": "PR を作成しました", + "switchBranchTitle": "ブランチを切り替え" + }, + "openers": { + "openDiffFailed": "差分を開けませんでした。", + "tabNotReady": "ファイルは開きましたが、タブの準備がまだできていません。再試行してください。", + "waitingForDesktop": "デスクトップへの接続を待機中…" + }, + "panel": { + "loadFailedTitle": "読み込めません", + "unavailableTitle": "ソース管理を利用できません" + }, + "prChip": { + "createPr": "PR を作成", + "loading": "PR を読み込み中…", + "loadingLabel": "PR を読み込み中", + "openLabel": "PR #{{number}}、{{state}}、{{checks}}。PR を開く。", + "openWithComments_one": "PR #{{number}}、{{state}}、{{checks}}、未解決のコメント {{count}} 件。PR を開く。", + "openWithComments_other": "PR #{{number}}、{{state}}、{{checks}}、未解決のコメント {{count}} 件。PR を開く。", + "unavailableLabel": "PR を表示できません:{{message}}" + }, "prCreate": { "authRequired": "{{reviewLabel}} を作成する前に認証してください。", "baseNotOnRemote": "{{reviewLabel}} を作成する前にベースブランチをプッシュしてください。", @@ -2605,8 +2846,19 @@ "unsupportedMergeRequests": "このリポジトリでは MR の作成に対応していません。", "unsupportedPullRequests": "このリポジトリでは PR の作成に対応していません。" }, + "prLink": { + "updatePullRequestFailed": "リンクされた PR の更新に失敗しました。", + "updateReviewFailed": "リンクされたレビューの更新に失敗しました。" + }, "primaryAction": { - "forcePushFromDesktop": "デスクトップからこの PR のブランチを強制プッシュ" + "commit": "Commit", + "forcePush": "フォースプッシュ", + "forcePushFromDesktop": "デスクトップからこの PR のブランチを強制プッシュ", + "publishBranch": "ブランチを公開", + "pull": "プル", + "push": "プッシュ", + "stageAll": "ステージオール", + "sync": "同期" }, "remoteDropdown": { "branchAlreadyPublished": "ブランチは既に公開されています", @@ -2656,6 +2908,591 @@ "tryFastForwardPull": "fast-forward プルを試行します。git がローカルコミットを拒否する場合があります", "tryRegularPush": "通常のプッシュを試行します。git が強制プッシュを要求する場合があります", "useForcePushToSync": "強制プッシュを使用してください — リモートにはローカルコミットの古いコピーしかありません" + }, + "runners": { + "actionFailed": "ソース管理の操作に失敗しました。" + }, + "screenState": { + "noBranch": "ブランチなし" + }, + "state": { + "noUpstream": "アップストリームなし", + "syncStatus": "{{ahead}} コミット先行、{{behind}} コミット遅れ" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Agent の起動に失敗しました。", + "waitingForDesktop": "デスクトップへの接続を待機中…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "コミットメッセージの生成に失敗しました。" + }, + "useMobileCreatePrRunner": { + "branchRequired": "PR を作成する前にブランチをチェックアウトしてください。" + }, + "useMobileGitRequests": { + "actionFailed": "ソース管理の操作に失敗しました。", + "branchUnavailable": "ブランチの状態を確認できません。", + "commitFailed": "コミットに失敗しました。", + "waitingForDesktop": "デスクトップへの接続を待機中…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "ベースブランチの特定に失敗しました。", + "forkPushWarning": "この PR は「メンテナーによる編集を許可」がオフのため、フォークへのプッシュが GitHub に拒否される場合があります。" + }, + "detailCommentRenderers": { + "commentPlaceholder": "コメントを追加", + "comments_one": "{{count}} 件のコメント", + "comments_other": "{{count}} 件のコメント", + "reopenThread": "スレッドを再開", + "reply": "返事", + "resolveThread": "スレッドを解決", + "resolvedCommentBy": "{{author}} の解決済みコメント", + "resolvedThreadBy": "{{author}} の解決済みスレッド", + "sendComment": "コメントを送信", + "show": "表示" + }, + "filterPickers": { + "allTeams": "全チーム", + "changeStatus": "ステータスを変更", + "fieldHidden": "カードでは非表示", + "fieldShown": "カードに表示", + "fieldsSubtitle": "アイテムカードに表示するプロジェクトのフィールドを選択してください。", + "fieldsTitle": "プロジェクトのフィールド", + "gitlabFilter": "GitLab フィルター", + "gitlabView": "GitLab ビュー", + "jiraFilter": "Jira フィルター", + "jiraSite": "Jira サイト", + "linearFilter": "Linear フィルター", + "linearIssue": "Linear Issue", + "linearWorkspace": "Linear ワークスペース", + "loadingStates": "ステータスを読み込み中…", + "noFields": "このビューに表示できる追加フィールドはありません。", + "noStates": "利用可能なステータスがありません。", + "switchWorkspaceFailed": "ワークスペースの切り替えに失敗しました", + "teamsSubtitle": "「タスク」に表示するチームを選択してください。", + "teamsTitle": "Linear チーム", + "teams_one": "{{count}} チーム", + "teams_other": "{{count}} チーム" + }, + "githubProjectList": { + "browseProjects": "プロジェクトを参照", + "chooseProject": "GitHub プロジェクトを選択", + "emptyField": "空欄", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "プロジェクトアイテム · {{repository}}{{number}}", + "items": "アイテム", + "moreFields_one": "+{{count}} フィールド", + "moreFields_other": "+{{count}} フィールド", + "noItems": "プロジェクトのアイテムがありません。", + "pullRequestSubtitle": "PR · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "追加", + "addByUrlHint": "表示されないプロジェクトは URL を入力して追加してください。", + "addPlaceholder": "URL または所有者/番号で追加", + "adding": "追加中…", + "browseAll": "すべて閲覧する", + "browseLoading": "すべて閲覧する(読み込み中…)", + "chooseView": "プロジェクトビューを選択", + "loadFailed": "プロジェクトのロードに失敗しました", + "noMatches": "一致するプロジェクトがありません。", + "noMoreProjects": "これ以上プロジェクトはありません。", + "noProjects": "読み込み済みのプロジェクトがありません。", + "organizationsError": "組織: {{message}}", + "organizationsLoadFailed": "一部の組織を読み込めませんでした({{count}} 件)。", + "ownerLoadFailed": "{{owner}} のプロジェクトを読み込めませんでした。", + "pin": "ピン", + "pinned": "ピン留め済み", + "recent": "最近の", + "retryHint": "タップして再試行してください。", + "searchProjects": "プロジェクトを検索する", + "sort": "プロジェクトの並べ替え", + "subtitle": "「タスク」ページで使うプロジェクトビューを選択してください。", + "title": "GitHub Projects", + "unsupportedLayout": "Orca はこの GitHub プロジェクトのレイアウトにまだ対応していません。", + "view": "プロジェクトビュー" + }, + "githubViewControls": { + "fields": "フィールド: {{fields}}", + "openView": "GitHub でビューを開く", + "sort": "並べ替え: {{sort}}", + "source": "ソース: {{source}}" + }, + "itemActions": { + "changeStatus": "ステータスを変更", + "copyGitHubLink": "GitHub リンクをコピーする", + "copyLinearLink": "Linear リンクをコピーする", + "createWorkspace": "ワークスペースを作成", + "creating": "作成中…", + "mergeConflicts": "GitHub でマージの競合が報告されています。", + "mergeMergeRequest": "MR をマージ", + "mergePullRequest": "PR をマージ" + }, + "itemDetailContent": { + "addSubIssue": "サブ Issue を追加", + "assignee": "担当者", + "assignees": "担当者", + "checks": "チェック", + "description": "説明", + "discussion": "ディスカッション", + "noChecks": "チェックが見つかりません。", + "noComments": "コメントはありません。", + "noPipelineRuns": "この MR のパイプライン実行履歴はありません。", + "noSubIssues": "サブ Issue はありません。", + "none": "なし", + "pipeline": "パイプライン", + "pipelineJobs_one": "{{count}} 件のジョブ", + "pipelineJobs_other": "{{count}} 件のジョブ", + "project": "プロジェクト", + "rerunAll": "すべて再実行", + "rerunFailed": "失敗分を再実行", + "status": "状態", + "subIssueTitle": "サブ Issue のタイトル", + "subIssues": "サブ Issue", + "type": "種類" + }, + "itemDetailDrawer": { + "refreshDetails": "詳細を更新" + }, + "itemFieldEditors": { + "addLabels": "追加するラベル(カンマ区切り)", + "addUsernames": "追加するユーザー名(カンマ区切り)", + "assignees": "担当者", + "labels": "ラベル", + "loadingAssignees": "担当者を読み込み中…", + "loadingLabels": "ラベルを読み込み中…", + "noAssignableUsers": "このリポジトリで担当者に指定できるユーザーが見つかりませんでした。", + "noLabels": "このリポジトリにはラベルがありません。", + "none": "なし", + "removeLabels": "削除するラベル(カンマ区切り)", + "removeUsernames": "削除するユーザー名(カンマ区切り)", + "saveTitle": "タイトルを保存", + "title": "タイトル", + "updateAssignees": "担当者を更新", + "updateLabels": "ラベルを更新" + }, + "itemReviewSections": { + "binaryFile": "バイナリファイルです。", + "changedFilesTitle": "変更済みファイル", + "descriptionPlaceholder": "説明", + "fileContentsUnavailable": "ファイルの内容を表示できません。", + "hideFile": "非表示", + "loadingReviewers": "レビュアーを読み込み中…", + "markUnviewed": "未閲覧としてマークする", + "markViewed": "閲覧済みとしてマークする", + "noDescription": "説明はありません。", + "noReviewerSuggestions": "レビュアーの候補が見つかりませんでした。", + "noReviewersRequested": "レビュアーはリクエストされていません。", + "requestReview": "レビューを依頼", + "reviewersPlaceholder": "依頼するレビュアー", + "reviewersTitle": "レビュアー", + "saveDescription": "説明を保存", + "viewFile": "表示" + }, + "legacySurface": { + "loadIssuesFailed": "{{source}} から Issue を読み込めませんでした。", + "mergeAction": "マージ", + "mergeMethodTitle": "マージ方法", + "mergePullRequestTitle": "PR をマージ", + "mergeRequestMergeMessage": "この MR のマージ方法を選択してください。", + "mergeRequestTitle": "MR をマージ", + "pullRequestMergeMessage": "この PR のマージ方法を選択してください。", + "retryLoadingIssues": "{{source}} からの Issue の読み込みを再試行", + "retrying": "再試行中…", + "sourceFallback": "{{repo}} では優先する Issue ソースの upstream が利用できません。origin を使用します。", + "subIssueDataUnavailable": "トークンではサブ Issue データを利用できません。", + "updateItemTitle": "項目を更新" + }, + "linearList": { + "changeStatusFrom": "状態を「{{status}}」から変更" + }, + "linearViewControls": { + "displayButton": "表示", + "groupLabel": "グループ化:{{group}}", + "orderLabel": "並べ替え:{{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "表示項目", + "linearGroupTitle": "Linear の Issue をグループ化", + "linearOrderTitle": "Linear の Issue を並べ替え", + "linearViewTitle": "Linear の表示", + "sortTasksTitle": "タスクを並べ替え" + }, + "listSurface": { + "connectLinearButton": "Linear に接続", + "connectLinearMessage": "「タスク」から、担当する Linear の Issue を確認して作業を開始できます。", + "connectLinearTitle": "Linear アカウントを接続する", + "jiraStatusFailed": "Jira の状態の読み取りに失敗しました。", + "updateDesktopMessage": "モバイルの「タスク」画面には、新しいバージョンのデスクトップランタイムが必要です。", + "updateDesktopTitle": "Orca デスクトップを更新" + }, + "options": { + "all": "全て", + "assignedToMe": "私に割り当てられた Issue", + "assignee": "担当者", + "board": "ボード", + "boardDescription": "グループ別の列で表示", + "closedState": "クローズ", + "completedState": "完了", + "createdState": "自分が作成", + "githubAssignedIssuesDescription": "私に割り当てられたオープンな Issue", + "githubDescription": "Issue と PR", + "githubIssuesDescription": "GitHub Issue", + "githubOpenIssuesDescription": "オープンな GitHub Issue", + "githubProjectsDescription": "GitHub Projects のビュー", + "githubPullRequestsDescription": "GitHub PR", + "gitlabAllDescription": "GitLab の全ての状態", + "gitlabClosedDescription": "クローズした Issue と MR", + "gitlabDescription": "Issue と MR", + "gitlabMergedDescription": "マージ済みの MR", + "gitlabOpenDescription": "オープンな Issue と MR", + "identifier": "識別子", + "issues": "Issue", + "jiraDescription": "担当する Issue と報告した Issue", + "labels": "ラベル", + "linearAllDescription": "接続済みワークスペース全体のオープンな Issue", + "linearAssignedDescription": "自分が担当する Issue", + "linearCompletedDescription": "最近完了した Issue", + "linearCreatedDescription": "自分が作成した Issue", + "linearDescription": "担当する Issue とチームの Issue", + "list": "リスト", + "listDescription": "Issue をコンパクトに一覧表示", + "mergedState": "マージ済み", + "mine": "私の", + "myIssues": "自分の Issue", + "myPullRequestsDescription": "私が作成した PR", + "myTodos": "私の ToDo", + "myTodosDescription": "未処理の GitLab ToDo", + "needsReview": "レビュー待ち", + "noGrouping": "グループ化なし", + "openPullRequestsDescription": "オープンな PR", + "openState": "オープン", + "priority": "優先度", + "projectMergeRequests": "プロジェクトの MR", + "projectMergeRequestsDescription": "リポジトリ別の MR と Issue", + "projects": "プロジェクト", + "pullRequests": "PR", + "repository": "リポジトリ", + "repositorySortDescription": "リポジトリ別にグループ化し、アクティビティが新しい順に表示", + "reviewRequestsDescription": "私に割り当てられたレビュー依頼", + "status": "状態", + "team": "チーム", + "updated": "更新日時", + "updatedSortDescription": "アクティビティが新しい順" + }, + "pickerProjection": { + "allRepos": "すべてのリポジトリ", + "allSites": "すべてのサイト", + "currentlyAscending": "現在は昇順・タップで降順に変更", + "currentlyDescending": "現在は降順・タップで昇順に変更", + "fieldAscending": "{{field}} 昇順", + "fieldDescending": "{{field}} 降順", + "fields": "フィールド", + "repos_one": "{{count}} 件のリポジトリ", + "repos_other": "{{count}} 件のリポジトリ", + "selectTarget": "作成先を選択", + "selectedFields": "{{selected}}/{{total}} フィールド", + "sortAscending": "昇順に並べ替え", + "sources_one": "{{count}} 件のソース", + "sources_other": "{{count}} 件のソース", + "unsupportedLayout": "モバイルでは未対応のレイアウト", + "updatedSort": "更新日時", + "usesFieldAscending": "{{field}} の昇順を使用", + "usesFieldDescending": "{{field}} の降順を使用", + "usesGitHubRankOrder": "GitHub のランク順を使用", + "viewNumber": "ビュー #{{number}}", + "viewOrder": "ビューの並び順" + }, + "prFileDiff": { + "commentOnLine": "{{line}} 行目にコメント", + "commentPlaceholder": "レビューコメントを追加", + "noTextChanges": "テキストの変更はありません。", + "showingDiffLines": "差分の全 {{total}} 行中、先頭 {{limit}} 行を表示しています。" + }, + "projectComments": { + "comments_one": "{{count}} 件のコメント", + "comments_other": "{{count}} 件のコメント", + "discussion": "ディスカッション", + "editComment": "コメントを編集", + "noComments": "コメントはありません。", + "reopenThread": "スレッドを再開", + "reply": "返事", + "resolveThread": "スレッドを解決", + "resolvedCommentBy": "{{author}} のコメント(解決済み)", + "resolvedThreadBy": "{{author}} のスレッド(解決済み)", + "show": "表示" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} は Orca に追加されていません。デスクトップアプリからこのリポジトリを追加し、モバイルの「タスク」を更新してください。", + "clearType": "種類をクリア", + "closeItem": "項目をクローズ", + "copyGitHubLink": "GitHub リンクをコピーする", + "copyRepository": "リポジトリ名をコピー", + "createWorkspace": "ワークスペースを作成", + "draftIssue": "下書きの Issue", + "issue": "Issue", + "issueType": "Issue の種類", + "loadingIssueTypes": "Issue の種類を読み込み中…", + "mergePullRequest": "PR をマージ", + "mergeRepositoryRequirement": "マージするには、このリポジトリを Orca に追加する必要があります。", + "noIssueTypes": "このリポジトリには Issue の種類が設定されていません。", + "noType": "種類なし", + "openInGitHub": "GitHub で開く", + "projectItem": "プロジェクト項目", + "projectSubtitle": "GitHub プロジェクト · {{repository}}{{itemNumber}}", + "pullRequest": "PR", + "reopenItem": "項目を再オープン", + "repositoryNotInOrca": "このリポジトリは Orca に登録されていません", + "status": "状態", + "type": "種類", + "workspaceCreationRequirement": "ワークスペースは GitHub の Issue と PR からのみ作成できます。" + }, + "projectFieldEditors": { + "clearField": "フィールドをクリア", + "completedIteration": "完了 · {{startDate}} · {{duration}} 日", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "日付は YYYY-MM-DD 形式で入力してください。", + "invalidNumber": "有効な数値を入力してください。", + "noIterations": "利用可能なイテレーションはありません。", + "numberPlaceholder": "数値", + "projectFields": "プロジェクトのフィールド", + "saveField": "フィールドを保存", + "textPlaceholder": "テキスト", + "upcomingIteration": "現在および今後の予定 · {{startDate}} · {{duration}} 日" + }, + "projectMetadataEditors": { + "assignees": "担当者", + "description": "説明", + "labels": "ラベル", + "loadingAssignees": "担当者を読み込み中…", + "loadingLabels": "ラベルを読み込み中…", + "noAssignableUsers": "このリポジトリで割り当て可能なユーザーが見つかりません。", + "noDescription": "説明はありません。", + "noLabels": "このリポジトリにはラベルがありません。", + "none": "なし", + "saveDescription": "説明を保存", + "saveTitle": "タイトルを保存", + "title": "タイトル" + }, + "projectReviewPanels": { + "binaryFile": "バイナリファイルです。", + "changedFiles": "変更済みファイル", + "checks": "チェック", + "fileUnavailable": "ファイルの内容を表示できません。", + "hideFile": "非表示", + "loadingReviewers": "レビュアーを読み込み中…", + "markUnviewed": "未閲覧としてマークする", + "markViewed": "閲覧済みとしてマークする", + "noChecks": "チェックが見つかりません。", + "noReviewers": "レビュアーはリクエストされていません。", + "noSuggestions": "レビュアー候補が見つかりません。", + "requestReview": "レビューを依頼", + "requestReviewers": "レビューの依頼先", + "rerunAll": "すべて再実行", + "rerunFailed": "失敗分を再実行", + "reviewers": "レビュアー", + "viewFile": "表示" + }, + "providerControls": { + "myTodos": "自分の ToDo", + "projectMergeRequests": "プロジェクトの MR", + "sort": "並べ替え:{{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "{{base}} へ", + "nextPage": "次のページ", + "page": "{{page}} ページ", + "pageOfTotal": "{{page}} / {{total}} ページ", + "previousPage": "前のページへ", + "selectPage": "ページを選択、{{page}} ページ", + "selectPageOfTotal": "ページを選択、全 {{total}} ページ中 {{page}} ページ" + }, + "providerPickers": { + "allRepositories": "すべてのリポジトリ", + "githubView": "GitHub の表示", + "issueSources": "GitHub Issue の取得元", + "issueSourcesDescription": "リポジトリごとに、検索や作業の作成に使うソースを upstream または origin から選択してください。", + "issues": "Issue", + "noIssueSources": "ほかに利用できる Issue の取得元はありません。", + "origin": "origin", + "pageHint": "読み込み済みまたは利用可能な結果ページに移動します。", + "pageLoaded": "読み込み済み", + "pageNotLoaded": "以前の結果を読み込み", + "pageNumber": "{{page}} ページ", + "pages": "GitHub の結果ページ", + "pullRequests": "PR", + "queryingSource": "検索対象: {{source}}", + "repoDescription": "検索対象のリポジトリを選択してください。", + "repos": "リポジトリ", + "taskSource": "タスクソース", + "upstream": "upstream" + }, + "providerViewProjection": { + "all": "全て", + "allSites": "すべてのサイト", + "allTeams": "全チーム", + "allWorkspaces": "すべてのワークスペース", + "chooseProject": "プロジェクトを選択", + "default": "デフォルト", + "defaultSubtitle": "{{subtitle}} · デフォルト", + "issues": "Issue", + "list": "リスト", + "noGrouping": "グループ化なし", + "openState": "オープン", + "priority": "優先度", + "projects": "プロジェクト", + "pullRequests": "PR", + "teams_one": "{{count}} チーム", + "teams_other": "{{count}} チーム", + "workspace": "ワークスペース" + }, + "reviewerLinear": { + "issues": "Issue", + "unassigned": "未割り当て" + }, + "screenChrome": { + "connectLinear": "Linear に接続", + "newGitHubIssue": "GitHub の新規 Issue", + "newLinearIssue": "新規 Linear Issue", + "refreshGitHub": "GitHub の作業を更新する", + "refreshGitLab": "GitLab 作業項目を更新する", + "refreshJira": "Jira Issue を更新する", + "refreshLinear": "Linear を更新", + "title": "タスク" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL(例:project = ABC AND statusCategory != Done)", + "projectPlaceholder": "プロジェクトビューを検索…", + "providerPlaceholder": "{{provider}} のタスクを検索…" + }, + "smartSourceModes": { + "allStates": "全て", + "branch": "ブランチ", + "closedState": "クローズ", + "mergedState": "マージ済み", + "name": "名前", + "openState": "オープン", + "smart": "スマート" + }, + "sparsePresetDraft": { + "directoryRequired": "少なくとも 1 つのディレクトリを追加してください。", + "repoRelativeDirectoriesRequired": "ルート、絶対パス、親セグメントではなく、リポジトリ相対ディレクトリを使用してください。" + }, + "taskViewOptions": { + "allSubtitle": "選択したサイト全体の未解決の Issue", + "assignedSubtitle": "自分に割り当てられた未解決の Issue", + "doneSubtitle": "最近解決された自分の Issue", + "noGitHubTasks": "GitHub のタスクはありません。", + "noGitLabTasks": "GitLab のタスクはありません。", + "noJiraTasks": "Jira のタスクはありません。", + "noLinearTasks": "Linear のタスクはありません。", + "reportedSubtitle": "報告した未解決の Issue" + }, + "tasksCreateDrawers": { + "connect": "接続", + "connectLinearWorkspace": "Linear ワークスペースに接続", + "createIssue": "Issue を作成", + "createWorkspaceIn": "ワークスペースの作成先リポジトリ", + "description": "説明", + "descriptionPlaceholder": "背景情報を追加", + "fileIn": "{{slug}} に登録", + "issueSource": "Issue ソース", + "keySecurityHint": "キーはホスト OS のキーチェーンで暗号化され、ローカルに保存されます。", + "linearConnectSubtitle": "ワークスペースの Issue を閲覧するには、個人用 API キーを貼り付けてください。", + "linearSettingsLink": "Linear の設定 / セキュリティ / 新規 API キー", + "linearTeam": "Linear チーム", + "linearTeamSubtitle": "選択した Linear チームに Issue を作成します。", + "newIssueTitle": "{{providerLabel}} の新規 Issue", + "origin": "オリジン", + "personalApiKey": "個人用APIキー", + "repository": "リポジトリ", + "repositorySubtitle": "選択したリポジトリに Issue を作成します。", + "team": "チーム", + "title": "タイトル", + "titlePlaceholder": "タスクのタイトル", + "upstream": "upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "ブランクターミナル" + }, + "workspaceCreateDrawer": { + "addRepository": "Linear の Issue からワークスペースを作成する前に、Git リポジトリを追加してください。", + "advanced": "詳細設定", + "agent": "Agent", + "connect": "接続", + "connectFirst": "先にリポジトリに接続", + "connectRepository": "リポジトリに接続", + "connecting": "接続中…", + "createFrom": "{{branch}} から作成", + "defaultBranch": "デフォルトブランチ", + "detectingAgents": "Agent を検出中…", + "optional": "[オプション]", + "remoteRepository": "リモートリポジトリ", + "repository": "リポジトリ", + "repositoryNotFound": "リポジトリが見つかりません。", + "selectRepository": "リポジトリを選択", + "sshConnection": "SSH 接続", + "startFrom": "作成元", + "title": "ワークスペースを作成", + "workspaceName": "ワークスペース名" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "「{{name}}」は既に存在します。", + "nameRequired": "名前を入力してください。", + "nameTooLong": "名前は80文字以内にしてください。", + "openShell": "シェルを開く" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "既存のブランチまたは参照を選択してください。", + "baseBranchTitle": "作成元", + "branchName": "ブランチ名: {{name}}", + "defaultBranch": "デフォルトブランチ", + "defaultBranchSubtitle": "このリポジトリに設定されたベースブランチを使用", + "editPreset": "{{name}} を編集", + "fullCheckout": "フルチェックアウト", + "fullCheckoutSubtitle": "リポジトリ全体を使用", + "newPreset": "新規プリセット", + "noBranches": "一致するブランチはありません。", + "searchBranches": "ブランチを検索", + "sparseCheckoutTitle": "スパースチェックアウト" + }, + "workspaceSshGate": { + "authenticationFailed": "認証に失敗しました", + "connected": "接続済み", + "connecting": "接続中", + "connectionFailed": "接続に失敗しました", + "deployingRelay": "リレーをデプロイ中", + "disconnected": "切断済み", + "reconnectFailed": "再接続に失敗しました", + "reconnecting": "再接続中" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "常に信頼して実行", + "creating": "作成中…", + "directoriesLabel": "ディレクトリ", + "directories_one": "{{count}} 個のディレクトリ", + "directories_other": "{{count}} 個のディレクトリ", + "dontRun": "実行しない", + "editSparsePreset": "スパースプリセットを編集", + "nameLabel": "名前", + "namePlaceholder": "レンダラー UI", + "newSetupScript": "新しいセットアップスクリプト", + "newSparsePreset": "新しいスパースプリセット", + "runHooks": "フックを実行する", + "runSetupAndCreate": "セットアップを実行して作成", + "runSetupTitle": "{{name}} のセットアップを実行しますか?", + "setupChangedTitle": "{{name}} のセットアップスクリプトが変更されました", + "setupScript": "セットアップスクリプト", + "setupSubtitle": "{{name}} でこのワークスペースを作成する前に、セットアップの実行有無を選択してください。", + "setupTitle": "セットアップスクリプトを実行しますか?", + "skipSetupAndCreate": "セットアップをスキップして作成", + "trustFailed": "セットアップスクリプトの信頼設定に失敗しました。", + "trustSubtitle": "このリポジトリの orca.yaml は、ワークスペースの起動前にコンピュータ上で実行されます。このリポジトリを信頼できる場合のみ実行してください。" + }, + "worktreeCreateRetry": { + "createFailed": "ワークスペースの作成に失敗しました" } }, "terminal": { diff --git a/mobile/src/i18n/locales/ko.json b/mobile/src/i18n/locales/ko.json index c0d830539f0..31d6d908e5a 100644 --- a/mobile/src/i18n/locales/ko.json +++ b/mobile/src/i18n/locales/ko.json @@ -13,7 +13,7 @@ "sessionWindow": "5시간", "switchFailed": "계정을 전환하지 못했습니다.", "title": "계정", - "useReset": "초기화권 사용", + "useReset": "재설정권 사용", "weeklyWindow": "7일" } }, @@ -1491,7 +1491,21 @@ "workspace": "워크스페이스" } }, + "newWorkspace": { + "hostPicker": { + "title": "워크스페이스 생성 호스트" + }, + "loadingDrawer": { + "downloadProgress": "다운로드 중… {{progress}}", + "downloading": "다운로드 중", + "loading": "로드 중" + } + }, "notifications": { + "desktopChannel": { + "name": "데스크톱 알림", + "silentName": "Orca 무음 알림" + }, "notificationDeliverySection": { "footer": "알림 유형은 페어링된 각 데스크톱의 알림 설정을 따릅니다. 이 앱을 7일 동안 사용하지 않으면 알림이 일시 중지됩니다. 다시 받으려면 앱을 열고 다시 연결하세요.", "onlyWhenAway": "데스크톱을 사용하지 않을 때만", @@ -2034,9 +2048,9 @@ "switchToTerminalView": "터미널 보기로 전환" }, "newTabAgentHostLaunch": { - "notesNotSent": "에이전트가 시작되었지만 노트가 전송되지 않았습니다.", - "notesSent": "노트 전송됨", - "notesUnconfirmed": "에이전트가 시작되었지만 노트가 전송되었는지 확인하지 못했습니다.", + "notesNotSent": "에이전트가 시작되었지만 메모가 전송되지 않았습니다.", + "notesSent": "메모 전송됨", + "notesUnconfirmed": "에이전트가 시작되었지만 메모가 전송되었는지 확인하지 못했습니다.", "promptUnconfirmed": "에이전트가 시작되었지만 프롬프트가 전송되었는지 확인하지 못했습니다." }, "prActionsEngine": { @@ -2162,7 +2176,7 @@ "draftsHint": "나가기 전에 휴대폰의 초안을 복사하거나 버리세요.", "file": "파일", "markdown": "Markdown", - "markdownNote": "Markdown 메모", + "markdownNote": "Markdown 노트", "newBrowser": "새 브라우저", "newTab": "새 탭", "notesCopied": "메모를 복사했습니다.", @@ -2254,12 +2268,12 @@ "untitledNoteCreateFailed": "제목 없는 Markdown 노트를 만들 수 없습니다." }, "useDiffComments": { - "copyNotesFailed": "노트를 복사하지 못했습니다.", - "deleteNoteFailed": "노트를 삭제하지 못했습니다.", - "noteAdded": "노트 추가됨", - "notesCopied": "노트 복사됨", - "saveNoteFailed": "노트를 저장하지 못했습니다.", - "saveNotesFailed": "리뷰 노트를 저장하지 못했습니다.", + "copyNotesFailed": "메모를 복사하지 못했습니다.", + "deleteNoteFailed": "메모를 삭제하지 못했습니다.", + "noteAdded": "메모 추가됨", + "notesCopied": "메모 복사됨", + "saveNoteFailed": "메모를 저장하지 못했습니다.", + "saveNotesFailed": "리뷰 메모를 저장하지 못했습니다.", "waitingForDesktop": "데스크톱 대기 중…" }, "useDiffReviewCommentActions": { @@ -2287,14 +2301,14 @@ "openFailed": "세션에서 열 수 없습니다." }, "useDiffReviewSendActions": { - "copyFailed": "리뷰 노트를 복사할 수 없습니다.", + "copyFailed": "리뷰 메모를 복사할 수 없습니다.", "inputLocked": "터미널 입력이 잠겨 있습니다.", "loadSessionsFailed": "에이전트 세션을 로드할 수 없습니다.", - "notesCopied": "리뷰 노트 복사됨", - "notesSent": "리뷰 노트 전송됨", - "notesSentWithWarning": "리뷰 노트를 전송했습니다. {{warning}}", - "promptNotSent": "에이전트가 시작되었지만 노트가 전송되지 않았습니다. '노트 복사'로 복사한 후 붙여넣으세요.", - "sendFailed": "노트를 전송하지 못했습니다.", + "notesCopied": "리뷰 메모 복사됨", + "notesSent": "리뷰 메모 전송됨", + "notesSentWithWarning": "리뷰 메모를 전송했습니다. {{warning}}", + "promptNotSent": "에이전트가 시작되었지만 메모가 전송되지 않았습니다. '메모 복사'로 복사한 후 붙여넣으세요.", + "sendFailed": "메모를 전송하지 못했습니다.", "startingAgent": "에이전트 시작 중…", "waitingForDesktop": "데스크톱 연결 대기 중…" }, @@ -2324,7 +2338,7 @@ }, "usePanelRouteActions": { "checkHostHint": "호스트 연결을 확인하세요.", - "copyNotesHint": "대신 노트를 복사하세요.", + "copyNotesHint": "대신 메모를 복사하세요.", "detectingAgents": "에이전트 감지 중", "newSessionHint": "새 에이전트 세션", "noEnabledAgents": "활성화된 에이전트 없음", @@ -2358,9 +2372,9 @@ "forkBusy": "다른 터미널을 여는 중입니다. 잠시 기다린 후 {{agentName}} 채팅을 다시 시도하세요.", "forkUnavailable": "연결되어 있고 업데이트된 호스트에서 {{agentName}} 채팅을 열고 다시 시도하세요.", "inputLocked": "터미널 입력이 다른 클라이언트에 의해 잠겨 있습니다.", - "notesSent": "노트 전송됨", - "sendNotesError": "노트를 보내지 못했습니다.", - "sendNotesFailed": "노트를 보내지 못했습니다.", + "notesSent": "메모 전송됨", + "sendNotesError": "메모를 보내지 못했습니다.", + "sendNotesFailed": "메모를 보내지 못했습니다.", "terminalTitle": "터미널" }, "useTerminalInput": { @@ -2520,11 +2534,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "리베이스할 기본 브랜치가 없습니다.", + "waitingForDesktop": "데스크톱 연결 대기 중…" + }, "actions": { + "checkingReviewStatus": "리뷰 상태를 확인 중입니다.", + "checkoutBeforePublish": "커밋을 게시하기 전에 브랜치를 체크아웃하세요.", + "commitStagedChanges": "스테이징된 변경 사항을 커밋하세요.", "commits": "커밋", + "committing": "커밋이 진행 중입니다.", "createPr": "PR 작성", + "enterCommitMessage": "커밋하려면 커밋 메시지를 입력하세요.", + "forcePushWithLease": "원격 브랜치를 업데이트하려면 lease로 강제 푸시하세요.", + "forcePushing": "강제 푸시가 진행 중입니다.", + "linkedReviewUnavailable": "연결된 리뷰 브랜치를 사용할 수 없습니다.", + "publishToOrigin": "이 브랜치를 origin에 게시하세요.", + "pullCommits_one": "커밋 {{count}}개를 풀하세요.", + "pullCommits_other": "커밋 {{count}}개를 풀하세요.", "pushAndCreatePr": "푸시 및 PR 작성", - "switchBranch": "브랜치 전환" + "pushCommits_one": "커밋 {{count}}개를 푸시하세요.", + "pushCommits_other": "커밋 {{count}}개를 푸시하세요.", + "pushLinkedReview": "연결된 리뷰 브랜치에 업데이트를 푸시하세요.", + "remoteOperationInProgress": "원격 작업이 진행 중입니다.", + "resolveConflicts": "커밋하기 전에 충돌을 해결하세요.", + "reviewAlreadyMerged": "커밋할 항목이 없습니다. 리뷰가 이미 병합되었습니다.", + "stageAllChanges": "모든 변경 사항을 스테이지하세요.", + "stageFileToCommit": "커밋하려면 파일을 하나 이상 스테이지하세요.", + "switchBranch": "브랜치 전환", + "syncCounts": "커밋 {{behind}}개를 풀하고 {{ahead}}개를 푸시하세요.", + "upToDate": "커밋할 항목이 없습니다. 브랜치가 최신 상태입니다.", + "waitForRemoteOperation": "원격 작업이 끝나면 다시 시도하세요." + }, + "branchBaseRef": { + "resolveFailed": "브랜치의 기준점을 확인할 수 없습니다." + }, + "branchCard": { + "branchCount": "브랜치 변경 {{count}}개", + "changedCount": "변경 {{count}}개", + "cherryPickState": "체리픽", + "mergeState": "병합", + "rebaseState": "리베이스", + "stagedCount": "{{count}}개 스테이징됨" + }, + "branchCompare": { + "commits_one": "커밋 {{count}}개", + "commits_other": "커밋 {{count}}개", + "files_one": "파일 {{count}}개", + "files_other": "파일 {{count}}개", + "sectionTitle": "브랜치에 커밋됨", + "summary": "{{files}} - {{baseRef}} 대비", + "summaryWithCommits": "{{files}} - {{commits}} - {{baseRef}} 대비" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "비교할 기본 브랜치를 확인할 수 없습니다.", + "loadFailed": "커밋된 변경 사항을 로드할 수 없습니다." + }, + "branchDiffPreviewDrawer": { + "closePreview": "커밋된 차이점 미리보기 닫기", + "committedOnBranch": "브랜치에 커밋됨", + "loadFailed": "차이점을 불러올 수 없음", + "truncated": "모바일 미리보기용으로 차이점의 일부가 생략되었습니다." }, "commitDropdown": { "checkOutBranchToPush": "커밋을 푸시하기 전에 브랜치를 체크아웃하세요", @@ -2549,8 +2619,49 @@ "stageFile": "commit 할 파일을 하나 이상 스테이지하세요", "useCommitAndForcePush": "Commit 및 강제 푸시를 사용하세요 — 원격에는 로컬 커밋의 이전 사본만 있습니다" }, + "commitFailurePanel": { + "fix": "수정", + "fixWithAi": "AI로 commit 실패 수정", + "hideDetails": "세부 정보 숨기기", + "hideFailureDetails": "커밋 실패 세부 정보 숨기기", + "showDetails": "세부 정보 표시", + "showFailureDetails": "커밋 실패 세부 정보 표시", + "summary": "커밋에 실패했습니다.", + "title": "커밋 실패" + }, + "commitMessageAi": { + "generateFailed": "커밋 메시지를 생성하지 못했습니다." + }, + "commitRunners": { + "actionFailed": "소스 제어 작업에 실패했습니다.", + "commitFailed": "커밋 실패" + }, + "conflictAbort": { + "abortMerge": "병합 중단", + "abortOperation": "{{operation}} 중단", + "abortRebase": "리베이스 중단", + "aborting": "중단 중…" + }, + "content": { + "cancelGeneration": "커밋 메시지 생성 취소", + "commitMessageDisabled": "커밋 메시지 입력이 비활성화되었습니다. 스테이징된 파일이 없습니다.", + "commitMessagePlaceholder": "Commit 메시지", + "emptyMessage": "워크트리에 변경 사항이 없습니다.", + "emptyTitle": "로컬 변경 사항 없음", + "generateMessage": "AI로 commit 메시지 생성", + "noStagedFiles": "스테이징된 파일 없음", + "openActions": "소스 제어 작업 열기", + "reconnecting": "데스크톱에 다시 연결 중…", + "regenerateHint": "다시 생성하려면 메시지를 지웁니다.", + "stageAll": "모두 스테이지", + "unstageAll": "모두 언스테이징" + }, "createPrAction": { - "createReview": "{{titleLabel}} 만들기" + "checkingStatus": "리뷰 상태 확인 중…", + "createPullRequest": "PR 생성", + "createReview": "{{titleLabel}} 만들기", + "providerUnavailable": "이 제공업체에서는 리뷰를 생성할 수 없음", + "statusUnavailable": "리뷰 상태를 사용할 수 없음" }, "dropdownCounts": { "fastForwardCount_one": "커밋 {{count}}개 fast-forward", @@ -2572,6 +2683,64 @@ "titleUnpublishedForcePushCount_one": "브랜치 커밋 {{count}}개를 lease로 강제 푸시하고 필요하면 업스트림을 설정합니다.", "titleUnpublishedForcePushCount_other": "브랜치 커밋 {{count}}개를 lease로 강제 푸시하고 필요하면 업스트림을 설정합니다." }, + "fileList": { + "committedSection": "브랜치에 커밋됨" + }, + "fileRows": { + "addedByThem": "상대 쪽에서 추가됨", + "addedByUs": "우리 쪽에서 추가됨", + "bothAdded": "양쪽에서 추가됨", + "bothDeleted": "양쪽에서 삭제됨", + "bothModified": "양쪽에서 수정됨", + "committedSection": "브랜치에 커밋됨", + "committedUnavailable": "커밋된 변경 사항을 확인할 수 없습니다.", + "deletedByThem": "상대 쪽에서 삭제됨", + "deletedByUs": "우리 쪽에서 삭제됨", + "discardFile": "{{path}} 변경사항 취소", + "loadingCommitted": "커밋된 변경 사항 로드 중…", + "openChangedFile": "변경된 파일 {{path}} 열기", + "openCommittedChange": "{{path}}의 커밋된 변경 사항 열기", + "renamedFrom": "이전 경로: {{path}}", + "stageFile": "{{path}} 스테이지", + "unresolvedConflict": "해결되지 않은 충돌", + "unstageFile": "{{path}} 언스테이지" + }, + "gitHistory": { + "days_one": "{{count}}일", + "days_other": "{{count}}일", + "hours_one": "{{count}}시간", + "hours_other": "{{count}}시간", + "justNow": "방금 전", + "loadFailed": "커밋 기록을 로드하지 못했습니다.", + "minutes_one": "{{count}}분", + "minutes_other": "{{count}}분", + "months_one": "{{count}}개월", + "months_other": "{{count}}개월", + "noCommitMessage": "(커밋 메시지 없음)", + "years_one": "{{count}}년", + "years_other": "{{count}}년" + }, + "gitHistoryList": { + "loadFailed": "기록을 불러오지 못했습니다.", + "loadFilesFailed": "커밋 파일을 불러올 수 없습니다.", + "noCommits": "커밋이 없습니다.", + "noFileChanges": "파일 변경 사항 없음", + "retryFiles": "커밋 파일 다시 불러오기", + "waitingForDesktop": "데스크톱 응답 대기 중…" + }, + "gitStatus": { + "changes": "변경 사항", + "conflicts": "충돌", + "stagedChanges": "스테이징된 변경 사항" + }, + "header": { + "backToSession": "세션으로 돌아가기", + "close": "소스 제어 닫기", + "openNumberedPrWeb": "웹에서 PR #{{number}} 열기", + "openPrWeb": "웹에서 PR 열기", + "refresh": "소스 제어 새로고침", + "title": "소스 제어" + }, "hostedReview": { "mrCopy": { "reviewLabel": "MR", @@ -2584,9 +2753,81 @@ "titleLabel": "PR" } }, + "hostedReviewCopy": { + "committingChanges": "변경 사항 커밋 중…", + "creatingReview": "리뷰 생성 중…", + "forcePushing": "lease로 강제 푸시하는 중…", + "generatingCommitMessage": "커밋 메시지 생성 중…", + "publishingBranch": "브랜치를 게시하는 중…", + "pushingCommits": "커밋 푸시 중…", + "stagingChanges": "변경 사항 스테이징 중…", + "updatingBranch": "브랜치를 업데이트하는 중…" + }, "hostedReviewCreate": { "pushSucceeded": "푸시는 성공했지만 {{shortLabel}} 생성에 실패했습니다: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "PR을 준비하는 동안 브랜치가 변경되었습니다.", + "generateMessageFailed": "커밋 메시지를 생성하지 못했습니다. 소스 제어에서 메시지를 입력한 다음 다시 시도하세요.", + "resolveConflicts": "PR을 생성하기 전에 충돌을 해결하세요.", + "resolveOrStageChanges": "PR을 생성하기 전에 변경 사항을 정리하거나 스테이지하세요.", + "reviewCommitMessage": "커밋 메시지를 검토한 다음 PR 생성을 다시 시도하세요." + }, + "hostedReviewGitPreparation": { + "commitFailed": "커밋 실패", + "refreshFailed": "소스 제어를 새로고침할 수 없습니다.", + "stageFailed": "변경 사항을 스테이지하지 못했습니다.", + "updateBranchFailed": "원격 브랜치를 업데이트할 수 없습니다. PR 생성을 다시 시도하세요." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "lease로 강제 푸시하지 못했습니다.", + "publishFailed": "브랜치를 게시하지 못했습니다.", + "pushFailed": "커밋을 푸시하지 못했습니다." + }, + "hostedReviewService": { + "createFailed": "PR을 생성하지 못했습니다.", + "pushBeforeCreateFailed": "푸시에 실패했습니다. 푸시 오류를 해결한 후 다시 시도하세요." + }, + "hubTab": { + "changes": "변경 사항", + "commits": "커밋", + "pullRequest": "PR" + }, + "loaders": { + "connectingToDesktop": "데스크톱에 연결 중…", + "loadFailed": "소스 제어를 로드할 수 없습니다.", + "updateDesktop": "모바일에서 소스 제어를 사용하려면 Orca 데스크톱 앱을 업데이트하세요.", + "waitingForDesktop": "데스크톱 연결 대기 중…" + }, + "modals": { + "actionsTitle": "소스 제어", + "currentBranch": "현재", + "discardButton": "버리기", + "discardConfirmMessage": "\"{{path}}\"의 변경 사항을 버리시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "discardTitle": "변경사항 취소", + "openPrMessage": "브라우저에서 여시겠습니까?", + "openPrWithWarning": "브라우저에서 여시겠습니까?\n\n{{warning}}", + "prCreatedTitle": "PR 생성 완료", + "switchBranchTitle": "브랜치 전환" + }, + "openers": { + "openDiffFailed": "차이점을 열 수 없습니다.", + "tabNotReady": "파일은 열렸지만 탭이 아직 준비되지 않았습니다. 다시 시도하세요.", + "waitingForDesktop": "데스크톱 연결 대기 중…" + }, + "panel": { + "loadFailedTitle": "로드 실패", + "unavailableTitle": "소스 제어 사용 불가" + }, + "prChip": { + "createPr": "PR 생성", + "loading": "PR 로드 중…", + "loadingLabel": "PR 로드 중", + "openLabel": "PR #{{number}}, {{state}}, {{checks}}. PR 열기.", + "openWithComments_one": "PR #{{number}}, {{state}}, {{checks}}, 해결되지 않은 댓글 {{count}}개. PR 열기.", + "openWithComments_other": "PR #{{number}}, {{state}}, {{checks}}, 해결되지 않은 댓글 {{count}}개. PR 열기.", + "unavailableLabel": "PR 확인 불가: {{message}}" + }, "prCreate": { "authRequired": "{{reviewLabel}} 생성 전에 인증하세요.", "baseNotOnRemote": "{{reviewLabel}}을(를) 생성하기 전에 기본 브랜치를 푸시하세요.", @@ -2605,8 +2846,19 @@ "unsupportedMergeRequests": "이 저장소에서는 MR 생성을 지원하지 않습니다.", "unsupportedPullRequests": "이 저장소에서는 PR 생성을 지원하지 않습니다." }, + "prLink": { + "updatePullRequestFailed": "연결된 PR을 업데이트하지 못했습니다.", + "updateReviewFailed": "연결된 리뷰를 업데이트하지 못했습니다." + }, "primaryAction": { - "forcePushFromDesktop": "데스크톱에서 이 PR의 브랜치를 강제 푸시하세요." + "commit": "Commit", + "forcePush": "강제 푸시", + "forcePushFromDesktop": "데스크톱에서 이 PR의 브랜치를 강제 푸시하세요.", + "publishBranch": "브랜치 게시", + "pull": "풀", + "push": "푸시", + "stageAll": "모두 스테이지", + "sync": "동기화" }, "remoteDropdown": { "branchAlreadyPublished": "브랜치가 이미 게시되었습니다", @@ -2656,6 +2908,591 @@ "tryFastForwardPull": "fast-forward 풀을 시도합니다. git에서 로컬 커밋을 거부할 수 있습니다", "tryRegularPush": "일반 푸시를 시도합니다. git에서 강제 푸시가 필요할 수 있습니다", "useForcePushToSync": "강제 푸시를 사용하세요 — 원격에는 로컬 커밋의 이전 사본만 있습니다" + }, + "runners": { + "actionFailed": "소스 제어 작업에 실패했습니다." + }, + "screenState": { + "noBranch": "브랜치 없음" + }, + "state": { + "noUpstream": "업스트림 없음", + "syncStatus": "{{ahead}}개 앞섬, {{behind}}개 뒤처짐" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "에이전트를 실행하지 못했습니다.", + "waitingForDesktop": "데스크톱 연결 대기 중…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "커밋 메시지를 생성하지 못했습니다." + }, + "useMobileCreatePrRunner": { + "branchRequired": "PR을 생성하기 전에 브랜치를 체크아웃하세요." + }, + "useMobileGitRequests": { + "actionFailed": "소스 제어 작업에 실패했습니다.", + "branchUnavailable": "브랜치 상태를 확인할 수 없습니다.", + "commitFailed": "커밋 실패", + "waitingForDesktop": "데스크톱 연결 대기 중…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "기본 브랜치를 확인하지 못했습니다.", + "forkPushWarning": "이 PR에서 \"유지 관리자의 수정 허용\"이 꺼져 있어 GitHub에서 포크로의 푸시를 거부할 수 있습니다." + }, + "detailCommentRenderers": { + "commentPlaceholder": "댓글 추가", + "comments_one": "댓글 {{count}}개", + "comments_other": "댓글 {{count}}개", + "reopenThread": "스레드 다시 열기", + "reply": "회신", + "resolveThread": "스레드 해결", + "resolvedCommentBy": "{{author}}의 댓글 · 해결됨", + "resolvedThreadBy": "{{author}}의 스레드 · 해결됨", + "sendComment": "댓글 보내기", + "show": "표시" + }, + "filterPickers": { + "allTeams": "모든 팀", + "changeStatus": "상태 변경", + "fieldHidden": "카드에서 숨김", + "fieldShown": "카드에 표시됨", + "fieldsSubtitle": "항목 카드에 표시할 프로젝트 필드를 선택하세요.", + "fieldsTitle": "프로젝트 필드", + "gitlabFilter": "GitLab 필터", + "gitlabView": "GitLab 보기", + "jiraFilter": "Jira 필터", + "jiraSite": "Jira 사이트", + "linearFilter": "Linear 필터", + "linearIssue": "Linear 이슈", + "linearWorkspace": "Linear 워크스페이스", + "loadingStates": "상태 로드 중…", + "noFields": "이 보기에는 표시할 추가 필드가 없습니다.", + "noStates": "사용 가능한 상태가 없습니다.", + "switchWorkspaceFailed": "워크스페이스를 전환하지 못했습니다.", + "teamsSubtitle": "작업 화면에 표시할 팀을 선택하세요.", + "teamsTitle": "Linear 팀", + "teams_one": "팀 {{count}}개", + "teams_other": "팀 {{count}}개" + }, + "githubProjectList": { + "browseProjects": "프로젝트 검색", + "chooseProject": "GitHub 프로젝트를 선택하세요.", + "emptyField": "비어 있음", + "issueSubtitle": "이슈 · {{repository}}{{number}}", + "itemSubtitle": "프로젝트 항목 · {{repository}}{{number}}", + "items": "항목", + "moreFields_one": "필드 +{{count}}개", + "moreFields_other": "필드 +{{count}}개", + "noItems": "프로젝트 항목이 없습니다.", + "pullRequestSubtitle": "PR · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "추가", + "addByUrlHint": "목록에 없는 프로젝트는 URL로 추가하세요.", + "addPlaceholder": "URL 또는 소유자/번호로 추가", + "adding": "추가 중…", + "browseAll": "모두 찾아보기", + "browseLoading": "모두 찾아보기 (로드 중…)", + "chooseView": "프로젝트 보기 선택", + "loadFailed": "프로젝트를 로드하지 못했습니다.", + "noMatches": "일치하는 프로젝트가 없습니다.", + "noMoreProjects": "더 이상 프로젝트가 없습니다.", + "noProjects": "불러온 프로젝트 없음", + "organizationsError": "조직: {{message}}", + "organizationsLoadFailed": "일부 조직을 불러오지 못했습니다({{count}}개).", + "ownerLoadFailed": "{{owner}}의 프로젝트를 불러올 수 없습니다.", + "pin": "핀", + "pinned": "고정됨", + "recent": "최근", + "retryHint": "탭하여 다시 시도하세요.", + "searchProjects": "프로젝트 검색", + "sort": "프로젝트 정렬", + "subtitle": "작업 페이지에 표시할 프로젝트 보기를 선택하세요.", + "title": "GitHub 프로젝트", + "unsupportedLayout": "Orca는 아직 이 GitHub 프로젝트 레이아웃을 지원하지 않습니다.", + "view": "프로젝트 보기" + }, + "githubViewControls": { + "fields": "필드: {{fields}}", + "openView": "GitHub에서 보기 열기", + "sort": "정렬: {{sort}}", + "source": "출처: {{source}}" + }, + "itemActions": { + "changeStatus": "상태 변경", + "copyGitHubLink": "GitHub 링크 복사", + "copyLinearLink": "Linear 링크 복사", + "createWorkspace": "워크스페이스 만들기", + "creating": "만드는 중…", + "mergeConflicts": "GitHub에서 병합 충돌이 보고되었습니다.", + "mergeMergeRequest": "MR 병합", + "mergePullRequest": "PR 병합" + }, + "itemDetailContent": { + "addSubIssue": "하위 이슈 추가", + "assignee": "담당자", + "assignees": "담당자", + "checks": "체크", + "description": "설명", + "discussion": "토론", + "noChecks": "체크를 찾을 수 없습니다.", + "noComments": "댓글이 없습니다.", + "noPipelineRuns": "이 MR에 실행된 파이프라인이 없습니다.", + "noSubIssues": "하위 이슈가 없습니다.", + "none": "없음", + "pipeline": "파이프라인", + "pipelineJobs_one": "작업 {{count}}개", + "pipelineJobs_other": "작업 {{count}}개", + "project": "프로젝트", + "rerunAll": "모두 재실행", + "rerunFailed": "실패한 체크 재실행", + "status": "상태", + "subIssueTitle": "하위 이슈 제목", + "subIssues": "하위 이슈", + "type": "유형" + }, + "itemDetailDrawer": { + "refreshDetails": "상세 정보 새로고침" + }, + "itemFieldEditors": { + "addLabels": "추가할 라벨(쉼표로 구분)", + "addUsernames": "추가할 사용자 이름(쉼표로 구분)", + "assignees": "담당자", + "labels": "라벨", + "loadingAssignees": "담당자 로드 중…", + "loadingLabels": "라벨 로드 중…", + "noAssignableUsers": "이 저장소에서 담당자로 지정할 수 있는 사용자가 없습니다.", + "noLabels": "이 저장소에 라벨이 없습니다.", + "none": "없음", + "removeLabels": "제거할 라벨(쉼표로 구분)", + "removeUsernames": "제거할 사용자 이름(쉼표로 구분)", + "saveTitle": "제목 저장", + "title": "제목", + "updateAssignees": "담당자 업데이트", + "updateLabels": "라벨 업데이트" + }, + "itemReviewSections": { + "binaryFile": "바이너리 파일입니다.", + "changedFilesTitle": "변경된 파일", + "descriptionPlaceholder": "설명", + "fileContentsUnavailable": "파일 내용을 표시할 수 없습니다.", + "hideFile": "숨기기", + "loadingReviewers": "리뷰어 로드 중…", + "markUnviewed": "보지 않은 것으로 표시", + "markViewed": "본 것으로 표시", + "noDescription": "설명이 없습니다.", + "noReviewerSuggestions": "추천 리뷰어를 찾지 못했습니다.", + "noReviewersRequested": "요청한 리뷰어가 없습니다.", + "requestReview": "리뷰 요청", + "reviewersPlaceholder": "리뷰를 요청할 리뷰어", + "reviewersTitle": "리뷰어", + "saveDescription": "설명 저장", + "viewFile": "보기" + }, + "legacySurface": { + "loadIssuesFailed": "{{source}}에서 이슈를 로드하지 못했습니다.", + "mergeAction": "병합", + "mergeMethodTitle": "병합 방식", + "mergePullRequestTitle": "PR 병합", + "mergeRequestMergeMessage": "이 MR의 병합 방식을 선택하세요.", + "mergeRequestTitle": "머지 리퀘스트", + "pullRequestMergeMessage": "이 PR의 병합 방식을 선택하세요.", + "retryLoadingIssues": "{{source}}에서 이슈 로드 다시 시도", + "retrying": "다시 시도 중…", + "sourceFallback": "{{repo}}에서 선택한 이슈 소스인 upstream을 사용할 수 없습니다. origin을 사용합니다.", + "subIssueDataUnavailable": "현재 토큰으로는 하위 이슈 데이터를 조회할 수 없습니다.", + "updateItemTitle": "항목 업데이트" + }, + "linearList": { + "changeStatusFrom": "상태 변경(현재: {{status}})" + }, + "linearViewControls": { + "displayButton": "표시", + "groupLabel": "그룹화: {{group}}", + "orderLabel": "정렬: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "표시 속성", + "linearGroupTitle": "Linear 이슈 그룹화", + "linearOrderTitle": "Linear 이슈 정렬", + "linearViewTitle": "Linear 보기", + "sortTasksTitle": "작업 정렬" + }, + "listSurface": { + "connectLinearButton": "Linear 연결", + "connectLinearMessage": "작업 화면에서 할당받은 Linear 이슈를 바로 살펴보고 작업을 시작하세요.", + "connectLinearTitle": "Linear 계정 연결", + "jiraStatusFailed": "Jira 상태를 읽지 못했습니다.", + "updateDesktopMessage": "모바일 작업 화면을 사용하려면 더 최신 버전의 데스크톱 런타임이 필요합니다.", + "updateDesktopTitle": "Orca 데스크톱 업데이트" + }, + "options": { + "all": "모두", + "assignedToMe": "나에게 할당됨", + "assignee": "담당자", + "board": "보드", + "boardDescription": "그룹별 열", + "closedState": "닫힘", + "completedState": "완료됨", + "createdState": "내가 만든 이슈", + "githubAssignedIssuesDescription": "나에게 할당된 열린 이슈", + "githubDescription": "이슈 및 PR", + "githubIssuesDescription": "GitHub 이슈", + "githubOpenIssuesDescription": "열려 있는 GitHub 이슈", + "githubProjectsDescription": "GitHub 프로젝트 보기", + "githubPullRequestsDescription": "GitHub PR", + "gitlabAllDescription": "모든 GitLab 상태", + "gitlabClosedDescription": "닫힌 이슈 및 MR", + "gitlabDescription": "이슈 및 MR", + "gitlabMergedDescription": "병합된 MR", + "gitlabOpenDescription": "열린 이슈 및 MR", + "identifier": "식별자", + "issues": "이슈", + "jiraDescription": "할당된 이슈 및 보고한 이슈", + "labels": "라벨", + "linearAllDescription": "연결된 워크스페이스의 열린 이슈", + "linearAssignedDescription": "할당받은 이슈", + "linearCompletedDescription": "최근 완료된 이슈", + "linearCreatedDescription": "직접 생성한 이슈", + "linearDescription": "할당된 이슈 및 팀 이슈", + "list": "목록", + "listDescription": "이슈를 간결한 행으로 표시", + "mergedState": "병합됨", + "mine": "내 항목", + "myIssues": "내 이슈", + "myPullRequestsDescription": "내가 작성한 PR", + "myTodos": "내 할 일", + "myTodosDescription": "대기 중인 GitLab 할 일", + "needsReview": "리뷰 필요", + "noGrouping": "그룹화 없음", + "openPullRequestsDescription": "열린 PR", + "openState": "열림", + "priority": "우선순위", + "projectMergeRequests": "프로젝트 MR", + "projectMergeRequestsDescription": "저장소별 MR 및 이슈", + "projects": "프로젝트", + "pullRequests": "PR", + "repository": "리포지토리", + "repositorySortDescription": "저장소별로 그룹화한 후 최근 활동순 정렬", + "reviewRequestsDescription": "나에게 할당된 리뷰 요청", + "status": "상태", + "team": "팀", + "updated": "업데이트됨", + "updatedSortDescription": "최근 활동순" + }, + "pickerProjection": { + "allRepos": "모든 저장소", + "allSites": "모든 사이트", + "currentlyAscending": "현재 오름차순 · 탭하면 내림차순", + "currentlyDescending": "현재 내림차순 · 탭하면 오름차순", + "fieldAscending": "{{field}} 오름차순", + "fieldDescending": "{{field}} 내림차순", + "fields": "필드", + "repos_one": "저장소 {{count}}개", + "repos_other": "저장소 {{count}}개", + "selectTarget": "대상 선택", + "selectedFields": "필드 {{selected}}/{{total}}개", + "sortAscending": "오름차순 정렬", + "sources_one": "소스 {{count}}개", + "sources_other": "소스 {{count}}개", + "unsupportedLayout": "모바일에서 지원하지 않는 레이아웃", + "updatedSort": "업데이트됨", + "usesFieldAscending": "{{field}} 오름차순 사용", + "usesFieldDescending": "{{field}} 내림차순 사용", + "usesGitHubRankOrder": "GitHub 항목 순서 사용", + "viewNumber": "보기 #{{number}}", + "viewOrder": "보기 순서" + }, + "prFileDiff": { + "commentOnLine": "{{line}}번 줄에 댓글 추가", + "commentPlaceholder": "리뷰 댓글 추가", + "noTextChanges": "텍스트 변경 사항이 없습니다.", + "showingDiffLines": "차이점 총 {{total}}줄 중 처음 {{limit}}줄을 표시합니다." + }, + "projectComments": { + "comments_one": "댓글 {{count}}개", + "comments_other": "댓글 {{count}}개", + "discussion": "토론", + "editComment": "댓글 수정", + "noComments": "댓글이 없습니다.", + "reopenThread": "스레드 다시 열기", + "reply": "회신", + "resolveThread": "스레드 해결", + "resolvedCommentBy": "{{author}}의 해결된 댓글", + "resolvedThreadBy": "{{author}}의 해결된 스레드", + "show": "표시" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}}이(가) Orca에 추가되지 않았습니다. 데스크톱 앱에서 이 저장소를 추가한 후 모바일의 작업 화면을 새로고침하세요.", + "clearType": "유형 해제", + "closeItem": "항목 닫기", + "copyGitHubLink": "GitHub 링크 복사", + "copyRepository": "저장소 복사", + "createWorkspace": "워크스페이스 생성", + "draftIssue": "초안 이슈", + "issue": "이슈", + "issueType": "이슈 유형", + "loadingIssueTypes": "이슈 유형 로드 중…", + "mergePullRequest": "PR 병합", + "mergeRepositoryRequirement": "병합하려면 이 저장소가 Orca에 추가되어 있어야 합니다.", + "noIssueTypes": "이 저장소에 설정된 이슈 유형이 없습니다.", + "noType": "유형 없음", + "openInGitHub": "GitHub에서 열기", + "projectItem": "프로젝트 항목", + "projectSubtitle": "GitHub 프로젝트 · {{repository}}{{itemNumber}}", + "pullRequest": "PR", + "reopenItem": "항목 다시 열기", + "repositoryNotInOrca": "Orca에 없는 저장소", + "status": "상태", + "type": "유형", + "workspaceCreationRequirement": "워크스페이스는 GitHub 이슈와 PR에서만 생성할 수 있습니다." + }, + "projectFieldEditors": { + "clearField": "필드 비우기", + "completedIteration": "완료 · {{startDate}} · {{duration}}일", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "날짜를 YYYY-MM-DD 형식으로 입력하세요.", + "invalidNumber": "올바른 숫자를 입력하세요.", + "noIterations": "사용 가능한 반복 주기가 없습니다.", + "numberPlaceholder": "숫자", + "projectFields": "프로젝트 필드", + "saveField": "필드 저장", + "textPlaceholder": "텍스트", + "upcomingIteration": "진행 중 및 예정 · {{startDate}} · {{duration}}일" + }, + "projectMetadataEditors": { + "assignees": "담당자", + "description": "설명", + "labels": "라벨", + "loadingAssignees": "담당자 로드 중…", + "loadingLabels": "라벨 로드 중…", + "noAssignableUsers": "이 저장소에서 담당자로 지정할 수 있는 사용자가 없습니다.", + "noDescription": "설명이 없습니다.", + "noLabels": "이 저장소에 라벨이 없습니다.", + "none": "없음", + "saveDescription": "설명 저장", + "saveTitle": "제목 저장", + "title": "제목" + }, + "projectReviewPanels": { + "binaryFile": "바이너리 파일입니다.", + "changedFiles": "변경된 파일", + "checks": "체크", + "fileUnavailable": "파일 내용을 사용할 수 없습니다.", + "hideFile": "숨기기", + "loadingReviewers": "리뷰어 로드 중…", + "markUnviewed": "보지 않은 것으로 표시", + "markViewed": "본 것으로 표시", + "noChecks": "체크가 없습니다.", + "noReviewers": "요청한 리뷰어가 없습니다.", + "noSuggestions": "추천 리뷰어가 없습니다.", + "requestReview": "리뷰 요청", + "requestReviewers": "리뷰어 요청", + "rerunAll": "모두 재실행", + "rerunFailed": "실패한 체크 재실행", + "reviewers": "리뷰어", + "viewFile": "보기" + }, + "providerControls": { + "myTodos": "내 할 일", + "projectMergeRequests": "프로젝트 MR", + "sort": "정렬: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "{{base}}(으)로", + "nextPage": "다음 페이지", + "page": "{{page}}페이지", + "pageOfTotal": "{{page}} / {{total}}페이지", + "previousPage": "이전 페이지", + "selectPage": "페이지 선택, {{page}}페이지", + "selectPageOfTotal": "페이지 선택, 전체 {{total}}페이지 중 {{page}}페이지" + }, + "providerPickers": { + "allRepositories": "모든 리포지토리", + "githubView": "GitHub 보기", + "issueSources": "GitHub 이슈 소스", + "issueSourcesDescription": "각 리포지토리에서 이슈 조회와 작업 생성에 사용할 소스를 upstream과 origin 중에서 선택하세요.", + "issues": "이슈", + "noIssueSources": "사용할 수 있는 다른 이슈 소스가 없습니다.", + "origin": "origin", + "pageHint": "로드되었거나 로드 가능한 결과 페이지로 이동하세요.", + "pageLoaded": "로드됨", + "pageNotLoaded": "이전 결과를 로드합니다.", + "pageNumber": "{{page}}페이지", + "pages": "GitHub 페이지", + "pullRequests": "PR", + "queryingSource": "조회 대상: {{source}}", + "repoDescription": "조회할 리포지토리를 선택하세요.", + "repos": "리포지토리", + "taskSource": "작업 소스", + "upstream": "업스트림" + }, + "providerViewProjection": { + "all": "모두", + "allSites": "모든 사이트", + "allTeams": "모든 팀", + "allWorkspaces": "모든 워크스페이스", + "chooseProject": "프로젝트 선택", + "default": "기본", + "defaultSubtitle": "{{subtitle}} · 기본", + "issues": "이슈", + "list": "목록", + "noGrouping": "그룹화 없음", + "openState": "열림", + "priority": "우선순위", + "projects": "프로젝트", + "pullRequests": "PR", + "teams_one": "팀 {{count}}개", + "teams_other": "팀 {{count}}개", + "workspace": "워크스페이스" + }, + "reviewerLinear": { + "issues": "이슈", + "unassigned": "할당되지 않음" + }, + "screenChrome": { + "connectLinear": "Linear 연결", + "newGitHubIssue": "새 GitHub 이슈", + "newLinearIssue": "새 Linear 이슈", + "refreshGitHub": "GitHub 작업 새로 고침", + "refreshGitLab": "GitLab 작업 항목 새로 고침", + "refreshJira": "Jira 이슈 새로 고침", + "refreshLinear": "Linear 새로고침", + "title": "작업" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL, 예: project = ABC AND statusCategory != Done", + "projectPlaceholder": "프로젝트 보기 검색…", + "providerPlaceholder": "{{provider}} 작업 검색…" + }, + "smartSourceModes": { + "allStates": "모두", + "branch": "브랜치", + "closedState": "닫힘", + "mergedState": "병합됨", + "name": "이름", + "openState": "열림", + "smart": "스마트" + }, + "sparsePresetDraft": { + "directoryRequired": "하나 이상의 디렉터리를 추가합니다.", + "repoRelativeDirectoriesRequired": "루트, 절대 경로, 상위 경로가 아니라 repo 기준 상대 디렉터리를 사용하세요." + }, + "taskViewOptions": { + "allSubtitle": "선택한 사이트의 미해결 이슈", + "assignedSubtitle": "나에게 할당된 미해결 이슈", + "doneSubtitle": "최근 해결된 내 이슈", + "noGitHubTasks": "GitHub 작업 없음", + "noGitLabTasks": "GitLab 작업 없음", + "noJiraTasks": "Jira 작업 없음", + "noLinearTasks": "Linear 작업 없음", + "reportedSubtitle": "내가 보고한 미해결 이슈" + }, + "tasksCreateDrawers": { + "connect": "연결", + "connectLinearWorkspace": "Linear 워크스페이스 연결", + "createIssue": "이슈 생성", + "createWorkspaceIn": "워크스페이스 생성 리포지토리", + "description": "설명", + "descriptionPlaceholder": "배경 설명 추가", + "fileIn": "{{slug}}에 이슈 등록", + "issueSource": "이슈 소스", + "keySecurityHint": "키는 호스트 OS 키체인을 통해 암호화되어 로컬에 저장됩니다.", + "linearConnectSubtitle": "해당 워크스페이스의 이슈를 보려면 개인 API 키를 붙여넣으세요.", + "linearSettingsLink": "Linear 설정 / 보안 / 새 API 키", + "linearTeam": "Linear 팀", + "linearTeamSubtitle": "선택한 Linear 팀에 이슈를 생성하세요.", + "newIssueTitle": "새 {{providerLabel}} 이슈", + "origin": "origin", + "personalApiKey": "개인 API 키", + "repository": "리포지토리", + "repositorySubtitle": "선택한 리포지토리에 이슈를 생성하세요.", + "team": "팀", + "title": "제목", + "titlePlaceholder": "작업 제목", + "upstream": "업스트림" + }, + "workspaceAgentSelection": { + "blankTerminal": "빈 터미널" + }, + "workspaceCreateDrawer": { + "addRepository": "Linear 워크스페이스를 생성하기 전에 Git 리포지토리를 추가하세요.", + "advanced": "고급", + "agent": "에이전트", + "connect": "연결", + "connectFirst": "먼저 리포지토리를 연결하세요", + "connectRepository": "리포지토리 연결", + "connecting": "연결 중…", + "createFrom": "{{branch}} 기준으로 생성", + "defaultBranch": "기본 브랜치", + "detectingAgents": "에이전트 감지 중…", + "optional": "[선택 사항]", + "remoteRepository": "원격 리포지토리", + "repository": "리포지토리", + "repositoryNotFound": "리포지토리를 찾을 수 없습니다.", + "selectRepository": "리포지토리 선택", + "sshConnection": "SSH 연결", + "startFrom": "시작 기준", + "title": "워크스페이스 생성", + "workspaceName": "워크스페이스 이름" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "\"{{name}}\"이(가) 이미 존재합니다.", + "nameRequired": "이름을 입력하세요.", + "nameTooLong": "이름은 80자 이하여야 합니다.", + "openShell": "셸 열기" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "기존 브랜치나 참조를 선택하세요.", + "baseBranchTitle": "시작 기준", + "branchName": "브랜치 이름: {{name}}", + "defaultBranch": "기본 브랜치", + "defaultBranchSubtitle": "이 저장소에 설정된 기본 브랜치 사용", + "editPreset": "프리셋 편집: {{name}}", + "fullCheckout": "전체 체크아웃", + "fullCheckoutSubtitle": "저장소 전체 사용", + "newPreset": "새로운 사전 설정", + "noBranches": "일치하는 브랜치가 없습니다.", + "searchBranches": "브랜치 검색", + "sparseCheckoutTitle": "스파스 체크아웃" + }, + "workspaceSshGate": { + "authenticationFailed": "인증 실패", + "connected": "연결됨", + "connecting": "연결 중", + "connectionFailed": "연결 실패", + "deployingRelay": "릴레이 배포 중", + "disconnected": "연결 끊김", + "reconnectFailed": "다시 연결 실패", + "reconnecting": "다시 연결 중" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "항상 신뢰하고 실행", + "creating": "만드는 중…", + "directoriesLabel": "디렉터리", + "directories_one": "디렉터리 {{count}}개", + "directories_other": "디렉터리 {{count}}개", + "dontRun": "실행 안 함", + "editSparsePreset": "스파스 프리셋 편집", + "nameLabel": "이름", + "namePlaceholder": "렌더러 UI", + "newSetupScript": "새 설정 스크립트", + "newSparsePreset": "새 스파스 프리셋", + "runHooks": "후크 실행", + "runSetupAndCreate": "설정 실행 후 만들기", + "runSetupTitle": "{{name}}의 설정 스크립트를 실행하시겠습니까?", + "setupChangedTitle": "{{name}}의 설정 스크립트가 변경되었습니다", + "setupScript": "설정 스크립트", + "setupSubtitle": "{{name}}의 워크스페이스를 만들려면 먼저 설정 스크립트 실행 여부를 선택해야 합니다.", + "setupTitle": "설정 스크립트를 실행하시겠습니까?", + "skipSetupAndCreate": "설정 건너뛰고 만들기", + "trustFailed": "설정 스크립트 신뢰 설정에 실패했습니다.", + "trustSubtitle": "워크스페이스가 시작되기 전에 이 저장소의 orca.yaml이 컴퓨터에서 실행됩니다. 이 저장소를 신뢰하는 경우에만 실행하세요." + }, + "worktreeCreateRetry": { + "createFailed": "워크스페이스를 생성하지 못했습니다." } }, "terminal": { diff --git a/mobile/src/i18n/locales/pt.json b/mobile/src/i18n/locales/pt.json index 4e1b7077056..00929180c65 100644 --- a/mobile/src/i18n/locales/pt.json +++ b/mobile/src/i18n/locales/pt.json @@ -6,7 +6,7 @@ "connectingTo": "Conectando a {{name}}…", "default": "Padrão do sistema", "hostNotFound": "Host não encontrado", - "invalidSnapshot": "Dados de contas inválidos recebidos do host", + "invalidSnapshot": "Snapshot de contas inválido recebido do host", "loadingAccounts": "Carregando contas…", "manageAccountsHint": "Adicione contas ou autentique-as novamente em Configurações → Contas no desktop.", "refreshAccounts": "Atualizar contas", @@ -383,8 +383,8 @@ "stoppingState": "Parando…" }, "streamFrame": { - "streamEnded": "Transmissão da conversa encerrada", - "streamFailed": "Falha na transmissão da conversa" + "streamEnded": "Transmissão da transcrição encerrada", + "streamFailed": "Falha na transmissão da transcrição" }, "taskList": { "added": "Adicionada {{task}}", @@ -604,7 +604,7 @@ "resetting": "Redefinindo…", "resettingLabel": "Redefinindo limites de taxa do Codex", "scopedHint": "Usa uma redefinição obtida para {{scopeLabel}}", - "useReset": "Usar redefinição", + "useReset": "Redefinir agora", "useResetLabel": "Usar redefinição de limite de taxa do Codex" }, "customKeyModal": { @@ -1234,7 +1234,7 @@ "loadFolderFailed": "Não foi possível carregar a pasta", "loading": "Carregando…", "openFolder": "Abrir pasta {{name}}", - "previewFile": "Visualizar arquivo {{name}}", + "previewFile": "Pré-visualizar arquivo {{name}}", "retryLoading": "Tentar carregar {{path}} novamente", "unavailable": "Indisponível no celular" }, @@ -1261,16 +1261,16 @@ "editorLabel": "Editor de {{title}}" }, "filePreviewResponse": { - "binaryUnavailable": "Visualização de arquivos binários indisponível", + "binaryUnavailable": "Pré-visualização de arquivos binários indisponível", "bytes": "{{size}} B", - "fileChanged": "O arquivo foi alterado no desktop. Recarregue a visualização antes de salvar.", + "fileChanged": "O arquivo foi alterado no desktop. Recarregue a pré-visualização antes de salvar.", "fileNotFound": "Arquivo não encontrado", - "fileTooLarge": "Arquivo muito grande para visualização no celular", + "fileTooLarge": "Arquivo muito grande para pré-visualização no celular", "filesystemUnreachable": "Não foi possível acessar o sistema de arquivos do desktop", "kilobytes": "{{size}} KB", - "loadFailed": "Não foi possível carregar a visualização", + "loadFailed": "Não foi possível carregar a pré-visualização", "megabytes": "{{size}} MB", - "reloadBeforeSaving": "Recarregue a visualização antes de salvar.", + "reloadBeforeSaving": "Recarregue a pré-visualização antes de salvar.", "unknownSize": "tamanho desconhecido" }, "filePreviewScreen": { @@ -1290,8 +1290,8 @@ "waiting": "Aguardando o desktop…" }, "filePreviewSourceText": { - "previewLabel": "Visualização do arquivo", - "truncatedNote": "Visualização truncada. Tamanho do arquivo: {{size}}." + "previewLabel": "Pré-visualização do arquivo", + "truncatedNote": "Pré-visualização truncada. Tamanho do arquivo: {{size}}." }, "markdownPreviewImage": { "expandFallback": "Expandir imagem", @@ -1354,7 +1354,7 @@ "tryAgain": "Tente novamente." }, "tasksCard": { - "noSources": "Nenhuma fonte de tarefas conectada", + "noSources": "Nenhuma origem de tarefas conectada", "openProviderTasks": "Abrir tarefas do {{provider}}", "title": "Tarefas" } @@ -1532,7 +1532,21 @@ "workspace": "Espaço de Trabalho" } }, + "newWorkspace": { + "hostPicker": { + "title": "Criar Espaço de Trabalho em" + }, + "loadingDrawer": { + "downloadProgress": "Baixando… {{progress}}", + "downloading": "Baixando", + "loading": "Carregando" + } + }, "notifications": { + "desktopChannel": { + "name": "Notificações do desktop", + "silentName": "Notificações silenciosas do Orca" + }, "notificationDeliverySection": { "footer": "Os tipos de alerta seguem as configurações de notificação de cada desktop pareado. As notificações são pausadas após 7 dias sem usar este app; abra-o e reconecte-se para retomá-las.", "onlyWhenAway": "Só quando estiver longe do desktop", @@ -1853,7 +1867,7 @@ "sendKey": "Enviar {{label}}", "switchToBufferedInput": "Mudar para entrada de comandos em buffer", "switchToDesktopMode": "Alternar para o modo desktop", - "switchToLiveInput": "Mudar para entrada direta no terminal", + "switchToLiveInput": "Mudar para entrada em tempo real no terminal", "switchToPhoneMode": "Mudar para o modo celular" }, "activeContent": { @@ -2590,11 +2604,71 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "Nenhuma branch base disponível para fazer rebase", + "waitingForDesktop": "Aguardando o desktop…" + }, "actions": { + "checkingReviewStatus": "Verificando status da revisão.", + "checkoutBeforePublish": "Faça checkout de uma branch antes de publicar commits.", + "commitStagedChanges": "Faça commit das alterações staged.", "commits": "Commits", + "committing": "Commit em andamento.", "createPr": "Criar PR", + "enterCommitMessage": "Digite uma mensagem de commit para fazer commit.", + "forcePushWithLease": "Faça force push com lease para atualizar a branch remota.", + "forcePushing": "Force push em andamento.", + "linkedReviewUnavailable": "A branch da revisão vinculada está indisponível.", + "publishToOrigin": "Publique esta branch no origin.", + "pullCommits_many": "Faça pull de {{count}} commits.", + "pullCommits_one": "Faça pull de {{count}} commit.", + "pullCommits_other": "Faça pull de {{count}} commits.", "pushAndCreatePr": "Push e Criar PR", - "switchBranch": "Trocar de branch" + "pushCommits_many": "Faça push de {{count}} commits.", + "pushCommits_one": "Faça push de {{count}} commit.", + "pushCommits_other": "Faça push de {{count}} commits.", + "pushLinkedReview": "Faça push das atualizações para a branch da revisão vinculada.", + "remoteOperationInProgress": "Operação remota em andamento.", + "resolveConflicts": "Resolva os conflitos antes de fazer commit.", + "reviewAlreadyMerged": "Nada para fazer commit. A revisão já foi mergeada.", + "stageAllChanges": "Adicione todas as alterações ao stage.", + "stageFileToCommit": "Adicione pelo menos um arquivo ao stage para fazer commit.", + "switchBranch": "Trocar de branch", + "syncCounts": "Faça pull de {{behind}} e push de {{ahead}}.", + "upToDate": "Nada para fazer commit. A branch está atualizada.", + "waitForRemoteOperation": "Tente novamente quando a operação remota terminar." + }, + "branchBaseRef": { + "resolveFailed": "Não foi possível determinar a branch base" + }, + "branchCard": { + "branchCount": "{{count}} na branch", + "changedCount": "Alterações: {{count}}", + "cherryPickState": "cherry-pick", + "mergeState": "merge", + "rebaseState": "rebase", + "stagedCount": "No stage: {{count}}" + }, + "branchCompare": { + "commits_many": "{{count}} commits", + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commits", + "files_many": "{{count}} arquivos", + "files_one": "{{count}} arquivo", + "files_other": "{{count}} arquivos", + "sectionTitle": "Commitado na Branch", + "summary": "{{files}} - em relação a {{baseRef}}", + "summaryWithCommits": "{{files}} - {{commits}} - em relação a {{baseRef}}" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Não foi possível determinar a branch base para comparação.", + "loadFailed": "Não foi possível carregar as alterações commitadas" + }, + "branchDiffPreviewDrawer": { + "closePreview": "Fechar prévia do diff commitado", + "committedOnBranch": "Commitado na branch", + "loadFailed": "Não foi possível carregar o diff", + "truncated": "Diff truncado para prévia no celular." }, "commitDropdown": { "checkOutBranchToPush": "Faça checkout de uma branch antes de fazer push de commits", @@ -2619,8 +2693,49 @@ "stageFile": "Coloque pelo menos um arquivo em stage para fazer commit", "useCommitAndForcePush": "Use Commit e Force Push — o remoto só tem cópias antigas de commits locais" }, + "commitFailurePanel": { + "fix": "Corrigir", + "fixWithAi": "Corrigir falha de commit com IA", + "hideDetails": "Ocultar detalhes", + "hideFailureDetails": "Ocultar detalhes da falha no commit", + "showDetails": "Mostrar detalhes", + "showFailureDetails": "Mostrar detalhes da falha no commit", + "summary": "Falha no commit.", + "title": "Falha no commit" + }, + "commitMessageAi": { + "generateFailed": "Falha ao gerar mensagem de commit" + }, + "commitRunners": { + "actionFailed": "Falha na ação de controle de versão", + "commitFailed": "Falha no commit" + }, + "conflictAbort": { + "abortMerge": "Abortar merge", + "abortOperation": "Abortar {{operation}}", + "abortRebase": "Abortar rebase", + "aborting": "Abortando…" + }, + "content": { + "cancelGeneration": "Cancelar geração da mensagem de commit", + "commitMessageDisabled": "Mensagem de commit desativada. Nenhum arquivo no stage.", + "commitMessagePlaceholder": "Mensagem de commit", + "emptyMessage": "A árvore de trabalho está limpa.", + "emptyTitle": "Nenhuma alteração local", + "generateMessage": "Gerar mensagem de commit com IA", + "noStagedFiles": "Nenhum arquivo no stage", + "openActions": "Abrir ações de controle de versão", + "reconnecting": "Reconectando ao desktop…", + "regenerateHint": "Limpe a mensagem para gerar novamente.", + "stageAll": "Colocar Tudo em Stage", + "unstageAll": "Remover Tudo do Stage" + }, "createPrAction": { - "createReview": "Criar {{titleLabel}}" + "checkingStatus": "Verificando status de review…", + "createPullRequest": "Criar Pull Request", + "createReview": "Criar {{titleLabel}}", + "providerUnavailable": "Criação de revisões indisponível para este provedor", + "statusUnavailable": "Status de review indisponível" }, "dropdownCounts": { "fastForwardCount_many": "Fazer fast-forward de {{count}} commits", @@ -2649,6 +2764,69 @@ "titleUnpublishedForcePushCount_one": "Faça force push com lease de {{count}} commit da branch e defina um upstream se necessário.", "titleUnpublishedForcePushCount_other": "Faça force push com lease de {{count}} commits da branch e defina um upstream se necessário." }, + "fileList": { + "committedSection": "Commitado na Branch" + }, + "fileRows": { + "addedByThem": "Adicionado por eles", + "addedByUs": "Adicionado por nós", + "bothAdded": "Adicionado por ambos", + "bothDeleted": "Excluído por ambos", + "bothModified": "Modificado por ambos", + "committedSection": "Commitado na Branch", + "committedUnavailable": "Alterações commitadas indisponíveis.", + "deletedByThem": "Excluído por eles", + "deletedByUs": "Excluído por nós", + "discardFile": "Descartar {{path}}", + "loadingCommitted": "Carregando alterações commitadas…", + "openChangedFile": "Abrir arquivo alterado {{path}}", + "openCommittedChange": "Abrir alteração commitada em {{path}}", + "renamedFrom": "de {{path}}", + "stageFile": "Adicionar {{path}} ao stage", + "unresolvedConflict": "Conflito não resolvido", + "unstageFile": "Remover {{path}} do stage" + }, + "gitHistory": { + "days_many": "{{count}}d", + "days_one": "{{count}}d", + "days_other": "{{count}}d", + "hours_many": "{{count}}h", + "hours_one": "{{count}}h", + "hours_other": "{{count}}h", + "justNow": "agora mesmo", + "loadFailed": "Falha ao carregar o histórico de commits", + "minutes_many": "{{count}}m", + "minutes_one": "{{count}}m", + "minutes_other": "{{count}}m", + "months_many": "{{count}} meses", + "months_one": "{{count}} mês", + "months_other": "{{count}} meses", + "noCommitMessage": "(sem mensagem de commit)", + "years_many": "{{count}} anos", + "years_one": "{{count}} ano", + "years_other": "{{count}} anos" + }, + "gitHistoryList": { + "loadFailed": "Falha ao carregar o histórico", + "loadFilesFailed": "Não foi possível carregar os arquivos do commit", + "noCommits": "Nenhum commit.", + "noFileChanges": "Nenhuma alteração em arquivos", + "retryFiles": "Tentar carregar os arquivos do commit novamente", + "waitingForDesktop": "Aguardando o desktop…" + }, + "gitStatus": { + "changes": "Alterações", + "conflicts": "Conflitos", + "stagedChanges": "Alterações no Stage" + }, + "header": { + "backToSession": "Voltar à sessão", + "close": "Fechar controle de código-fonte", + "openNumberedPrWeb": "Abrir pull request #{{number}} na web", + "openPrWeb": "Abrir pull request na web", + "refresh": "Atualizar controle de código-fonte", + "title": "Controle de Código-Fonte" + }, "hostedReview": { "mrCopy": { "reviewLabel": "merge request", @@ -2661,9 +2839,82 @@ "titleLabel": "Pull Request" } }, + "hostedReviewCopy": { + "committingChanges": "Commitando alterações…", + "creatingReview": "Criando revisão…", + "forcePushing": "Fazendo force push com lease…", + "generatingCommitMessage": "Gerando mensagem de commit…", + "publishingBranch": "Publicando a branch…", + "pushingCommits": "Enviando (push) commits…", + "stagingChanges": "Adicionando alterações ao stage…", + "updatingBranch": "Atualizando a branch…" + }, "hostedReviewCreate": { "pushSucceeded": "Push concluído, mas a criação do {{shortLabel}} falhou: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "A branch mudou durante a preparação do pull request.", + "generateMessageFailed": "Não foi possível gerar uma mensagem de commit. Adicione uma no Controle de Código-Fonte e tente novamente.", + "resolveConflicts": "Resolva os conflitos antes de criar um pull request.", + "resolveOrStageChanges": "Resolva as pendências ou adicione as alterações ao stage antes de criar um pull request.", + "reviewCommitMessage": "Revise a mensagem de commit e tente novamente Criar PR." + }, + "hostedReviewGitPreparation": { + "commitFailed": "Falha no commit", + "refreshFailed": "Não foi possível atualizar o controle de versão", + "stageFailed": "Falha ao adicionar alterações ao stage", + "updateBranchFailed": "Não foi possível atualizar a branch remota. Tente novamente Criar PR." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "Falha ao fazer force push com lease", + "publishFailed": "Falha ao publicar a branch", + "pushFailed": "Falha ao fazer push dos commits" + }, + "hostedReviewService": { + "createFailed": "Falha ao criar pull request", + "pushBeforeCreateFailed": "O push falhou. Resolva o erro de push e tente novamente." + }, + "hubTab": { + "changes": "Alterações", + "commits": "Commits", + "pullRequest": "Pull Request" + }, + "loaders": { + "connectingToDesktop": "Conectando ao desktop…", + "loadFailed": "Não foi possível carregar o controle de versão", + "updateDesktop": "Atualize o Orca no desktop para usar o controle de versão no celular.", + "waitingForDesktop": "Aguardando o desktop…" + }, + "modals": { + "actionsTitle": "Controle de Código-Fonte", + "currentBranch": "atual", + "discardButton": "Descartar", + "discardConfirmMessage": "Descartar alterações em \"{{path}}\"? Esta ação não pode ser desfeita.", + "discardTitle": "Descartar alteração?", + "openPrMessage": "Abrir no seu navegador?", + "openPrWithWarning": "Abrir no seu navegador?\n\n{{warning}}", + "prCreatedTitle": "Pull Request Criado", + "switchBranchTitle": "Trocar Branch" + }, + "openers": { + "openDiffFailed": "Não foi possível abrir o diff", + "tabNotReady": "O arquivo foi aberto, mas a aba ainda não está pronta. Tente novamente.", + "waitingForDesktop": "Aguardando o desktop…" + }, + "panel": { + "loadFailedTitle": "Não foi possível carregar", + "unavailableTitle": "Controle de Código-Fonte Indisponível" + }, + "prChip": { + "createPr": "Criar pull request", + "loading": "Carregando pull request…", + "loadingLabel": "Carregando pull request", + "openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Abrir pull request.", + "openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentários não resolvidos. Abrir pull request.", + "openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentário não resolvido. Abrir pull request.", + "openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentários não resolvidos. Abrir pull request.", + "unavailableLabel": "Pull request indisponível: {{message}}" + }, "prCreate": { "authRequired": "Autentique-se antes de criar um {{reviewLabel}}.", "baseNotOnRemote": "Faça push da branch base antes de criar um {{reviewLabel}}.", @@ -2682,8 +2933,19 @@ "unsupportedMergeRequests": "Não há suporte à criação de merge requests neste repositório.", "unsupportedPullRequests": "Não há suporte à criação de pull requests neste repositório." }, + "prLink": { + "updatePullRequestFailed": "Falha ao atualizar o pull request vinculado", + "updateReviewFailed": "Falha ao atualizar a revisão vinculada" + }, "primaryAction": { - "forcePushFromDesktop": "Faça force push da branch deste pull request pelo desktop" + "commit": "Commit", + "forcePush": "Force Push", + "forcePushFromDesktop": "Faça force push da branch deste pull request pelo desktop", + "publishBranch": "Publicar Branch", + "pull": "Pull", + "push": "Push", + "stageAll": "Colocar Tudo em Stage", + "sync": "Sincronizar" }, "remoteDropdown": { "branchAlreadyPublished": "A branch já está publicada", @@ -2733,6 +2995,600 @@ "tryFastForwardPull": "Tente um pull com fast-forward; o git pode rejeitar commits locais", "tryRegularPush": "Tente um push normal; o git pode exigir force push", "useForcePushToSync": "Use Force Push — o remoto só tem cópias antigas de commits locais" + }, + "runners": { + "actionFailed": "Falha na ação de controle de versão" + }, + "screenState": { + "noBranch": "Sem branch" + }, + "state": { + "noUpstream": "Sem upstream", + "syncStatus": "{{ahead}} à frente, {{behind}} atrás" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Falha ao iniciar o agente", + "waitingForDesktop": "Aguardando o desktop…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Falha ao gerar a mensagem de commit" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Faça checkout de uma branch antes de criar um pull request." + }, + "useMobileGitRequests": { + "actionFailed": "Falha na ação de controle de versão", + "branchUnavailable": "Status da branch indisponível", + "commitFailed": "Falha no commit", + "waitingForDesktop": "Aguardando o desktop…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "Falha ao determinar a branch base.", + "forkPushWarning": "Este PR está com \"Permitir edições de mantenedores\" desativado; o GitHub pode rejeitar o push para o fork." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Adicionar um comentário", + "comments_many": "{{count}} comentários", + "comments_one": "{{count}} comentário", + "comments_other": "{{count}} comentários", + "reopenThread": "Reabrir thread", + "reply": "Responder", + "resolveThread": "Resolver thread", + "resolvedCommentBy": "Comentário de {{author}} resolvido", + "resolvedThreadBy": "Thread de {{author}} resolvida", + "sendComment": "Enviar comentário", + "show": "Mostrar" + }, + "filterPickers": { + "allTeams": "Todas as equipes", + "changeStatus": "Alterar status", + "fieldHidden": "Oculto nos cartões", + "fieldShown": "Exibido nos cartões", + "fieldsSubtitle": "Selecione quais campos do projeto aparecem nos cartões dos itens.", + "fieldsTitle": "Campos do Projeto", + "gitlabFilter": "Filtro do GitLab", + "gitlabView": "Visualização do GitLab", + "jiraFilter": "Filtro do Jira", + "jiraSite": "Site do Jira", + "linearFilter": "Filtro do Linear", + "linearIssue": "Issue do Linear", + "linearWorkspace": "Espaço de trabalho do Linear", + "loadingStates": "Carregando estados…", + "noFields": "Esta visualização não tem campos extras para mostrar.", + "noStates": "Nenhum estado disponível", + "switchWorkspaceFailed": "Falha ao trocar de espaço de trabalho", + "teamsSubtitle": "Selecione quais equipes aparecem em Tarefas.", + "teamsTitle": "Equipes do Linear", + "teams_many": "{{count}} equipes", + "teams_one": "{{count}} equipe", + "teams_other": "{{count}} equipes" + }, + "githubProjectList": { + "browseProjects": "Navegar pelos projetos", + "chooseProject": "Selecione um projeto do GitHub", + "emptyField": "Vazio", + "issueSubtitle": "Issue · {{repository}}{{number}}", + "itemSubtitle": "Item do projeto · {{repository}}{{number}}", + "items": "Itens", + "moreFields_many": "+{{count}} campos", + "moreFields_one": "+{{count}} campo", + "moreFields_other": "+{{count}} campos", + "noItems": "Nenhum item no projeto", + "pullRequestSubtitle": "Pull request · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Adicionar", + "addByUrlHint": "Use Adicionar por URL para acessar os projetos ausentes.", + "addPlaceholder": "Adicionar por URL ou owner/número", + "adding": "Adicionando…", + "browseAll": "Navegar por todos", + "browseLoading": "Navegar por todos (carregando…)", + "chooseView": "Selecionar visualização do projeto", + "loadFailed": "Falha ao carregar os projetos", + "noMatches": "Nenhum projeto corresponde à busca.", + "noMoreProjects": "Não há mais projetos.", + "noProjects": "Nenhum projeto carregado", + "organizationsError": "organizações: {{message}}", + "organizationsLoadFailed": "Algumas organizações não foram carregadas ({{count}}).", + "ownerLoadFailed": "Não foi possível carregar os projetos de {{owner}}.", + "pin": "Fixar", + "pinned": "Fixados", + "recent": "Recentes", + "retryHint": "Toque para tentar novamente.", + "searchProjects": "Buscar projetos", + "sort": "Ordenação do projeto", + "subtitle": "Selecione uma visualização de projeto para a página Tarefas.", + "title": "GitHub Projects", + "unsupportedLayout": "O Orca ainda não oferece suporte a este layout de projeto do GitHub.", + "view": "Visualização do projeto" + }, + "githubViewControls": { + "fields": "Campos: {{fields}}", + "openView": "Abrir visualização no GitHub", + "sort": "Ordenação: {{sort}}", + "source": "Origem: {{source}}" + }, + "itemActions": { + "changeStatus": "Alterar status", + "copyGitHubLink": "Copiar link do GitHub", + "copyLinearLink": "Copiar link do Linear", + "createWorkspace": "Criar espaço de trabalho", + "creating": "Criando…", + "mergeConflicts": "O GitHub informa conflitos de merge.", + "mergeMergeRequest": "Fazer merge do merge request", + "mergePullRequest": "Fazer merge do pull request" + }, + "itemDetailContent": { + "addSubIssue": "Adicionar sub-issue", + "assignee": "Responsável", + "assignees": "Responsáveis", + "checks": "Verificações", + "description": "Descrição", + "discussion": "Discussão", + "noChecks": "Nenhuma verificação encontrada.", + "noComments": "Sem comentários.", + "noPipelineRuns": "Nenhuma execução de pipeline para este MR.", + "noSubIssues": "Nenhuma sub-issue.", + "none": "Nenhum item", + "pipeline": "Pipeline", + "pipelineJobs_many": "{{count}} jobs", + "pipelineJobs_one": "{{count}} job", + "pipelineJobs_other": "{{count}} jobs", + "project": "Projeto", + "rerunAll": "Reexecutar todas", + "rerunFailed": "Reexecutar as que falharam", + "status": "Status", + "subIssueTitle": "Título da sub-issue", + "subIssues": "Sub-issues", + "type": "Tipo" + }, + "itemDetailDrawer": { + "refreshDetails": "Atualizar detalhes" + }, + "itemFieldEditors": { + "addLabels": "Adicionar rótulos, separados por vírgula", + "addUsernames": "Adicionar nomes de usuário, separados por vírgula", + "assignees": "Responsáveis", + "labels": "Rótulos", + "loadingAssignees": "Carregando responsáveis…", + "loadingLabels": "Carregando rótulos…", + "noAssignableUsers": "Nenhum usuário disponível para atribuição neste repositório.", + "noLabels": "Nenhum rótulo neste repositório.", + "none": "Nenhum", + "removeLabels": "Remover rótulos, separados por vírgula", + "removeUsernames": "Remover nomes de usuário, separados por vírgula", + "saveTitle": "Salvar título", + "title": "Título", + "updateAssignees": "Atualizar responsáveis", + "updateLabels": "Atualizar rótulos" + }, + "itemReviewSections": { + "binaryFile": "Arquivo binário.", + "changedFilesTitle": "Arquivos alterados", + "descriptionPlaceholder": "Descrição", + "fileContentsUnavailable": "Conteúdo do arquivo indisponível.", + "hideFile": "Ocultar", + "loadingReviewers": "Carregando revisores…", + "markUnviewed": "Marcar como não visualizado", + "markViewed": "Marcar como visualizado", + "noDescription": "Sem descrição.", + "noReviewerSuggestions": "Nenhuma sugestão de revisor encontrada.", + "noReviewersRequested": "Nenhum revisor solicitado.", + "requestReview": "Solicitar revisão", + "reviewersPlaceholder": "Solicitar revisores", + "reviewersTitle": "Revisores", + "saveDescription": "Salvar descrição", + "viewFile": "Ver" + }, + "legacySurface": { + "loadIssuesFailed": "Não foi possível carregar as issues de {{source}}.", + "mergeAction": "Merge", + "mergeMethodTitle": "Método de merge", + "mergePullRequestTitle": "Fazer Merge do Pull Request", + "mergeRequestMergeMessage": "Escolha como fazer merge deste merge request.", + "mergeRequestTitle": "Merge Request", + "pullRequestMergeMessage": "Escolha como fazer merge deste pull request.", + "retryLoadingIssues": "Tentar carregar novamente as issues de {{source}}", + "retrying": "Tentando novamente…", + "sourceFallback": "A origem de issues preferida, upstream, está indisponível para {{repo}}. Usando origin.", + "subIssueDataUnavailable": "Os dados de sub-issue não estão disponíveis para o seu token.", + "updateItemTitle": "Atualizar Item" + }, + "linearList": { + "changeStatusFrom": "Alterar status de {{status}}" + }, + "linearViewControls": { + "displayButton": "Exibição", + "groupLabel": "Agrupar por: {{group}}", + "orderLabel": "Ordem: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Propriedades de exibição", + "linearGroupTitle": "Agrupar issues do Linear", + "linearOrderTitle": "Ordenar issues do Linear", + "linearViewTitle": "Visualização do Linear", + "sortTasksTitle": "Ordenar tarefas" + }, + "listSurface": { + "connectLinearButton": "Conectar Linear", + "connectLinearMessage": "Veja as issues do Linear atribuídas a você e comece a trabalhar nelas diretamente em Tarefas.", + "connectLinearTitle": "Conecte sua conta do Linear", + "jiraStatusFailed": "Falha ao ler o status do Jira", + "updateDesktopMessage": "Esta visualização de Tarefas no celular requer uma versão mais recente do Orca no desktop.", + "updateDesktopTitle": "Atualize o Orca no desktop" + }, + "options": { + "all": "Todos", + "assignedToMe": "Atribuído a mim", + "assignee": "Responsável", + "board": "Quadro", + "boardDescription": "Colunas agrupadas", + "closedState": "Fechados", + "completedState": "Concluídas", + "createdState": "Criadas", + "githubAssignedIssuesDescription": "Issues abertas atribuídas a você", + "githubDescription": "Issues e pull requests", + "githubIssuesDescription": "Issues do GitHub", + "githubOpenIssuesDescription": "Issues abertas do GitHub", + "githubProjectsDescription": "Visualizações do GitHub Projects", + "githubPullRequestsDescription": "Pull requests do GitHub", + "gitlabAllDescription": "Qualquer estado do GitLab", + "gitlabClosedDescription": "Issues e merge requests fechados", + "gitlabDescription": "Issues e merge requests", + "gitlabMergedDescription": "Merge requests mergeados", + "gitlabOpenDescription": "Issues e merge requests em aberto", + "identifier": "Identificador", + "issues": "Issues", + "jiraDescription": "Issues atribuídas e relatadas", + "labels": "Rótulos", + "linearAllDescription": "Issues abertas nos espaços de trabalho conectados", + "linearAssignedDescription": "Issues atribuídas a você", + "linearCompletedDescription": "Issues concluídas recentemente", + "linearCreatedDescription": "Issues criadas por você", + "linearDescription": "Issues atribuídas e da equipe", + "list": "Lista", + "listDescription": "Issues em linhas compactas", + "mergedState": "Mergeados", + "mine": "Meus", + "myIssues": "Minhas issues", + "myPullRequestsDescription": "Pull requests criados por você", + "myTodos": "Minhas pendências", + "myTodosDescription": "Pendências do GitLab", + "needsReview": "Precisa de revisão", + "noGrouping": "Sem agrupamento", + "openPullRequestsDescription": "Pull requests abertos", + "openState": "Em aberto", + "priority": "Prioridade", + "projectMergeRequests": "MRs do projeto", + "projectMergeRequestsDescription": "Merge requests e issues por repositório", + "projects": "Projetos", + "pullRequests": "PRs", + "repository": "Repositório", + "repositorySortDescription": "Agrupar por repositório, depois pela atividade mais recente", + "reviewRequestsDescription": "Solicitações de revisão atribuídas a você", + "status": "Status", + "team": "Equipe", + "updated": "Atualizado", + "updatedSortDescription": "Atividade mais recente primeiro" + }, + "pickerProjection": { + "allRepos": "Todos os repositórios", + "allSites": "Todos os sites", + "currentlyAscending": "Crescente · toque para inverter", + "currentlyDescending": "Decrescente · toque para inverter", + "fieldAscending": "{{field}} cresc.", + "fieldDescending": "{{field}} decresc.", + "fields": "Campos", + "repos_many": "{{count}} repositórios", + "repos_one": "{{count}} repositório", + "repos_other": "{{count}} repositórios", + "selectTarget": "Selecionar destino", + "selectedFields": "{{selected}}/{{total}} campos", + "sortAscending": "Ordenar em ordem crescente", + "sources_many": "{{count}} origens", + "sources_one": "{{count}} origem", + "sources_other": "{{count}} origens", + "unsupportedLayout": "Layout não compatível no celular", + "updatedSort": "Atualizado", + "usesFieldAscending": "Usa {{field}} em ordem crescente", + "usesFieldDescending": "Usa {{field}} em ordem decrescente", + "usesGitHubRankOrder": "Usa a ordem de classificação do GitHub", + "viewNumber": "Visualização #{{number}}", + "viewOrder": "Ordem da visualização" + }, + "prFileDiff": { + "commentOnLine": "Comentar na linha {{line}}", + "commentPlaceholder": "Adicionar comentário de revisão", + "noTextChanges": "Nenhuma alteração de texto encontrada.", + "showingDiffLines": "Exibindo as primeiras {{limit}} de {{total}} linhas do diff." + }, + "projectComments": { + "comments_many": "{{count}} comentários", + "comments_one": "{{count}} comentário", + "comments_other": "{{count}} comentários", + "discussion": "Discussão", + "editComment": "Editar comentário", + "noComments": "Nenhum comentário.", + "reopenThread": "Reabrir thread", + "reply": "Responder", + "resolveThread": "Resolver thread", + "resolvedCommentBy": "Comentário de {{author}} resolvido", + "resolvedThreadBy": "Thread de {{author}} resolvida", + "show": "Mostrar" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} não foi adicionado ao Orca. Adicione este repositório pelo app desktop e depois atualize Tarefas no celular.", + "clearType": "Limpar tipo", + "closeItem": "Fechar item", + "copyGitHubLink": "Copiar link do GitHub", + "copyRepository": "Copiar repositório", + "createWorkspace": "Criar Espaço de Trabalho", + "draftIssue": "Rascunho de issue", + "issue": "Issue", + "issueType": "Tipo de issue", + "loadingIssueTypes": "Carregando tipos de issue…", + "mergePullRequest": "Fazer merge do pull request", + "mergeRepositoryRequirement": "Para fazer merge, este repositório precisa estar no Orca.", + "noIssueTypes": "Nenhum tipo de issue configurado para este repositório.", + "noType": "Sem tipo", + "openInGitHub": "Abrir no GitHub", + "projectItem": "Item do projeto", + "projectSubtitle": "Projeto do GitHub · {{repository}}{{itemNumber}}", + "pullRequest": "Pull request", + "reopenItem": "Reabrir item", + "repositoryNotInOrca": "Repositório não está no Orca", + "status": "Status", + "type": "Tipo", + "workspaceCreationRequirement": "Espaços de trabalho só podem ser criados a partir de issues e pull requests do GitHub." + }, + "projectFieldEditors": { + "clearField": "Limpar campo", + "completedIteration": "Concluída · {{startDate}} · {{duration}}d", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "Digite uma data no formato YYYY-MM-DD.", + "invalidNumber": "Digite um número válido.", + "noIterations": "Nenhuma iteração disponível.", + "numberPlaceholder": "Número", + "projectFields": "Campos do projeto", + "saveField": "Salvar campo", + "textPlaceholder": "Texto", + "upcomingIteration": "Atual e próximas · {{startDate}} · {{duration}}d" + }, + "projectMetadataEditors": { + "assignees": "Responsáveis", + "description": "Descrição", + "labels": "Rótulos", + "loadingAssignees": "Carregando responsáveis…", + "loadingLabels": "Carregando rótulos…", + "noAssignableUsers": "Nenhum usuário disponível para atribuição neste repositório.", + "noDescription": "Sem descrição.", + "noLabels": "Nenhum rótulo neste repositório.", + "none": "Nenhum", + "saveDescription": "Salvar descrição", + "saveTitle": "Salvar título", + "title": "Título" + }, + "projectReviewPanels": { + "binaryFile": "Arquivo binário.", + "changedFiles": "Arquivos alterados", + "checks": "Verificações", + "fileUnavailable": "Conteúdo do arquivo indisponível.", + "hideFile": "Ocultar", + "loadingReviewers": "Carregando revisores…", + "markUnviewed": "Marcar como não visualizado", + "markViewed": "Marcar como visualizado", + "noChecks": "Nenhuma verificação encontrada.", + "noReviewers": "Nenhum revisor solicitado.", + "noSuggestions": "Nenhuma sugestão de revisor encontrada.", + "requestReview": "Solicitar revisão", + "requestReviewers": "Solicitar revisores", + "rerunAll": "Reexecutar todas", + "rerunFailed": "Reexecutar as que falharam", + "reviewers": "Revisores", + "viewFile": "Ver" + }, + "providerControls": { + "myTodos": "Minhas pendências", + "projectMergeRequests": "MRs do projeto", + "sort": "Ordenar por: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "para {{base}}", + "nextPage": "Próxima página", + "page": "Página {{page}}", + "pageOfTotal": "Página {{page}} de {{total}}", + "previousPage": "Página anterior", + "selectPage": "Selecionar página, página {{page}}", + "selectPageOfTotal": "Selecionar página, página {{page}} de {{total}}" + }, + "providerPickers": { + "allRepositories": "Todos os repositórios", + "githubView": "Visualização do GitHub", + "issueSources": "Origens de issues do GitHub", + "issueSourcesDescription": "Escolha, para cada repositório, se deseja buscar e criar issues em upstream ou origin.", + "issues": "Issues", + "noIssueSources": "Nenhuma origem alternativa de issues disponível.", + "origin": "Origin", + "pageHint": "Ir para uma página de resultados carregada ou disponível.", + "pageLoaded": "Carregada", + "pageNotLoaded": "Carrega resultados mais antigos", + "pageNumber": "Página {{page}}", + "pages": "Páginas do GitHub", + "pullRequests": "Pull Requests", + "queryingSource": "Consultando {{source}}", + "repoDescription": "Escolha quais repositórios consultar.", + "repos": "Repositórios", + "taskSource": "Origem de tarefas", + "upstream": "Upstream" + }, + "providerViewProjection": { + "all": "Todos", + "allSites": "Todos os sites", + "allTeams": "Todas as equipes", + "allWorkspaces": "Todos os espaços de trabalho", + "chooseProject": "Escolher projeto", + "default": "Padrão", + "defaultSubtitle": "{{subtitle}} · Padrão", + "issues": "Issues", + "list": "Lista", + "noGrouping": "Sem agrupamento", + "openState": "Em aberto", + "priority": "Prioridade", + "projects": "Projetos", + "pullRequests": "PRs", + "teams_many": "{{count}} equipes", + "teams_one": "{{count}} equipe", + "teams_other": "{{count}} equipes", + "workspace": "Espaço de trabalho" + }, + "reviewerLinear": { + "issues": "Issues", + "unassigned": "Não atribuído" + }, + "screenChrome": { + "connectLinear": "Conectar Linear", + "newGitHubIssue": "Nova issue do GitHub", + "newLinearIssue": "Nova issue do Linear", + "refreshGitHub": "Atualizar trabalho do GitHub", + "refreshGitLab": "Atualizar itens de trabalho do GitLab", + "refreshJira": "Atualizar issues do Jira", + "refreshLinear": "Atualizar Linear", + "title": "Tarefas" + }, + "searchControl": { + "jiraPlaceholder": "JQL do Jira, ex.: project = ABC AND statusCategory != Done", + "projectPlaceholder": "Buscar na visualização do projeto…", + "providerPlaceholder": "Buscar tarefas do {{provider}}…" + }, + "smartSourceModes": { + "allStates": "Todos", + "branch": "Branch", + "closedState": "Fechado", + "mergedState": "Mergeado", + "name": "Nome", + "openState": "Aberto", + "smart": "Inteligente" + }, + "sparsePresetDraft": { + "directoryRequired": "Adicione ao menos um diretório.", + "repoRelativeDirectoriesRequired": "Use diretórios relativos ao repositório, não caminhos raiz, absolutos ou segmentos pai." + }, + "taskViewOptions": { + "allSubtitle": "Issues não resolvidas nos sites selecionados", + "assignedSubtitle": "Issues não resolvidas atribuídas a você", + "doneSubtitle": "Suas issues resolvidas recentemente", + "noGitHubTasks": "Nenhuma tarefa do GitHub", + "noGitLabTasks": "Nenhuma tarefa do GitLab", + "noJiraTasks": "Nenhuma tarefa do Jira", + "noLinearTasks": "Nenhuma tarefa do Linear", + "reportedSubtitle": "Issues não resolvidas que você relatou" + }, + "tasksCreateDrawers": { + "connect": "Conectar", + "connectLinearWorkspace": "Conectar espaço de trabalho do Linear", + "createIssue": "Criar Issue", + "createWorkspaceIn": "Criar Espaço de Trabalho em", + "description": "Descrição", + "descriptionPlaceholder": "Adicionar contexto", + "fileIn": "Criar em {{slug}}", + "issueSource": "Origem da issue", + "keySecurityHint": "Sua chave é criptografada pelo chaveiro do sistema operacional do host e armazenada localmente.", + "linearConnectSubtitle": "Cole uma chave de API pessoal para consultar as issues desse espaço de trabalho.", + "linearSettingsLink": "Configurações do Linear / Segurança / Nova chave de API", + "linearTeam": "Equipe do Linear", + "linearTeamSubtitle": "Crie uma issue na equipe selecionada do Linear.", + "newIssueTitle": "Nova Issue do {{providerLabel}}", + "origin": "Origin", + "personalApiKey": "Chave de API pessoal", + "repository": "Repositório", + "repositorySubtitle": "Crie uma issue no repositório selecionado.", + "team": "Equipe", + "title": "Título", + "titlePlaceholder": "Título da tarefa", + "upstream": "Upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "Terminal em Branco" + }, + "workspaceCreateDrawer": { + "addRepository": "Adicione um repositório Git antes de criar um espaço de trabalho do Linear.", + "advanced": "Avançado", + "agent": "Agente", + "connect": "Conectar", + "connectFirst": "Conecte o repositório primeiro", + "connectRepository": "Conectar Repositório", + "connecting": "Conectando…", + "createFrom": "Criar a partir de {{branch}}", + "defaultBranch": "Branch padrão", + "detectingAgents": "Detectando agentes…", + "optional": "[Opcional]", + "remoteRepository": "Repositório remoto", + "repository": "Repositório", + "repositoryNotFound": "Repositório não encontrado.", + "selectRepository": "Selecione um repositório", + "sshConnection": "Conexão SSH", + "startFrom": "Iniciar a partir de", + "title": "Criar Espaço de Trabalho", + "workspaceName": "Nome do Espaço de Trabalho" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "\"{{name}}\" já existe.", + "nameRequired": "O nome é obrigatório.", + "nameTooLong": "O nome deve ter no máximo 80 caracteres.", + "openShell": "Abrir uma shell" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Selecione uma branch ou referência existente.", + "baseBranchTitle": "Iniciar a partir de", + "branchName": "Nome da branch: {{name}}", + "defaultBranch": "Branch padrão", + "defaultBranchSubtitle": "Usar a branch base configurada neste repositório", + "editPreset": "Editar {{name}}", + "fullCheckout": "Checkout completo", + "fullCheckoutSubtitle": "Usar o repositório inteiro", + "newPreset": "Novo predefinido", + "noBranches": "Nenhuma branch corresponde à busca.", + "searchBranches": "Buscar branches", + "sparseCheckoutTitle": "Checkout esparso" + }, + "workspaceSshGate": { + "authenticationFailed": "Falha na autenticação", + "connected": "Conectado", + "connecting": "Conectando", + "connectionFailed": "Falha na conexão", + "deployingRelay": "Implantando relay", + "disconnected": "Desconectado", + "reconnectFailed": "Falha na reconexão", + "reconnecting": "Reconectando" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Sempre confiar e executar", + "creating": "Criando…", + "directoriesLabel": "Diretórios", + "directories_many": "{{count}} diretórios", + "directories_one": "{{count}} diretório", + "directories_other": "{{count}} diretórios", + "dontRun": "Não executar", + "editSparsePreset": "Editar predefinição de checkout esparso", + "nameLabel": "Nome", + "namePlaceholder": "Interface do renderizador", + "newSetupScript": "Novo script de configuração", + "newSparsePreset": "Nova predefinição de checkout esparso", + "runHooks": "Executar hooks", + "runSetupAndCreate": "Executar configuração e criar", + "runSetupTitle": "Executar a configuração de {{name}}?", + "setupChangedTitle": "O script de configuração de {{name}} mudou", + "setupScript": "Script de configuração", + "setupSubtitle": "Escolha se deseja executar a configuração de {{name}} antes de criar este espaço de trabalho.", + "setupTitle": "Executar script de configuração?", + "skipSetupAndCreate": "Pular configuração e criar", + "trustFailed": "Falha ao marcar o script de configuração como confiável.", + "trustSubtitle": "O orca.yaml deste repositório é executado no seu computador antes de iniciar o espaço de trabalho. Execute-o apenas se você confiar neste repositório." + }, + "worktreeCreateRetry": { + "createFailed": "Falha ao criar espaço de trabalho" } }, "terminal": { diff --git a/mobile/src/i18n/locales/ru.json b/mobile/src/i18n/locales/ru.json index 40a8905ac08..f85093b00c6 100644 --- a/mobile/src/i18n/locales/ru.json +++ b/mobile/src/i18n/locales/ru.json @@ -1530,12 +1530,12 @@ "cardDisplay": "Отображение карточек", "cardLayout": "Вид карточек", "clearFilters": "Сбросить фильтры", - "exceptDefaultBranch": "Кроме основной ветки", + "exceptDefaultBranch": "Кроме ветки по умолчанию", "filters": "Фильтры", "groupBy": "Группировать по", "hideAutomationCreated": "Скрыть созданные автоматизацией", "hideCliCreated": "Скрыть созданные через CLI", - "hideDefaultBranch": "Скрыть основную ветку", + "hideDefaultBranch": "Скрыть ветку по умолчанию", "hideDetachedHead": "Скрыть с отсоединённым HEAD", "hideOtherClientWorkspaces": "Скрыть рабочие пространства других клиентов", "hideSleeping": "Скрыть спящие рабочие пространства", @@ -1569,7 +1569,21 @@ "workspace": "Рабочее пространство" } }, + "newWorkspace": { + "hostPicker": { + "title": "Где создать рабочее пространство" + }, + "loadingDrawer": { + "downloadProgress": "Скачивание… {{progress}}", + "downloading": "Скачивание", + "loading": "Загрузка" + } + }, "notifications": { + "desktopChannel": { + "name": "Уведомления с компьютера", + "silentName": "Беззвучные уведомления Orca" + }, "notificationDeliverySection": { "footer": "Типы уведомлений зависят от настроек уведомлений на каждом сопряжённом компьютере. Если не пользоваться приложением 7 дней, уведомления приостанавливаются. Чтобы возобновить их, откройте приложение и подключитесь снова.", "onlyWhenAway": "Только когда вы не за компьютером", @@ -1806,7 +1820,7 @@ "noDetails": "Подробности недоступны." }, "prCheckDetailContent": { - "annotation": "Примечание", + "annotation": "Аннотация", "failedJobs": "Неудачные задания", "jobs": "Задания", "unknown": "неизвестно" @@ -2339,7 +2353,7 @@ }, "terminalLiveInputStatus": { "listening": "Прослушивание", - "liveInput": "Ввод в реальном времени", + "liveInput": "Прямой ввод", "preparingMic": "Подготовка микрофона", "processing": "Обработка", "releaseMicHint": "Отпустите кнопку микрофона, чтобы остановить запись", @@ -2374,7 +2388,7 @@ "browserCommandFailed": "Не удалось выполнить команду браузера", "browserCreateFailed": "Не удалось создать вкладку браузера", "browserUnavailable": "Страница браузера пока недоступна.", - "browserUpdateRequired": "Для трансляции браузера на телефон обновите Orca на сервере", + "browserUpdateRequired": "Для трансляции браузера на телефон обновите Orca на компьютере", "invalidUrl": "Введите корректный URL", "noteCreateFailed": "Не удалось создать заметку Markdown", "untitledNoteCreateFailed": "Не удалось создать заметку Markdown без названия" @@ -2468,7 +2482,7 @@ "actionFailed": "Не удалось выполнить действие с комментарием" }, "usePrTitleAction": { - "disconnected": "Нет подключения к серверу.", + "disconnected": "Нет подключения к компьютеру.", "updateFailed": "Не удалось обновить заголовок." }, "useQuickCommands": { @@ -2656,11 +2670,75 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "Нет базовой ветки для перебазирования", + "waitingForDesktop": "Ожидание подключения к компьютеру…" + }, "actions": { + "checkingReviewStatus": "Получение статуса PR/MR.", + "checkoutBeforePublish": "Переключитесь на ветку перед публикацией коммитов.", + "commitStagedChanges": "Создать коммит с изменениями в индексе.", "commits": "Коммиты", + "committing": "Создаётся коммит.", "createPr": "Создать PR", + "enterCommitMessage": "Введите сообщение, чтобы создать коммит.", + "forcePushWithLease": "Обновить удалённую ветку принудительной отправкой с проверкой её состояния.", + "forcePushing": "Выполняется принудительная отправка.", + "linkedReviewUnavailable": "Ветка связанного PR/MR недоступна.", + "publishToOrigin": "Опубликовать эту ветку в origin.", + "pullCommits_few": "Получить и слить {{count}} коммита.", + "pullCommits_many": "Получить и слить {{count}} коммитов.", + "pullCommits_one": "Получить и слить {{count}} коммит.", + "pullCommits_other": "Получить и слить {{count}} коммита.", "pushAndCreatePr": "Отправить и создать PR", - "switchBranch": "Переключиться на ветку" + "pushCommits_few": "Отправить {{count}} коммита.", + "pushCommits_many": "Отправить {{count}} коммитов.", + "pushCommits_one": "Отправить {{count}} коммит.", + "pushCommits_other": "Отправить {{count}} коммита.", + "pushLinkedReview": "Отправить изменения в ветку связанного PR/MR.", + "remoteOperationInProgress": "Выполняется удалённая операция.", + "resolveConflicts": "Разрешите конфликты перед созданием коммита.", + "reviewAlreadyMerged": "Нет изменений для коммита. Изменения уже слиты.", + "stageAllChanges": "Добавить все изменения в индекс.", + "stageFileToCommit": "Добавьте хотя бы один файл в индекс, чтобы создать коммит.", + "switchBranch": "Переключиться на ветку", + "syncCounts": "Получить и слить: {{behind}}, отправить: {{ahead}}.", + "upToDate": "Нет изменений для коммита. Ветка актуальна.", + "waitForRemoteOperation": "Повторите попытку после завершения удалённой операции." + }, + "branchBaseRef": { + "resolveFailed": "Не удалось определить базовую ветку" + }, + "branchCard": { + "branchCount": "В ветке: {{count}}", + "changedCount": "Изменено: {{count}}", + "cherryPickState": "cherry-pick", + "mergeState": "слияние", + "rebaseState": "перебазирование", + "stagedCount": "В индексе: {{count}}" + }, + "branchCompare": { + "commits_few": "{{count}} коммита", + "commits_many": "{{count}} коммитов", + "commits_one": "{{count}} коммит", + "commits_other": "{{count}} коммита", + "files_few": "{{count}} файла", + "files_many": "{{count}} файлов", + "files_one": "{{count}} файл", + "files_other": "{{count}} файла", + "sectionTitle": "Закоммичено в ветке", + "summary": "{{files}} — по сравнению с {{baseRef}}", + "summaryWithCommits": "{{files}} — {{commits}} — по сравнению с {{baseRef}}" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Не удалось определить базовую ветку для сравнения.", + "loadFailed": "Не удалось загрузить закоммиченные изменения" + }, + "branchDiffPreviewDrawer": { + "closePreview": "Закрыть предпросмотр закоммиченных изменений", + "committedOnBranch": "Закоммичено в ветке", + "loadFailed": "Не удалось загрузить различия", + "truncated": "В мобильном предпросмотре показана часть различий." }, "commitDropdown": { "checkOutBranchToPush": "Переключитесь на ветку перед отправкой коммитов", @@ -2685,8 +2763,49 @@ "stageFile": "Добавьте в индекс хотя бы один файл для коммита", "useCommitAndForcePush": "Используйте «Закоммитить и принудительно отправить»: в удалённой ветке только старые версии локальных коммитов" }, + "commitFailurePanel": { + "fix": "Исправить", + "fixWithAi": "Исправить ошибку коммита с ИИ", + "hideDetails": "Скрыть подробности", + "hideFailureDetails": "Скрыть подробности ошибки коммита", + "showDetails": "Показать подробности", + "showFailureDetails": "Показать подробности ошибки коммита", + "summary": "Не удалось создать коммит.", + "title": "Не удалось создать коммит" + }, + "commitMessageAi": { + "generateFailed": "Не удалось сгенерировать сообщение коммита" + }, + "commitRunners": { + "actionFailed": "Не удалось выполнить операцию управления версиями", + "commitFailed": "Не удалось создать коммит" + }, + "conflictAbort": { + "abortMerge": "Прервать слияние", + "abortOperation": "Прервать {{operation}}", + "abortRebase": "Прервать перебазирование", + "aborting": "Прерывание…" + }, + "content": { + "cancelGeneration": "Отменить создание сообщения коммита", + "commitMessageDisabled": "Ввод сообщения коммита недоступен. В индексе нет файлов.", + "commitMessagePlaceholder": "Сообщение коммита", + "emptyMessage": "В рабочем дереве нет изменений.", + "emptyTitle": "Нет локальных изменений", + "generateMessage": "Создать сообщение коммита с помощью ИИ", + "noStagedFiles": "В индексе нет файлов", + "openActions": "Открыть меню управления версиями", + "reconnecting": "Переподключение к компьютеру…", + "regenerateHint": "Очистите сообщение для повторного создания.", + "stageAll": "Добавить всё в индекс", + "unstageAll": "Убрать всё из индекса" + }, "createPrAction": { - "createReview": "Создать {{titleLabel}}" + "checkingStatus": "Получение статуса PR/MR…", + "createPullRequest": "Создать пул-реквест", + "createReview": "Создать {{titleLabel}}", + "providerUnavailable": "Создание PR/MR недоступно для этого провайдера", + "statusUnavailable": "Статус PR/MR недоступен" }, "dropdownCounts": { "fastForwardCount_few": "Продвинуть ветку на {{count}} коммита", @@ -2722,6 +2841,74 @@ "titleUnpublishedForcePushCount_one": "Принудительно отправьте {{count}} коммит этой ветки с проверкой состояния удалённой ветки и при необходимости настройте отслеживаемую удалённую ветку.", "titleUnpublishedForcePushCount_other": "Принудительно отправьте {{count}} коммита этой ветки с проверкой состояния удалённой ветки и при необходимости настройте отслеживаемую удалённую ветку." }, + "fileList": { + "committedSection": "Закоммичено в ветке" + }, + "fileRows": { + "addedByThem": "Добавлен ими", + "addedByUs": "Добавлен нами", + "bothAdded": "Добавлен с обеих сторон", + "bothDeleted": "Удалён с обеих сторон", + "bothModified": "Изменён с обеих сторон", + "committedSection": "Закоммичено в ветке", + "committedUnavailable": "Закоммиченные изменения недоступны.", + "deletedByThem": "Удалён ими", + "deletedByUs": "Удалён нами", + "discardFile": "Отменить изменения в «{{path}}»", + "loadingCommitted": "Загрузка закоммиченных изменений…", + "openChangedFile": "Открыть изменённый файл {{path}}", + "openCommittedChange": "Открыть закоммиченные изменения в «{{path}}»", + "renamedFrom": "из {{path}}", + "stageFile": "Добавить {{path}} в индекс", + "unresolvedConflict": "Неразрешённый конфликт", + "unstageFile": "Убрать {{path}} из индекса" + }, + "gitHistory": { + "days_few": "{{count}} д", + "days_many": "{{count}} д", + "days_one": "{{count}} д", + "days_other": "{{count}} д", + "hours_few": "{{count}} ч", + "hours_many": "{{count}} ч", + "hours_one": "{{count}} ч", + "hours_other": "{{count}} ч", + "justNow": "только что", + "loadFailed": "Не удалось загрузить историю коммитов", + "minutes_few": "{{count}} мин", + "minutes_many": "{{count}} мин", + "minutes_one": "{{count}} мин", + "minutes_other": "{{count}} мин", + "months_few": "{{count}} мес.", + "months_many": "{{count}} мес.", + "months_one": "{{count}} мес.", + "months_other": "{{count}} мес.", + "noCommitMessage": "(без сообщения коммита)", + "years_few": "{{count}} года", + "years_many": "{{count}} лет", + "years_one": "{{count}} год", + "years_other": "{{count}} года" + }, + "gitHistoryList": { + "loadFailed": "Не удалось загрузить историю", + "loadFilesFailed": "Не удалось загрузить файлы коммита", + "noCommits": "Нет коммитов.", + "noFileChanges": "Нет изменений в файлах", + "retryFiles": "Повторить загрузку файлов коммита", + "waitingForDesktop": "Ожидание ответа от компьютера…" + }, + "gitStatus": { + "changes": "Изменения", + "conflicts": "Конфликты", + "stagedChanges": "Изменения в индексе" + }, + "header": { + "backToSession": "Вернуться к сессии", + "close": "Закрыть управление версиями", + "openNumberedPrWeb": "Открыть пул-реквест #{{number}} в браузере", + "openPrWeb": "Открыть пул-реквест в браузере", + "refresh": "Обновить данные управления версиями", + "title": "Управление версиями" + }, "hostedReview": { "mrCopy": { "reviewLabel": "запрос на слияние", @@ -2734,9 +2921,83 @@ "titleLabel": "Пул-реквест" } }, + "hostedReviewCopy": { + "committingChanges": "Создание коммита…", + "creatingReview": "Создание запроса на проверку…", + "forcePushing": "Принудительная отправка с проверкой удалённой ветки…", + "generatingCommitMessage": "Создание сообщения коммита…", + "publishingBranch": "Публикация ветки…", + "pushingCommits": "Отправка коммитов…", + "stagingChanges": "Добавление изменений в индекс…", + "updatingBranch": "Обновление ветки…" + }, "hostedReviewCreate": { "pushSucceeded": "Отправка прошла успешно, но не удалось создать {{shortLabel}}: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "Ветка изменилась во время подготовки пул-реквеста.", + "generateMessageFailed": "Не удалось сгенерировать сообщение коммита. Введите его в разделе «Управление версиями» и повторите попытку.", + "resolveConflicts": "Разрешите конфликты перед созданием пул-реквеста.", + "resolveOrStageChanges": "Разрешите конфликты или добавьте изменения в индекс перед созданием пул-реквеста.", + "reviewCommitMessage": "Проверьте сообщение коммита и повторите «Создать PR»." + }, + "hostedReviewGitPreparation": { + "commitFailed": "Не удалось создать коммит", + "refreshFailed": "Не удалось обновить данные управления версиями", + "stageFailed": "Не удалось добавить изменения в индекс", + "updateBranchFailed": "Не удалось обновить удалённую ветку. Повторите «Создать PR»." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "Не удалось выполнить принудительную отправку с проверкой удалённой ветки", + "publishFailed": "Не удалось опубликовать ветку", + "pushFailed": "Не удалось отправить коммиты" + }, + "hostedReviewService": { + "createFailed": "Не удалось создать пул-реквест", + "pushBeforeCreateFailed": "Не удалось отправить изменения. Устраните причину ошибки отправки, затем повторите попытку." + }, + "hubTab": { + "changes": "Изменения", + "commits": "Коммиты", + "pullRequest": "Пул-реквест" + }, + "loaders": { + "connectingToDesktop": "Подключение к компьютеру…", + "loadFailed": "Не удалось загрузить данные управления версиями", + "updateDesktop": "Обновите Orca на компьютере, чтобы использовать управление версиями на мобильном устройстве.", + "waitingForDesktop": "Ожидание подключения к компьютеру…" + }, + "modals": { + "actionsTitle": "Управление версиями", + "currentBranch": "текущая", + "discardButton": "Отменить изменения", + "discardConfirmMessage": "Отменить изменения в «{{path}}»? Это действие необратимо.", + "discardTitle": "Отменить изменение", + "openPrMessage": "Открыть в браузере?", + "openPrWithWarning": "Открыть в браузере?\n\n{{warning}}", + "prCreatedTitle": "Пул-реквест создан", + "switchBranchTitle": "Переключиться на ветку" + }, + "openers": { + "openDiffFailed": "Не удалось открыть сравнение", + "tabNotReady": "Файл открыт, но его вкладка ещё не готова. Повторите попытку.", + "waitingForDesktop": "Ожидание подключения к компьютеру…" + }, + "panel": { + "loadFailedTitle": "Не удалось загрузить", + "unavailableTitle": "Управление версиями недоступно" + }, + "prChip": { + "createPr": "Создать пул-реквест", + "loading": "Загрузка пул-реквеста…", + "loadingLabel": "Загрузка пул-реквеста", + "openLabel": "Пул-реквест #{{number}}, {{state}}, {{checks}}. Открыть пул-реквест.", + "openWithComments_few": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённых комментария. Открыть пул-реквест.", + "openWithComments_many": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённых комментариев. Открыть пул-реквест.", + "openWithComments_one": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённый комментарий. Открыть пул-реквест.", + "openWithComments_other": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённого комментария. Открыть пул-реквест.", + "unavailableLabel": "Пул-реквест недоступен: {{message}}" + }, "prCreate": { "authRequired": "Прежде чем создать {{reviewLabel}}, пройдите аутентификацию.", "baseNotOnRemote": "Прежде чем создать {{reviewLabel}}, отправьте базовую ветку.", @@ -2755,8 +3016,19 @@ "unsupportedMergeRequests": "Создание запросов на слияние для этого репозитория не поддерживается.", "unsupportedPullRequests": "Создание пул-реквестов для этого репозитория не поддерживается." }, + "prLink": { + "updatePullRequestFailed": "Не удалось обновить связь с пул-реквестом", + "updateReviewFailed": "Не удалось обновить связь с запросом на проверку" + }, "primaryAction": { - "forcePushFromDesktop": "Принудительно отправьте ветку этого пул-реквеста из настольного приложения" + "commit": "Закоммитить", + "forcePush": "Отправить принудительно", + "forcePushFromDesktop": "Принудительно отправьте ветку этого пул-реквеста из настольного приложения", + "publishBranch": "Опубликовать ветку", + "pull": "Получить и слить", + "push": "Отправить", + "stageAll": "Добавить всё в индекс", + "sync": "Синхронизировать" }, "remoteDropdown": { "branchAlreadyPublished": "Ветка уже опубликована", @@ -2806,6 +3078,609 @@ "tryFastForwardPull": "Попробовать получить изменения и слить перемоткой вперёд; git может отклонить операцию из-за локальных коммитов", "tryRegularPush": "Попробовать обычную отправку; git может потребовать принудительную отправку", "useForcePushToSync": "Используйте принудительную отправку: в удалённом репозитории есть только старые версии локальных коммитов" + }, + "runners": { + "actionFailed": "Не удалось выполнить операцию управления версиями" + }, + "screenState": { + "noBranch": "Нет ветки" + }, + "state": { + "noUpstream": "Нет отслеживаемой ветки", + "syncStatus": "Опережает на {{ahead}}, отстаёт на {{behind}}" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Не удалось запустить агента", + "waitingForDesktop": "Ожидание подключения к компьютеру…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Не удалось сгенерировать сообщение коммита" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Перед созданием пул-реквеста переключитесь на ветку." + }, + "useMobileGitRequests": { + "actionFailed": "Не удалось выполнить операцию управления версиями", + "branchUnavailable": "Состояние ветки недоступно", + "commitFailed": "Не удалось создать коммит", + "waitingForDesktop": "Ожидание подключения к компьютеру…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "Не удалось определить базовую ветку.", + "forkPushWarning": "В этом PR отключена настройка «Разрешить правки сопровождающим»; GitHub может отклонить отправку в форк." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Добавить комментарий", + "comments_few": "{{count}} комментария", + "comments_many": "{{count}} комментариев", + "comments_one": "{{count}} комментарий", + "comments_other": "{{count}} комментария", + "reopenThread": "Возобновить обсуждение", + "reply": "Ответить", + "resolveThread": "Закрыть обсуждение", + "resolvedCommentBy": "Закрытый комментарий от {{author}}", + "resolvedThreadBy": "Закрытое обсуждение от {{author}}", + "sendComment": "Отправить комментарий", + "show": "Показать" + }, + "filterPickers": { + "allTeams": "Все команды", + "changeStatus": "Изменить статус", + "fieldHidden": "Скрыто на карточках", + "fieldShown": "Показано на карточках", + "fieldsSubtitle": "Выберите, какие поля проекта показывать на карточках элементов.", + "fieldsTitle": "Поля проекта", + "gitlabFilter": "Фильтр GitLab", + "gitlabView": "Представление GitLab", + "jiraFilter": "Фильтр Jira", + "jiraSite": "Сайт Jira", + "linearFilter": "Фильтр Linear", + "linearIssue": "Задача Linear", + "linearWorkspace": "Рабочее пространство Linear", + "loadingStates": "Загрузка статусов…", + "noFields": "В этом представлении нет дополнительных полей.", + "noStates": "Нет доступных статусов", + "switchWorkspaceFailed": "Не удалось сменить рабочее пространство", + "teamsSubtitle": "Выберите команды для отображения в разделе «Задачи».", + "teamsTitle": "Команды Linear", + "teams_few": "{{count}} команды", + "teams_many": "{{count}} команд", + "teams_one": "{{count}} команда", + "teams_other": "{{count}} команды" + }, + "githubProjectList": { + "browseProjects": "Просмотреть проекты", + "chooseProject": "Выберите проект GitHub", + "emptyField": "Пусто", + "issueSubtitle": "Задача · {{repository}}{{number}}", + "itemSubtitle": "Элемент проекта · {{repository}}{{number}}", + "items": "Элементы", + "moreFields_few": "+{{count}} поля", + "moreFields_many": "+{{count}} полей", + "moreFields_one": "+{{count}} поле", + "moreFields_other": "+{{count}} поля", + "noItems": "В проекте нет элементов", + "pullRequestSubtitle": "Пул-реквест · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Добавить", + "addByUrlHint": "Добавьте недостающие проекты по URL.", + "addPlaceholder": "Добавить по URL или owner/number", + "adding": "Добавление…", + "browseAll": "Посмотреть все", + "browseLoading": "Посмотреть все (загрузка…)", + "chooseView": "Выберите представление проекта", + "loadFailed": "Не удалось загрузить проекты", + "noMatches": "Подходящих проектов не найдено.", + "noMoreProjects": "Больше проектов нет.", + "noProjects": "Нет загруженных проектов", + "organizationsError": "организации: {{message}}", + "organizationsLoadFailed": "Не удалось загрузить некоторые организации ({{count}}).", + "ownerLoadFailed": "Не удалось загрузить проекты {{owner}}.", + "pin": "Закрепить", + "pinned": "Закреплено", + "recent": "Недавние", + "retryHint": "Нажмите, чтобы повторить.", + "searchProjects": "Поиск проектов", + "sort": "Сортировка проекта", + "subtitle": "Выберите представление проекта для страницы «Задачи».", + "title": "Проекты GitHub", + "unsupportedLayout": "Orca пока не поддерживает этот макет проекта GitHub.", + "view": "Представление проекта" + }, + "githubViewControls": { + "fields": "Поля: {{fields}}", + "openView": "Открыть представление в GitHub", + "sort": "Сортировка: {{sort}}", + "source": "Источник: {{source}}" + }, + "itemActions": { + "changeStatus": "Изменить статус", + "copyGitHubLink": "Скопировать ссылку на GitHub", + "copyLinearLink": "Скопировать ссылку на Linear", + "createWorkspace": "Создать рабочее пространство", + "creating": "Создание…", + "mergeConflicts": "GitHub сообщает о конфликтах слияния.", + "mergeMergeRequest": "Слить запрос на слияние", + "mergePullRequest": "Слить пул-реквест" + }, + "itemDetailContent": { + "addSubIssue": "Добавить подзадачу", + "assignee": "Исполнитель", + "assignees": "Исполнители", + "checks": "Проверки", + "description": "Описание", + "discussion": "Обсуждение", + "noChecks": "Проверки не найдены.", + "noComments": "Комментариев нет.", + "noPipelineRuns": "Для этого MR нет запусков конвейера.", + "noSubIssues": "Нет подзадач.", + "none": "Нет", + "pipeline": "Конвейер", + "pipelineJobs_few": "{{count}} задания", + "pipelineJobs_many": "{{count}} заданий", + "pipelineJobs_one": "{{count}} задание", + "pipelineJobs_other": "{{count}} задания", + "project": "Проект", + "rerunAll": "Повторить все", + "rerunFailed": "Повторить неуспешные", + "status": "Статус", + "subIssueTitle": "Название подзадачи", + "subIssues": "Подзадачи", + "type": "Тип" + }, + "itemDetailDrawer": { + "refreshDetails": "Обновить данные" + }, + "itemFieldEditors": { + "addLabels": "Метки для добавления (через запятую)", + "addUsernames": "Логины для добавления (через запятую)", + "assignees": "Исполнители", + "labels": "Метки", + "loadingAssignees": "Загрузка исполнителей…", + "loadingLabels": "Загрузка меток…", + "noAssignableUsers": "В этом репозитории не найдены пользователи, которых можно назначить исполнителями.", + "noLabels": "В этом репозитории нет меток.", + "none": "Нет", + "removeLabels": "Метки для удаления (через запятую)", + "removeUsernames": "Логины для удаления (через запятую)", + "saveTitle": "Сохранить заголовок", + "title": "Заголовок", + "updateAssignees": "Обновить исполнителей", + "updateLabels": "Обновить метки" + }, + "itemReviewSections": { + "binaryFile": "Двоичный файл.", + "changedFilesTitle": "Изменённые файлы", + "descriptionPlaceholder": "Описание", + "fileContentsUnavailable": "Содержимое файла недоступно.", + "hideFile": "Скрыть", + "loadingReviewers": "Загрузка рецензентов…", + "markUnviewed": "Отметить непросмотренным", + "markViewed": "Отметить просмотренным", + "noDescription": "Описания нет.", + "noReviewerSuggestions": "Кандидаты в рецензенты не найдены.", + "noReviewersRequested": "Проверка ещё ни у кого не запрошена.", + "requestReview": "Запросить проверку", + "reviewersPlaceholder": "Пригласить рецензентов", + "reviewersTitle": "Рецензенты", + "saveDescription": "Сохранить описание", + "viewFile": "Просмотреть" + }, + "legacySurface": { + "loadIssuesFailed": "Не удалось загрузить задачи из {{source}}.", + "mergeAction": "Слить", + "mergeMethodTitle": "Способ слияния", + "mergePullRequestTitle": "Слить пул-реквест", + "mergeRequestMergeMessage": "Выберите способ слияния этого запроса на слияние.", + "mergeRequestTitle": "Запрос на слияние", + "pullRequestMergeMessage": "Выберите способ слияния этого пул-реквеста.", + "retryLoadingIssues": "Повторить загрузку задач из {{source}}", + "retrying": "Повторная попытка…", + "sourceFallback": "Предпочтительный источник задач upstream недоступен для {{repo}}. Используется origin.", + "subIssueDataUnavailable": "Ваш токен не даёт доступа к данным подзадач.", + "updateItemTitle": "Обновить элемент" + }, + "linearList": { + "changeStatusFrom": "Изменить статус «{{status}}»" + }, + "linearViewControls": { + "displayButton": "Отображение", + "groupLabel": "Группировка: {{group}}", + "orderLabel": "Порядок: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Отображаемые поля", + "linearGroupTitle": "Группировка задач Linear", + "linearOrderTitle": "Сортировка задач Linear", + "linearViewTitle": "Вид задач Linear", + "sortTasksTitle": "Сортировка задач" + }, + "listSurface": { + "connectLinearButton": "Подключить Linear", + "connectLinearMessage": "Просматривайте назначенные вам задачи Linear и начинайте работу над ними прямо в разделе «Задачи».", + "connectLinearTitle": "Подключите учётную запись Linear", + "jiraStatusFailed": "Не удалось получить статус Jira", + "updateDesktopMessage": "Для раздела «Задачи» в мобильном приложении нужна более новая версия Orca на компьютере.", + "updateDesktopTitle": "Обновите Orca на компьютере" + }, + "options": { + "all": "Все", + "assignedToMe": "Назначенные мне", + "assignee": "Исполнитель", + "board": "Доска", + "boardDescription": "Колонки по группам", + "closedState": "Закрытые", + "completedState": "Выполненные", + "createdState": "Созданные", + "githubAssignedIssuesDescription": "Открытые задачи, назначенные вам", + "githubDescription": "Задачи и пул-реквесты", + "githubIssuesDescription": "Задачи GitHub", + "githubOpenIssuesDescription": "Открытые задачи GitHub", + "githubProjectsDescription": "Представления GitHub Projects", + "githubPullRequestsDescription": "Пул-реквесты GitHub", + "gitlabAllDescription": "Любой статус GitLab", + "gitlabClosedDescription": "Закрытые задачи и запросы на слияние", + "gitlabDescription": "Задачи и запросы на слияние", + "gitlabMergedDescription": "Слитые запросы на слияние", + "gitlabOpenDescription": "Открытые задачи и запросы на слияние", + "identifier": "Идентификатор", + "issues": "Задачи", + "jiraDescription": "Назначенные вам и созданные вами задачи", + "labels": "Метки", + "linearAllDescription": "Открытые задачи в подключённых рабочих пространствах", + "linearAssignedDescription": "Задачи, назначенные вам", + "linearCompletedDescription": "Недавно выполненные задачи", + "linearCreatedDescription": "Задачи, созданные вами", + "linearDescription": "Назначенные вам задачи и задачи команды", + "list": "Список", + "listDescription": "Компактный список задач", + "mergedState": "Слитые", + "mine": "Мои", + "myIssues": "Мои задачи", + "myPullRequestsDescription": "Созданные вами пул-реквесты", + "myTodos": "Мои дела", + "myTodosDescription": "Невыполненные дела GitLab", + "needsReview": "Нужна проверка", + "noGrouping": "Без группировки", + "openPullRequestsDescription": "Открытые пул-реквесты", + "openState": "Открытые", + "priority": "Приоритет", + "projectMergeRequests": "MR проекта", + "projectMergeRequestsDescription": "Запросы на слияние и задачи по репозиториям", + "projects": "Проекты", + "pullRequests": "PR", + "repository": "Репозиторий", + "repositorySortDescription": "По репозиториям, внутри — сначала недавно обновлённые", + "reviewRequestsDescription": "Запросы на проверку, назначенные вам", + "status": "Статус", + "team": "Команда", + "updated": "Обновлено", + "updatedSortDescription": "Сначала недавно обновлённые" + }, + "pickerProjection": { + "allRepos": "Все репозитории", + "allSites": "Все сайты", + "currentlyAscending": "По возрастанию · нажмите для сортировки по убыванию", + "currentlyDescending": "По убыванию · нажмите для сортировки по возрастанию", + "fieldAscending": "{{field}} по возрастанию", + "fieldDescending": "{{field}} по убыванию", + "fields": "Поля", + "repos_few": "{{count}} репозитория", + "repos_many": "{{count}} репозиториев", + "repos_one": "{{count}} репозиторий", + "repos_other": "{{count}} репозитория", + "selectTarget": "Выбрать место создания", + "selectedFields": "Поля: {{selected}}/{{total}}", + "sortAscending": "Сортировать по возрастанию", + "sources_few": "{{count}} источника", + "sources_many": "{{count}} источников", + "sources_one": "{{count}} источник", + "sources_other": "{{count}} источника", + "unsupportedLayout": "Макет не поддерживается на мобильных устройствах", + "updatedSort": "Обновлено", + "usesFieldAscending": "Сортировка: {{field}} по возрастанию", + "usesFieldDescending": "Сортировка: {{field}} по убыванию", + "usesGitHubRankOrder": "Порядок элементов из GitHub", + "viewNumber": "Представление № {{number}}", + "viewOrder": "Порядок представления" + }, + "prFileDiff": { + "commentOnLine": "Комментировать строку {{line}}", + "commentPlaceholder": "Добавьте комментарий к строке", + "noTextChanges": "Текстовых изменений не найдено.", + "showingDiffLines": "Показаны строки сравнения с 1 по {{limit}} из {{total}}." + }, + "projectComments": { + "comments_few": "{{count}} комментария", + "comments_many": "{{count}} комментариев", + "comments_one": "{{count}} комментарий", + "comments_other": "{{count}} комментария", + "discussion": "Обсуждение", + "editComment": "Редактировать комментарий", + "noComments": "Комментариев нет.", + "reopenThread": "Открыть обсуждение заново", + "reply": "Ответить", + "resolveThread": "Закрыть обсуждение", + "resolvedCommentBy": "Закрытый комментарий от {{author}}", + "resolvedThreadBy": "Закрытое обсуждение от {{author}}", + "show": "Показать" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "Репозиторий {{repository}} не добавлен в Orca. Добавьте его в настольном приложении, затем обновите раздел «Задачи» в мобильном приложении.", + "clearType": "Сбросить тип", + "closeItem": "Закрыть элемент", + "copyGitHubLink": "Скопировать ссылку на GitHub", + "copyRepository": "Скопировать имя репозитория", + "createWorkspace": "Создать рабочее пространство", + "draftIssue": "Черновик задачи", + "issue": "Задача", + "issueType": "Тип задачи", + "loadingIssueTypes": "Загрузка типов задач…", + "mergePullRequest": "Слить пул-реквест", + "mergeRepositoryRequirement": "Для слияния добавьте этот репозиторий в Orca.", + "noIssueTypes": "Для этого репозитория не настроены типы задач.", + "noType": "Без типа", + "openInGitHub": "Открыть на GitHub", + "projectItem": "Элемент проекта", + "projectSubtitle": "Проект GitHub · {{repository}}{{itemNumber}}", + "pullRequest": "Пул-реквест", + "reopenItem": "Открыть элемент заново", + "repositoryNotInOrca": "Репозиторий не добавлен в Orca", + "status": "Статус", + "type": "Тип", + "workspaceCreationRequirement": "Рабочие пространства можно создавать только на основе задач и пул-реквестов GitHub." + }, + "projectFieldEditors": { + "clearField": "Очистить поле", + "completedIteration": "Завершена · {{startDate}} · {{duration}} дн.", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "Введите дату в формате YYYY-MM-DD.", + "invalidNumber": "Введите корректное число.", + "noIterations": "Нет доступных итераций.", + "numberPlaceholder": "Число", + "projectFields": "Поля проекта", + "saveField": "Сохранить поле", + "textPlaceholder": "Текст", + "upcomingIteration": "Текущая или предстоящая · {{startDate}} · {{duration}} дн." + }, + "projectMetadataEditors": { + "assignees": "Исполнители", + "description": "Описание", + "labels": "Метки", + "loadingAssignees": "Загрузка исполнителей…", + "loadingLabels": "Загрузка меток…", + "noAssignableUsers": "Для этого репозитория не найдены пользователи, которых можно назначить исполнителями.", + "noDescription": "Описания нет.", + "noLabels": "В этом репозитории нет меток.", + "none": "Нет", + "saveDescription": "Сохранить описание", + "saveTitle": "Сохранить заголовок", + "title": "Заголовок" + }, + "projectReviewPanels": { + "binaryFile": "Двоичный файл.", + "changedFiles": "Изменённые файлы", + "checks": "Проверки", + "fileUnavailable": "Содержимое файла недоступно.", + "hideFile": "Скрыть", + "loadingReviewers": "Загрузка рецензентов…", + "markUnviewed": "Отметить непросмотренным", + "markViewed": "Отметить просмотренным", + "noChecks": "Проверки не найдены.", + "noReviewers": "Проверка ещё ни у кого не запрошена.", + "noSuggestions": "Подходящих рецензентов нет.", + "requestReview": "Запросить проверку", + "requestReviewers": "Укажите рецензентов", + "rerunAll": "Перезапустить все", + "rerunFailed": "Перезапустить неудачные", + "reviewers": "Рецензенты", + "viewFile": "Просмотреть" + }, + "providerControls": { + "myTodos": "Мои дела", + "projectMergeRequests": "MR проекта", + "sort": "Сортировка: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "в {{base}}", + "nextPage": "Следующая страница", + "page": "Страница {{page}}", + "pageOfTotal": "Страница {{page}} из {{total}}", + "previousPage": "Предыдущая страница", + "selectPage": "Выбрать страницу, страница {{page}}", + "selectPageOfTotal": "Выбрать страницу, страница {{page}} из {{total}}" + }, + "providerPickers": { + "allRepositories": "Все репозитории", + "githubView": "Режим GitHub", + "issueSources": "Источники задач GitHub", + "issueSourcesDescription": "Выберите для каждого репозитория, где искать и создавать задачи: upstream или origin.", + "issues": "Задачи", + "noIssueSources": "Другие источники задач недоступны.", + "origin": "Исходный репозиторий", + "pageHint": "Перейдите на загруженную или доступную страницу результатов.", + "pageLoaded": "Загружена", + "pageNotLoaded": "Загрузит более ранние результаты", + "pageNumber": "Страница {{page}}", + "pages": "Страницы GitHub", + "pullRequests": "Пул-реквесты", + "queryingSource": "Запрос к {{source}}", + "repoDescription": "Выберите репозитории для поиска.", + "repos": "Репозитории", + "taskSource": "Источник задач", + "upstream": "Вышестоящий репозиторий" + }, + "providerViewProjection": { + "all": "Все", + "allSites": "Все сайты", + "allTeams": "Все команды", + "allWorkspaces": "Все рабочие пространства", + "chooseProject": "Выбрать проект", + "default": "По умолчанию", + "defaultSubtitle": "{{subtitle}} · По умолчанию", + "issues": "Задачи", + "list": "Список", + "noGrouping": "Без группировки", + "openState": "Открытые", + "priority": "Приоритет", + "projects": "Проекты", + "pullRequests": "PR", + "teams_few": "{{count}} команды", + "teams_many": "{{count}} команд", + "teams_one": "{{count}} команда", + "teams_other": "{{count}} команды", + "workspace": "Рабочее пространство" + }, + "reviewerLinear": { + "issues": "Задачи", + "unassigned": "Не назначено" + }, + "screenChrome": { + "connectLinear": "Подключить Linear", + "newGitHubIssue": "Новая задача GitHub", + "newLinearIssue": "Новая задача Linear", + "refreshGitHub": "Обновить задачи GitHub", + "refreshGitLab": "Обновить задачи GitLab", + "refreshJira": "Обновить задачи Jira", + "refreshLinear": "Обновить Linear", + "title": "Задачи" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL, например project = ABC AND statusCategory != Done", + "projectPlaceholder": "Поиск в проекте…", + "providerPlaceholder": "Поиск задач {{provider}}…" + }, + "smartSourceModes": { + "allStates": "Все", + "branch": "Ветка", + "closedState": "Закрытые", + "mergedState": "Слитые", + "name": "Название", + "openState": "Открытые", + "smart": "Умный ввод" + }, + "sparsePresetDraft": { + "directoryRequired": "Добавьте хотя бы один каталог.", + "repoRelativeDirectoriesRequired": "Укажите каталоги относительно репозитория. Корень, абсолютные пути и переходы к родительскому каталогу недопустимы." + }, + "taskViewOptions": { + "allSubtitle": "Нерешённые задачи на выбранных сайтах", + "assignedSubtitle": "Нерешённые задачи, назначенные вам", + "doneSubtitle": "Ваши недавно решённые задачи", + "noGitHubTasks": "Нет задач в GitHub", + "noGitLabTasks": "Нет задач в GitLab", + "noJiraTasks": "Нет задач в Jira", + "noLinearTasks": "Нет задач в Linear", + "reportedSubtitle": "Нерешённые задачи, созданные вами" + }, + "tasksCreateDrawers": { + "connect": "Подключить", + "connectLinearWorkspace": "Подключить рабочее пространство Linear", + "createIssue": "Создать задачу", + "createWorkspaceIn": "Где создать рабочее пространство", + "description": "Описание", + "descriptionPlaceholder": "Добавьте подробности", + "fileIn": "Создать в {{slug}}", + "issueSource": "Источник задач", + "keySecurityHint": "Ваш ключ шифруется с помощью хранилища ключей ОС сервера и хранится локально.", + "linearConnectSubtitle": "Вставьте личный API-ключ, чтобы просматривать задачи из этого рабочего пространства.", + "linearSettingsLink": "Настройки Linear / Безопасность / Новый API-ключ", + "linearTeam": "Команда Linear", + "linearTeamSubtitle": "Создайте задачу в выбранной команде Linear.", + "newIssueTitle": "Новая задача в {{providerLabel}}", + "origin": "Исходный репозиторий", + "personalApiKey": "Личный API-ключ", + "repository": "Репозиторий", + "repositorySubtitle": "Создайте задачу в выбранном репозитории.", + "team": "Команда", + "title": "Заголовок", + "titlePlaceholder": "Заголовок задачи", + "upstream": "Вышестоящий репозиторий" + }, + "workspaceAgentSelection": { + "blankTerminal": "Пустой терминал" + }, + "workspaceCreateDrawer": { + "addRepository": "Добавьте репозиторий Git, прежде чем создавать рабочее пространство для задачи Linear.", + "advanced": "Дополнительно", + "agent": "Агент", + "connect": "Подключиться", + "connectFirst": "Сначала подключите репозиторий", + "connectRepository": "Подключить репозиторий", + "connecting": "Подключение…", + "createFrom": "Создать на основе {{branch}}", + "defaultBranch": "Ветка по умолчанию", + "detectingAgents": "Поиск агентов…", + "optional": "[Необязательно]", + "remoteRepository": "Удалённый репозиторий", + "repository": "Репозиторий", + "repositoryNotFound": "Репозиторий не найден.", + "selectRepository": "Выберите репозиторий", + "sshConnection": "SSH-подключение", + "startFrom": "Начать с", + "title": "Создать рабочее пространство", + "workspaceName": "Название рабочего пространства" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "«{{name}}» уже существует.", + "nameRequired": "Укажите название.", + "nameTooLong": "Название должно быть не длиннее 80 символов.", + "openShell": "Открыть командную оболочку" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Выберите существующую ветку или ссылку Git.", + "baseBranchTitle": "Начать с", + "branchName": "Имя ветки: {{name}}", + "defaultBranch": "Ветка по умолчанию", + "defaultBranchSubtitle": "Использовать заданную базовую ветку репозитория", + "editPreset": "Изменить {{name}}", + "fullCheckout": "Полная выгрузка", + "fullCheckoutSubtitle": "Использовать весь репозиторий", + "newPreset": "Новый набор настроек", + "noBranches": "Подходящих веток нет.", + "searchBranches": "Поиск веток", + "sparseCheckoutTitle": "Выборочная выгрузка" + }, + "workspaceSshGate": { + "authenticationFailed": "Ошибка аутентификации", + "connected": "Подключён", + "connecting": "Подключение", + "connectionFailed": "Не удалось подключиться", + "deployingRelay": "Развёртывание ретранслятора", + "disconnected": "Отключён", + "reconnectFailed": "Не удалось подключиться повторно", + "reconnecting": "Повторное подключение" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Всегда доверять и запускать", + "creating": "Создание…", + "directoriesLabel": "Каталоги", + "directories_few": "{{count}} каталога", + "directories_many": "{{count}} каталогов", + "directories_one": "{{count}} каталог", + "directories_other": "{{count}} каталога", + "dontRun": "Не выполнять", + "editSparsePreset": "Изменить набор выборочной выгрузки", + "nameLabel": "Название", + "namePlaceholder": "Интерфейс рендерера", + "newSetupScript": "Новый скрипт настройки", + "newSparsePreset": "Новый набор выборочной выгрузки", + "runHooks": "Выполнить хуки", + "runSetupAndCreate": "Выполнить настройку и создать", + "runSetupTitle": "Запустить настройку из {{name}}?", + "setupChangedTitle": "Скрипт настройки {{name}} изменился", + "setupScript": "Скрипт настройки", + "setupSubtitle": "Перед созданием рабочего пространства для {{name}} выберите, запускать ли скрипт настройки.", + "setupTitle": "Запустить скрипт настройки?", + "skipSetupAndCreate": "Пропустить настройку и создать", + "trustFailed": "Не удалось добавить скрипт настройки в доверенные.", + "trustSubtitle": "Скрипт из orca.yaml этого репозитория выполняется на вашем компьютере перед запуском рабочего пространства. Запускайте его, только если доверяете этому репозиторию." + }, + "worktreeCreateRetry": { + "createFailed": "Не удалось создать рабочее пространство" } }, "terminal": { diff --git a/mobile/src/i18n/locales/tr.json b/mobile/src/i18n/locales/tr.json index 67f746007e7..c1b4a305f11 100644 --- a/mobile/src/i18n/locales/tr.json +++ b/mobile/src/i18n/locales/tr.json @@ -527,7 +527,7 @@ "agentLaunchNotice": { "copyFailed": "Kopyalanamadı", "copyPrompt": "İstemi kopyala", - "statusUnreadable": "Bu ana makinenin durumu okunamadı. Yeniden deneniyor…", + "statusUnreadable": "Bu sunucunun durumu okunamadı. Yeniden deneniyor…", "updateRequired": "Telefonunuzdan ajan başlatmak için bilgisayarınızdaki Orca'yı güncelleyin." }, "agentSpinner": { @@ -543,7 +543,7 @@ }, "authFailedBannerActions": { "repair": "Yeniden eşleştir", - "webNote": "Orca uygulamasından bu ana makineye yeniden bağlanın veya ana makineyi kaldırın." + "webNote": "Orca uygulamasından bu sunucuya yeniden bağlanın veya sunucuyu kaldırın." }, "codexResetCredit": { "alreadyAppliedTitle": "Sıfırlama zaten uygulandı", @@ -562,7 +562,7 @@ "expiryNowMultiple": "Sıradaki şimdi sona eriyor", "expiryNowSingle": "Şimdi sona eriyor", "invalidResponse": "Sunucudan geçersiz sıfırlama yanıtı", - "noResetMessage": "Bu hesabın kullanabileceği kazanılmış sıfırlama kredisi yok.", + "noResetMessage": "Bu hesabın kullanabileceği kazanılmış sıfırlama hakkı yok.", "noResetTitle": "Sıfırlama hakkı yok", "nothingToResetMessage": "Sıfırlamaya uygun hiçbir Codex hız sınırı penceresinde kullanım hakkı tükenmedi.", "nothingToResetTitle": "Sıfırlanacak bir şey yok", @@ -575,7 +575,7 @@ "resetting": "Sıfırlanıyor…", "resettingLabel": "Codex hız sınırları sıfırlanıyor", "scopedHint": "{{scopeLabel}} için kazanılmış bir sıfırlama hakkı kullanır", - "useReset": "Sıfırla", + "useReset": "Sıfırlama hakkını kullan", "useResetLabel": "Codex hız sınırı sıfırlama hakkını kullan" }, "customKeyModal": { @@ -698,15 +698,15 @@ "discard": "At", "discardFile": "Dosya değişikliklerini at", "markFileReviewed": "Dosyayı incelendi olarak işaretle", - "markReviewed": "İncelenmiş Say", + "markReviewed": "İncelendi Olarak İşaretle", "nextFile": "Sonraki dosya", "note": "Not", "previousFile": "Önceki dosya", "reviewed": "İncelendi", "stage": "Stage Et", "stageFile": "Dosyayı stage et", - "unstage": "Unstage Et", - "unstageFile": "Dosyayı unstage et" + "unstage": "Stage'den Çıkar", + "unstageFile": "Dosyayı stage'den çıkar" }, "diffReviewHeader": { "filterAll": "Tümü", @@ -763,7 +763,7 @@ "viewDiagnostics": "Ağ tanılamasını görüntüle" }, "hostProtocolGate": { - "checkingCompatibility": "Ana makine uyumluluğu kontrol ediliyor" + "checkingCompatibility": "Sunucu uyumluluğu kontrol ediliyor" }, "hostRouteNoticeBanner": { "dismissNotice": "Bildirimi kapat" @@ -942,18 +942,18 @@ "shortcutBarDescription": "Tuşları gösterip gizlemek için düğmeleri açıp kapatın. Terminal kısayol çubuğunda bir tuşun sırasını değiştirmek için tutamacını basılı tutup sürükleyin." }, "useCodexResetCreditAction": { - "confirmTitle": "Hız sınırı sıfırlama kredisi kullanılsın mı?", + "confirmTitle": "Hız sınırı sıfırlama hakkı kullanılsın mı?", "detailsChanged": "Sıfırlama ayrıntıları değişti", "detailsChangedMessage": "Sunucu Codex ile iletişime geçmeden önce hesap veya sıfırlama teklifi değişti. Güncellenen ayrıntıları inceleyin, ardından yeniden onaylayın.", "hostAccount": "Sunucudaki {{identity}}", - "hostAccountConfirmMessage": "Bu işlem, sunucudaki {{identity}} hesabı için kazanılmış bir sıfırlama kredisi kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", + "hostAccountConfirmMessage": "Bu işlem, sunucudaki {{identity}} hesabı için kazanılmış bir sıfırlama hakkı kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", "hostSelectedAccount": "sunucudaki seçili yönetilen hesap", - "hostSelectedAccountConfirmMessage": "Bu işlem, sunucudaki seçili yönetilen hesap için kazanılmış bir sıfırlama kredisi kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", + "hostSelectedAccountConfirmMessage": "Bu işlem, sunucudaki seçili yönetilen hesap için kazanılmış bir sıfırlama hakkı kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", "resetFailed": "Hız sınırları sıfırlanamadı", "wslAccount": "WSL {{distro}} üzerindeki {{identity}}", - "wslAccountConfirmMessage": "Bu işlem, WSL {{distro}} üzerindeki {{identity}} hesabı için kazanılmış bir sıfırlama kredisi kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", + "wslAccountConfirmMessage": "Bu işlem, WSL {{distro}} üzerindeki {{identity}} hesabı için kazanılmış bir sıfırlama hakkı kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar.", "wslSelectedAccount": "WSL {{distro}} üzerindeki seçili yönetilen hesap", - "wslSelectedAccountConfirmMessage": "Bu işlem, WSL {{distro}} üzerindeki seçili yönetilen hesap için kazanılmış bir sıfırlama kredisi kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar." + "wslSelectedAccountConfirmMessage": "Bu işlem, WSL {{distro}} üzerindeki seçili yönetilen hesap için kazanılmış bir sıfırlama hakkı kullanır ve uygun hız sınırı pencerelerini hemen sıfırlar." }, "voiceModelList": { "deleteModel": "{{label}} modelini sil", @@ -991,7 +991,7 @@ "connectingViaRelay": "Relay üzerinden bağlanılıyor…", "desktopUnreachable": "Bilgisayara ulaşılamadı", "disconnected": "Bağlantı kesildi", - "hostFallback": "Ana Makine", + "hostFallback": "Sunucu", "hostOffline": "{{host}} çevrimdışı", "hostOfflineDetail": "Bilgisayarınızın uyanık, Orca'nın çalışır durumda ve oturumunuzun açık olduğunu kontrol edin", "labelWithHint": "{{label}} — {{hint}}", @@ -1012,13 +1012,13 @@ "directViaTailscale": "Tailscale üzerinden doğrudan" }, "hostEndpoint": { - "addressRequired": "Bir ana makine adresi girin.", + "addressRequired": "Bir sunucu adresi girin.", "hostnameRequired": "Ana makine adı eksik.", "invalidAddress": "Geçerli bir adres değil.", "invalidHostname": "Geçerli bir ana makine adı değil.", "invalidPort": "Port 1–65535 aralığında olmalıdır.", "invalidScheme": "ws:// veya wss:// (ya da host:port) kullanın.", - "pathOrQueryNotAllowed": "Ana makine adresi yol veya sorgu içermemelidir." + "pathOrQueryNotAllowed": "Sunucu adresi yol veya sorgu içermemelidir." }, "pairConfirmState": { "invalidCode": "Geçerli bir eşleştirme kodu değil", @@ -1418,7 +1418,7 @@ "agentActivitySort": "Ajan Etkinliği", "agentActivitySortDescription": "Önce ilgilenilmesi gereken ajanlar, ardından en son etkinlik.", "agentStatuses": "Ajan durumları", - "allHosts": "Tüm ana makineler", + "allHosts": "Tüm sunucular", "allProjects": "Tüm projeler", "automation": "Otomasyon", "branchFolderPath": "Branch / klasör yolu", @@ -1428,7 +1428,7 @@ "fullList": "Tam liste", "githubIssues": "GitHub sorunları", "githubTicket": "GitHub sorunu", - "host": "Ana Makine", + "host": "Sunucu", "hover": "Üzerine gelme", "jiraIssue": "Jira sorunu", "jiraIssues": "Jira sorunları", @@ -1465,7 +1465,7 @@ "hideDetachedHead": "Detached HEAD durumundakileri gizle", "hideOtherClientWorkspaces": "Diğer istemcilerin çalışma alanlarını gizle", "hideSleeping": "Uyuyanları gizle", - "hosts": "Ana Makineler", + "hosts": "Sunucular", "localLinux": "Yerel Linux", "localMac": "Yerel Mac", "localWindows": "Yerel Windows", @@ -1495,7 +1495,21 @@ "workspace": "Çalışma Alanı" } }, + "newWorkspace": { + "hostPicker": { + "title": "Çalışma Alanı İçin Sunucu" + }, + "loadingDrawer": { + "downloadProgress": "İndiriliyor… {{progress}}", + "downloading": "İndiriliyor", + "loading": "Yükleniyor" + } + }, "notifications": { + "desktopChannel": { + "name": "Masaüstü Bildirimleri", + "silentName": "Orca sessiz bildirimleri" + }, "notificationDeliverySection": { "footer": "Uyarı türleri, eşleştirilen her bilgisayarın bildirim ayarlarına göre belirlenir. Bu uygulama 7 gün kullanılmazsa bildirimler duraklatılır; sürdürmek için uygulamayı açıp yeniden bağlanın.", "onlyWhenAway": "Yalnızca bilgisayardan uzaktayken", @@ -1745,7 +1759,7 @@ }, "prSidebarCreateEmptyState": { "branchNotLinked": "{{branch}} branch'i açık bir PR'a bağlı değil.", - "branchRequired": "Bir pull request oluşturmadan önce bir branch'e checkout yapın.", + "branchRequired": "Bir pull request oluşturmadan önce bir branch'i checkout edin.", "createFailed": "Pull request oluşturulamadı.", "createPr": "PR Oluştur", "createPullRequest": "Pull request oluştur", @@ -2094,7 +2108,7 @@ "globalScope": "Genel", "label": "Etiket", "labelPlaceholder": "Geliştirme sunucusunu başlat", - "olderHostPromptTooLong": "Bu ana makine için çok uzun. Daha uzun istemleri kaydetmek için ana makinedeki Orca'yı güncelleyin.", + "olderHostPromptTooLong": "Bu sunucu için çok uzun. Daha uzun istemleri kaydetmek için sunucudaki Orca'yı güncelleyin.", "projectScope": "Proje", "prompt": "İstem", "promptHint": "Becerileri, dosya yollarını ve yerleşik komutları destekler.", @@ -2224,7 +2238,7 @@ "startingMic": "Mikrofon başlatılıyor", "stopHint": "Durdurmak için mikrofona dokunun", "transcribing": "Masaüstünde yazıya dökülüyor", - "uploadingImage": "Görsel ana makineye yükleniyor", + "uploadingImage": "Görsel sunucuya yükleniyor", "uploadingImageTitle": "Görsel yükleniyor" }, "terminalRecords": { @@ -2327,7 +2341,7 @@ "terminalNotReady": "Durdurma isteği gönderilemedi (terminal hazır değil)" }, "usePanelRouteActions": { - "checkHostHint": "Ana makine bağlantısını kontrol edin", + "checkHostHint": "Sunucu bağlantısını kontrol edin", "copyNotesHint": "Bunun yerine notları kopyalayın", "detectingAgents": "Ajanlar Algılanıyor", "newSessionHint": "Yeni ajan oturumu", @@ -2355,12 +2369,12 @@ "inputTooLarge": "Girdi çok büyük (en fazla 256 KiB)" }, "useStartup": { - "wakeAgents": "Uykudaki ajanları uyandırmak için ana makinede Orca'yı açın." + "wakeAgents": "Uykudaki ajanları uyandırmak için sunucuda Orca'yı açın." }, "useTerminalCreateActions": { "createFailed": "Terminal oluşturulamadı", "forkBusy": "Başka bir terminal açılıyor. Bekleyip {{agentName}} sohbetini açmayı tekrar deneyin.", - "forkUnavailable": "Bağlı ve güncel bir ana makinede {{agentName}} sohbetini açıp tekrar deneyin.", + "forkUnavailable": "Bağlı ve güncel bir sunucuda {{agentName}} sohbetini açıp tekrar deneyin.", "inputLocked": "Terminal girişi başka bir istemci tarafından kilitlenmiş.", "notesSent": "Notlar gönderildi", "sendNotesError": "Notlar gönderilemedi", @@ -2524,11 +2538,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "Üzerine rebase edilecek temel branch yok", + "waitingForDesktop": "Masaüstü bekleniyor…" + }, "actions": { + "checkingReviewStatus": "İnceleme durumu kontrol ediliyor.", + "checkoutBeforePublish": "Commit'leri yayınlamadan önce bir branch'i checkout edin.", + "commitStagedChanges": "Stage edilmiş değişiklikleri commit'leyin.", "commits": "Commit'ler", + "committing": "Commit işlemi sürüyor.", "createPr": "PR Oluştur", + "enterCommitMessage": "Commit'lemek için bir commit mesajı girin.", + "forcePushWithLease": "Remote branch'i güncellemek için lease korumasıyla force push edin.", + "forcePushing": "Force push işlemi sürüyor.", + "linkedReviewUnavailable": "Bağlantılı inceleme branch'i kullanılamıyor.", + "publishToOrigin": "Bu branch'i origin'e yayınlayın.", + "pullCommits_one": "{{count}} commit pull edin.", + "pullCommits_other": "{{count}} commit pull edin.", "pushAndCreatePr": "Push Et ve PR Oluştur", - "switchBranch": "Branch'i değiştir" + "pushCommits_one": "{{count}} commit push edin.", + "pushCommits_other": "{{count}} commit push edin.", + "pushLinkedReview": "Güncellemeleri bağlantılı inceleme branch'ine push edin.", + "remoteOperationInProgress": "Remote işlemi sürüyor.", + "resolveConflicts": "Commit'lemeden önce çakışmaları çözün.", + "reviewAlreadyMerged": "Commit'lenecek bir şey yok. İnceleme zaten merge edildi.", + "stageAllChanges": "Tüm değişiklikleri stage edin.", + "stageFileToCommit": "Commit'lemek için en az bir dosyayı stage edin.", + "switchBranch": "Branch'i değiştir", + "syncCounts": "{{behind}} commit pull edin, {{ahead}} commit push edin.", + "upToDate": "Commit'lenecek bir şey yok. Branch güncel.", + "waitForRemoteOperation": "Remote işlemi tamamlandığında yeniden deneyin." + }, + "branchBaseRef": { + "resolveFailed": "Temel branch belirlenemedi" + }, + "branchCard": { + "branchCount": "branch'te {{count}}", + "changedCount": "{{count}} değişiklik", + "cherryPickState": "cherry-pick", + "mergeState": "merge", + "rebaseState": "rebase", + "stagedCount": "{{count}} stage edildi" + }, + "branchCompare": { + "commits_one": "{{count}} commit", + "commits_other": "{{count}} commit", + "files_one": "{{count}} dosya", + "files_other": "{{count}} dosya", + "sectionTitle": "Branch'e Commit Edildi", + "summary": "{{files}} - {{baseRef}} ile karşılaştırma", + "summaryWithCommits": "{{files}} - {{commits}} - {{baseRef}} ile karşılaştırma" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "Karşılaştırma için temel branch belirlenemedi.", + "loadFailed": "Commit'lenen değişiklikler yüklenemedi" + }, + "branchDiffPreviewDrawer": { + "closePreview": "Commit'lenmiş diff önizlemesini kapat", + "committedOnBranch": "Branch'e commit'lendi", + "loadFailed": "Diff Yüklenemedi", + "truncated": "Diff, mobil önizleme için kısaltıldı." }, "commitDropdown": { "checkOutBranchToPush": "Commit'leri push etmeden önce bir branch'i checkout edin", @@ -2544,17 +2614,58 @@ "commitStagedChanges": "Stage edilmiş değişiklikleri commit'le", "commitSync": "Commit'le ve Senkronize Et", "commitThenPullPush": "Commit'leyin, ardından pull ve push yapın", - "enterMessage": "Commit etmek için bir commit mesajı girin", + "enterMessage": "Commit'lemek için bir commit mesajı girin", "linkedReviewTargetUnavailable": "Bağlı incelemenin hedef branch'i kullanılamıyor", "prAlreadyMerged": "PR zaten merge edilmiş", "publishBranchFirstToPush": "Commit'leri push etmek için önce branch'i yayımlayın", "publishBranchFirstToSync": "Commit'leri senkronize etmek için önce branch'i yayımlayın", - "resolveConflicts": "Commit etmeden önce conflict'leri çözün", - "stageFile": "Commit etmek için en az bir dosya stage edin", + "resolveConflicts": "Commit'lemeden önce conflict'leri çözün", + "stageFile": "Commit'lemek için en az bir dosya stage edin", "useCommitAndForcePush": "Commit ve force push seçeneğini kullanın — remote'da yalnızca yerel commit'lerin eski kopyaları var" }, + "commitFailurePanel": { + "fix": "Düzelt", + "fixWithAi": "Commit hatasını AI ile düzelt", + "hideDetails": "Ayrıntıları gizle", + "hideFailureDetails": "Commit hatasının ayrıntılarını gizle", + "showDetails": "Ayrıntıları göster", + "showFailureDetails": "Commit hatasının ayrıntılarını göster", + "summary": "Commit'lenemedi.", + "title": "Commit'lenemedi" + }, + "commitMessageAi": { + "generateFailed": "Commit mesajı oluşturulamadı" + }, + "commitRunners": { + "actionFailed": "Kaynak kontrolü işlemi gerçekleştirilemedi", + "commitFailed": "Commit'lenemedi" + }, + "conflictAbort": { + "abortMerge": "Merge'i iptal et", + "abortOperation": "{{operation}} işlemini iptal et", + "abortRebase": "Rebase'i iptal et", + "aborting": "İptal ediliyor…" + }, + "content": { + "cancelGeneration": "Commit mesajı oluşturmayı iptal et", + "commitMessageDisabled": "Commit mesajı devre dışı. Stage edilmiş dosya yok.", + "commitMessagePlaceholder": "Commit mesajı", + "emptyMessage": "Çalışma ağacı temiz.", + "emptyTitle": "Yerel değişiklik yok", + "generateMessage": "Commit mesajını AI ile oluştur", + "noStagedFiles": "Stage edilmiş dosya yok", + "openActions": "Kaynak kontrolü eylemlerini aç", + "reconnecting": "Masaüstüne yeniden bağlanılıyor…", + "regenerateHint": "Yeniden oluşturmak için mesajı temizleyin.", + "stageAll": "Tümünü Stage Et", + "unstageAll": "Tümünü Stage'den Çıkar" + }, "createPrAction": { - "createReview": "{{titleLabel}} oluştur" + "checkingStatus": "İnceleme durumu kontrol ediliyor…", + "createPullRequest": "Pull Request Oluştur", + "createReview": "{{titleLabel}} oluştur", + "providerUnavailable": "Bu sağlayıcıda inceleme oluşturulamıyor", + "statusUnavailable": "İnceleme durumu kullanılamıyor" }, "dropdownCounts": { "fastForwardCount_one": "{{count}} commit fast-forward et", @@ -2576,6 +2687,64 @@ "titleUnpublishedForcePushCount_one": "Branch'teki {{count}} commit'i lease korumasıyla force push edin ve gerekirse bir upstream ayarlayın.", "titleUnpublishedForcePushCount_other": "Branch'teki {{count}} commit'i lease korumasıyla force push edin ve gerekirse bir upstream ayarlayın." }, + "fileList": { + "committedSection": "Branch'e Commit'lendi" + }, + "fileRows": { + "addedByThem": "Karşı tarafça eklendi", + "addedByUs": "Tarafımızdan eklendi", + "bothAdded": "İki tarafta da eklendi", + "bothDeleted": "İki tarafta da silindi", + "bothModified": "İki tarafta da değiştirildi", + "committedSection": "Branch'e Commit'lendi", + "committedUnavailable": "Commit'lenen değişiklikler kullanılamıyor.", + "deletedByThem": "Karşı tarafça silindi", + "deletedByUs": "Tarafımızdan silindi", + "discardFile": "{{path}} değişikliklerini at", + "loadingCommitted": "Commit'lenen değişiklikler yükleniyor…", + "openChangedFile": "Değiştirilen {{path}} dosyasını aç", + "openCommittedChange": "{{path}} için commit'lenen değişikliği aç", + "renamedFrom": "önceki yol: {{path}}", + "stageFile": "{{path}} dosyasını stage et", + "unresolvedConflict": "Çözülmemiş çakışma", + "unstageFile": "{{path}} dosyasını stage'den çıkar" + }, + "gitHistory": { + "days_one": "{{count}}g", + "days_other": "{{count}}g", + "hours_one": "{{count}}sa", + "hours_other": "{{count}}sa", + "justNow": "az önce", + "loadFailed": "Commit geçmişi yüklenemedi", + "minutes_one": "{{count}}dk", + "minutes_other": "{{count}}dk", + "months_one": "{{count}}ay", + "months_other": "{{count}}ay", + "noCommitMessage": "(commit mesajı yok)", + "years_one": "{{count}}yıl", + "years_other": "{{count}}yıl" + }, + "gitHistoryList": { + "loadFailed": "Geçmiş yüklenemedi", + "loadFilesFailed": "Commit dosyaları yüklenemedi", + "noCommits": "Commit yok.", + "noFileChanges": "Dosya değişikliği yok", + "retryFiles": "Commit dosyalarını yüklemeyi yeniden dene", + "waitingForDesktop": "Masaüstü bekleniyor…" + }, + "gitStatus": { + "changes": "Değişiklikler", + "conflicts": "Conflict'ler", + "stagedChanges": "Stage Edilen Değişiklikler" + }, + "header": { + "backToSession": "Oturuma dön", + "close": "Kaynak kontrolünü kapat", + "openNumberedPrWeb": "#{{number}} numaralı pull request'i tarayıcıda aç", + "openPrWeb": "Pull request'i tarayıcıda aç", + "refresh": "Kaynak kontrolünü yenile", + "title": "Kaynak Kontrolü" + }, "hostedReview": { "mrCopy": { "reviewLabel": "merge request", @@ -2588,15 +2757,87 @@ "titleLabel": "Pull Request" } }, + "hostedReviewCopy": { + "committingChanges": "Değişiklikler commit'leniyor…", + "creatingReview": "İnceleme oluşturuluyor…", + "forcePushing": "Lease ile force push yapılıyor…", + "generatingCommitMessage": "Commit mesajı oluşturuluyor…", + "publishingBranch": "Branch yayınlanıyor…", + "pushingCommits": "Commit'ler push ediliyor…", + "stagingChanges": "Değişiklikler stage ediliyor…", + "updatingBranch": "Branch güncelleniyor…" + }, "hostedReviewCreate": { "pushSucceeded": "Push tamamlandı, ancak {{shortLabel}} oluşturulamadı: {{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "Pull request hazırlanırken branch değişti.", + "generateMessageFailed": "Commit mesajı oluşturulamadı. Kaynak Kontrolü bölümünde bir mesaj ekleyip tekrar deneyin.", + "resolveConflicts": "Pull request oluşturmadan önce conflict'leri çözün.", + "resolveOrStageChanges": "Pull request oluşturmadan önce conflict'leri çözün veya değişiklikleri stage edin.", + "reviewCommitMessage": "Commit mesajını gözden geçirin, ardından PR Oluştur işlemini tekrar deneyin." + }, + "hostedReviewGitPreparation": { + "commitFailed": "Commit'lenemedi", + "refreshFailed": "Kaynak kontrolü yenilenemedi", + "stageFailed": "Değişiklikler stage edilemedi", + "updateBranchFailed": "Remote branch güncellenemedi. PR Oluştur işlemini tekrar deneyin." + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "Lease ile force push yapılamadı", + "publishFailed": "Branch yayınlanamadı", + "pushFailed": "Commit'ler push edilemedi" + }, + "hostedReviewService": { + "createFailed": "Pull request oluşturulamadı", + "pushBeforeCreateFailed": "Push işlemi yapılamadı. Push hatasını giderip tekrar deneyin." + }, + "hubTab": { + "changes": "Değişiklikler", + "commits": "Commit'ler", + "pullRequest": "Pull Request" + }, + "loaders": { + "connectingToDesktop": "Masaüstüne bağlanılıyor…", + "loadFailed": "Kaynak kontrolü yüklenemedi", + "updateDesktop": "Mobilde Kaynak Kontrolü özelliğini kullanmak için Orca masaüstü uygulamasını güncelleyin.", + "waitingForDesktop": "Masaüstü bekleniyor…" + }, + "modals": { + "actionsTitle": "Kaynak Kontrolü", + "currentBranch": "geçerli", + "discardButton": "At", + "discardConfirmMessage": "“{{path}}” dosyasındaki değişiklikler atılsın mı? Bu işlem geri alınamaz.", + "discardTitle": "Değişikliği At", + "openPrMessage": "Tarayıcınızda açılsın mı?", + "openPrWithWarning": "Tarayıcınızda açılsın mı?\n\n{{warning}}", + "prCreatedTitle": "Pull Request Oluşturuldu", + "switchBranchTitle": "Branch Değiştir" + }, + "openers": { + "openDiffFailed": "Diff açılamadı", + "tabNotReady": "Dosya açıldı ancak sekmesi henüz hazır değil. Yeniden deneyin.", + "waitingForDesktop": "Masaüstü bekleniyor…" + }, + "panel": { + "loadFailedTitle": "Yüklenemedi", + "unavailableTitle": "Kaynak Kontrolü Kullanılamıyor" + }, + "prChip": { + "createPr": "Pull request oluştur", + "loading": "Pull request yükleniyor…", + "loadingLabel": "Pull request yükleniyor", + "openLabel": "#{{number}} numaralı pull request, {{state}}, {{checks}}. Pull request'i aç.", + "openWithComments_one": "#{{number}} numaralı pull request, {{state}}, {{checks}}, {{count}} çözülmemiş yorum. Pull request'i aç.", + "openWithComments_other": "#{{number}} numaralı pull request, {{state}}, {{checks}}, {{count}} çözülmemiş yorum. Pull request'i aç.", + "unavailableLabel": "Pull request kullanılamıyor: {{message}}" + }, "prCreate": { "authRequired": "Bir {{reviewLabel}} oluşturmadan önce kimliğinizi doğrulayın.", "baseNotOnRemote": "Bir {{reviewLabel}} oluşturmadan önce temel branch'i push edin.", "createdNotRefreshed": "{{titleLabel}} oluşturuldu ancak Orca tarafından henüz yenilenemedi.", "defaultBranch": "Bir {{reviewLabel}} oluşturmadan önce bir özellik branch'ine geçin.", - "detachedHead": "Bir {{reviewLabel}} oluşturmadan önce bir branch'e geçiş yapın (checkout).", + "detachedHead": "Bir {{reviewLabel}} oluşturmadan önce bir branch'i checkout edin.", "dirty": "Bir {{reviewLabel}} oluşturmadan önce değişiklikleri commit'leyin.", "existing": "{{titleLabel}} zaten açık.", "existingNumber": "{{titleLabel}} #{{number}} zaten açık.", @@ -2609,8 +2850,19 @@ "unsupportedMergeRequests": "Bu repo için merge request oluşturma desteklenmiyor.", "unsupportedPullRequests": "Bu repo için pull request oluşturma desteklenmiyor." }, + "prLink": { + "updatePullRequestFailed": "Bağlı pull request güncellenemedi", + "updateReviewFailed": "Bağlı inceleme güncellenemedi" + }, "primaryAction": { - "forcePushFromDesktop": "Bu pull request'in branch'ini masaüstünden force push edin" + "commit": "Commit", + "forcePush": "Force Push", + "forcePushFromDesktop": "Bu pull request'in branch'ini masaüstünden force push edin", + "publishBranch": "Branch'i Yayınla", + "pull": "Pull", + "push": "Push", + "stageAll": "Tümünü Stage Et", + "sync": "Senkronize Et" }, "remoteDropdown": { "branchAlreadyPublished": "Branch zaten yayımlandı", @@ -2660,6 +2912,591 @@ "tryFastForwardPull": "Fast-forward pull işlemini deneyin; git yerel commit'leri reddedebilir", "tryRegularPush": "Normal push işlemini deneyin; git force push gerektirebilir", "useForcePushToSync": "Force Push işlemini kullanın — remote'ta yalnızca yerel commit'lerin eski kopyaları var" + }, + "runners": { + "actionFailed": "Kaynak kontrolü işlemi gerçekleştirilemedi" + }, + "screenState": { + "noBranch": "Branch yok" + }, + "state": { + "noUpstream": "Upstream yok", + "syncStatus": "{{ahead}} ileride, {{behind}} geride" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "Ajan başlatılamadı", + "waitingForDesktop": "Masaüstü bekleniyor…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "Commit mesajı oluşturulamadı" + }, + "useMobileCreatePrRunner": { + "branchRequired": "Pull request oluşturmadan önce bir branch'i checkout edin." + }, + "useMobileGitRequests": { + "actionFailed": "Kaynak kontrolü işlemi gerçekleştirilemedi", + "branchUnavailable": "Branch durumu alınamadı", + "commitFailed": "Commit'lenemedi", + "waitingForDesktop": "Masaüstü bekleniyor…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "Temel branch çözümlenemedi.", + "forkPushWarning": "Bu PR'da “Allow edits from maintainers” kapalı; fork'a push işlemi GitHub tarafından reddedilebilir." + }, + "detailCommentRenderers": { + "commentPlaceholder": "Bir yorum ekleyin", + "comments_one": "{{count}} yorum", + "comments_other": "{{count}} yorum", + "reopenThread": "Yorum dizisini yeniden aç", + "reply": "Yanıtla", + "resolveThread": "Yorum dizisini çöz", + "resolvedCommentBy": "Çözülmüş yorum · {{author}}", + "resolvedThreadBy": "Çözülmüş yorum dizisi · {{author}}", + "sendComment": "Yorumu gönder", + "show": "Göster" + }, + "filterPickers": { + "allTeams": "Tüm takımlar", + "changeStatus": "Durumu Değiştir", + "fieldHidden": "Kartlarda gizli", + "fieldShown": "Kartlarda gösteriliyor", + "fieldsSubtitle": "Öğe kartlarında gösterilecek Proje alanlarını seçin.", + "fieldsTitle": "Proje Alanları", + "gitlabFilter": "GitLab Filtresi", + "gitlabView": "GitLab Görünümü", + "jiraFilter": "Jira Filtresi", + "jiraSite": "Jira Sitesi", + "linearFilter": "Linear Filtresi", + "linearIssue": "Linear sorunu", + "linearWorkspace": "Linear Çalışma Alanı", + "loadingStates": "Durumlar yükleniyor…", + "noFields": "Bu görünümde gösterilecek ek alan yok.", + "noStates": "Kullanılabilir durum yok", + "switchWorkspaceFailed": "Çalışma alanı değiştirilemedi", + "teamsSubtitle": "Görevler bölümünde hangi takımların görüneceğini seçin.", + "teamsTitle": "Linear Takımları", + "teams_one": "{{count}} takım", + "teams_other": "{{count}} takım" + }, + "githubProjectList": { + "browseProjects": "Projelere göz at", + "chooseProject": "Bir GitHub projesi seçin", + "emptyField": "Boş", + "issueSubtitle": "Sorun · {{repository}}{{number}}", + "itemSubtitle": "Proje öğesi · {{repository}}{{number}}", + "items": "Öğeler", + "moreFields_one": "+{{count}} alan", + "moreFields_other": "+{{count}} alan", + "noItems": "Proje öğesi yok", + "pullRequestSubtitle": "Pull request · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "Ekle", + "addByUrlHint": "Eksik projelere erişmek için URL ile ekleme alanını kullanın.", + "addPlaceholder": "URL veya sahip/numara ile ekle", + "adding": "Ekleniyor…", + "browseAll": "Tümüne göz at", + "browseLoading": "Tümüne göz at (yükleniyor…)", + "chooseView": "Proje Görünümü Seç", + "loadFailed": "Projeler yüklenemedi", + "noMatches": "Eşleşen proje yok.", + "noMoreProjects": "Başka proje yok.", + "noProjects": "Yüklenmiş proje yok", + "organizationsError": "kuruluşlar: {{message}}", + "organizationsLoadFailed": "Bazı kuruluşlar yüklenemedi ({{count}}).", + "ownerLoadFailed": "{{owner}} hesabının projeleri yüklenemedi.", + "pin": "Sabitle", + "pinned": "Sabitlenenler", + "recent": "Son Kullanılanlar", + "retryHint": "Yeniden denemek için dokunun.", + "searchProjects": "Proje ara", + "sort": "Proje Sıralaması", + "subtitle": "Görevler sayfası için bir proje görünümü seçin.", + "title": "GitHub Projects", + "unsupportedLayout": "Orca bu GitHub Projects düzenini henüz desteklemiyor.", + "view": "Proje Görünümü" + }, + "githubViewControls": { + "fields": "Alanlar: {{fields}}", + "openView": "Görünümü GitHub'da aç", + "sort": "Sıralama: {{sort}}", + "source": "Kaynak: {{source}}" + }, + "itemActions": { + "changeStatus": "Durumu değiştir", + "copyGitHubLink": "GitHub bağlantısını kopyala", + "copyLinearLink": "Linear bağlantısını kopyala", + "createWorkspace": "Çalışma Alanı Oluştur", + "creating": "Oluşturuluyor…", + "mergeConflicts": "GitHub merge çakışmaları olduğunu bildiriyor.", + "mergeMergeRequest": "Merge request'i merge et", + "mergePullRequest": "Pull request'i merge et" + }, + "itemDetailContent": { + "addSubIssue": "Alt sorun ekle", + "assignee": "Atanan kişi", + "assignees": "Atanan kişiler", + "checks": "Kontroller", + "description": "Açıklama", + "discussion": "Tartışma", + "noChecks": "Kontrol bulunamadı.", + "noComments": "Yorum yok.", + "noPipelineRuns": "Bu MR için pipeline çalıştırması yok.", + "noSubIssues": "Alt sorun yok.", + "none": "Yok", + "pipeline": "Pipeline", + "pipelineJobs_one": "{{count}} iş", + "pipelineJobs_other": "{{count}} iş", + "project": "Proje", + "rerunAll": "Tümünü yeniden çalıştır", + "rerunFailed": "Başarısızları yeniden çalıştır", + "status": "Durum", + "subIssueTitle": "Alt sorun başlığı", + "subIssues": "Alt sorunlar", + "type": "Tür" + }, + "itemDetailDrawer": { + "refreshDetails": "Ayrıntıları yenile" + }, + "itemFieldEditors": { + "addLabels": "Eklenecek etiketleri virgülle ayırın", + "addUsernames": "Eklenecek kullanıcı adlarını virgülle ayırın", + "assignees": "Atananlar", + "labels": "Etiketler", + "loadingAssignees": "Atananlar yükleniyor…", + "loadingLabels": "Etiketler yükleniyor…", + "noAssignableUsers": "Bu repo için atanabilecek kullanıcı bulunamadı.", + "noLabels": "Bu repoda etiket yok.", + "none": "Yok", + "removeLabels": "Kaldırılacak etiketleri virgülle ayırın", + "removeUsernames": "Kaldırılacak kullanıcı adlarını virgülle ayırın", + "saveTitle": "Başlığı kaydet", + "title": "Başlık", + "updateAssignees": "Atananları güncelle", + "updateLabels": "Etiketleri güncelle" + }, + "itemReviewSections": { + "binaryFile": "İkili dosya.", + "changedFilesTitle": "Değiştirilen dosyalar", + "descriptionPlaceholder": "Açıklama", + "fileContentsUnavailable": "Dosya içeriğine erişilemiyor.", + "hideFile": "Gizle", + "loadingReviewers": "İnceleyenler yükleniyor…", + "markUnviewed": "Görülmedi olarak işaretle", + "markViewed": "Görüldü olarak işaretle", + "noDescription": "Açıklama yok.", + "noReviewerSuggestions": "İnceleyen önerisi bulunamadı.", + "noReviewersRequested": "Kimseden inceleme istenmedi.", + "requestReview": "İnceleme iste", + "reviewersPlaceholder": "İnceleme istenecek kişiler", + "reviewersTitle": "İnceleyenler", + "saveDescription": "Açıklamayı kaydet", + "viewFile": "Görüntüle" + }, + "legacySurface": { + "loadIssuesFailed": "{{source}} kaynağından sorunlar yüklenemedi.", + "mergeAction": "Merge et", + "mergeMethodTitle": "Merge yöntemi", + "mergePullRequestTitle": "Pull Request'i Merge Et", + "mergeRequestMergeMessage": "Bu merge request'in nasıl merge edileceğini seçin.", + "mergeRequestTitle": "Merge Request", + "pullRequestMergeMessage": "Bu pull request'in nasıl merge edileceğini seçin.", + "retryLoadingIssues": "{{source}} kaynağından sorunları yüklemeyi yeniden dene", + "retrying": "Yeniden deneniyor…", + "sourceFallback": "{{repo}} için tercih edilen sorun kaynağı upstream kullanılamıyor. origin kullanılıyor.", + "subIssueDataUnavailable": "Belirtecinizle alt sorun verilerine erişilemiyor.", + "updateItemTitle": "Öğeyi Güncelle" + }, + "linearList": { + "changeStatusFrom": "Durumu değiştir (şu an: {{status}})" + }, + "linearViewControls": { + "displayButton": "Görünüm", + "groupLabel": "Gruplama: {{group}}", + "orderLabel": "Sıralama: {{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "Gösterilecek Özellikler", + "linearGroupTitle": "Linear Sorunlarını Grupla", + "linearOrderTitle": "Linear Sorunlarını Sırala", + "linearViewTitle": "Linear Görünümü", + "sortTasksTitle": "Görevleri Sırala" + }, + "listSurface": { + "connectLinearButton": "Linear'ı bağla", + "connectLinearMessage": "Doğrudan Görevler bölümünden size atanan Linear sorunlarına göz atın ve üzerlerinde çalışmaya başlayın.", + "connectLinearTitle": "Linear hesabınızı bağlayın", + "jiraStatusFailed": "Jira durumu okunamadı", + "updateDesktopMessage": "Bu mobil Görevler görünümü için masaüstü çalışma zamanının daha yeni bir sürümü gerekiyor.", + "updateDesktopTitle": "Orca masaüstü uygulamasını güncelleyin" + }, + "options": { + "all": "Tümü", + "assignedToMe": "Bana atananlar", + "assignee": "Atanan kişi", + "board": "Pano", + "boardDescription": "Gruplandırılmış sütunlar", + "closedState": "Kapalı", + "completedState": "Tamamlandı", + "createdState": "Oluşturduklarım", + "githubAssignedIssuesDescription": "Size atanan açık sorunlar", + "githubDescription": "Sorunlar ve pull request'ler", + "githubIssuesDescription": "GitHub sorunları", + "githubOpenIssuesDescription": "Açık GitHub sorunları", + "githubProjectsDescription": "GitHub Projects görünümleri", + "githubPullRequestsDescription": "GitHub pull request'leri", + "gitlabAllDescription": "Tüm GitLab durumları", + "gitlabClosedDescription": "Kapatılan sorunlar ve merge request'ler", + "gitlabDescription": "Sorunlar ve merge request'ler", + "gitlabMergedDescription": "Merge edilen merge request'ler", + "gitlabOpenDescription": "Açık sorunlar ve merge request'ler", + "identifier": "Tanımlayıcı", + "issues": "Sorunlar", + "jiraDescription": "Atanan ve bildirilen sorunlar", + "labels": "Etiketler", + "linearAllDescription": "Bağlı çalışma alanlarındaki açık sorunlar", + "linearAssignedDescription": "Size atanan sorunlar", + "linearCompletedDescription": "Yakın zamanda tamamlanan sorunlar", + "linearCreatedDescription": "Oluşturduğunuz sorunlar", + "linearDescription": "Atanan sorunlar ve takım sorunları", + "list": "Liste", + "listDescription": "Kompakt sorun satırları", + "mergedState": "Merge edildi", + "mine": "Benimkiler", + "myIssues": "Sorunlarım", + "myPullRequestsDescription": "Oluşturduğunuz pull request'ler", + "myTodos": "Yapılacaklarım", + "myTodosDescription": "GitLab'da bekleyen yapılacaklar", + "needsReview": "İnceleme gerekiyor", + "noGrouping": "Gruplama yok", + "openPullRequestsDescription": "Açık pull request'ler", + "openState": "Açık", + "priority": "Öncelik", + "projectMergeRequests": "Proje MR'ları", + "projectMergeRequestsDescription": "Repository'ye göre merge request'ler ve sorunlar", + "projects": "Projeler", + "pullRequests": "PR'lar", + "repository": "Repository", + "repositorySortDescription": "Repository'ye göre gruplama, en yeni etkinlik önce", + "reviewRequestsDescription": "Size atanan inceleme istekleri", + "status": "Durum", + "team": "Takım", + "updated": "Güncellenme", + "updatedSortDescription": "En yeni etkinlik önce" + }, + "pickerProjection": { + "allRepos": "Tüm repolar", + "allSites": "Tüm siteler", + "currentlyAscending": "Artan sıra · azalan sıraya geçmek için dokunun", + "currentlyDescending": "Azalan sıra · artan sıraya geçmek için dokunun", + "fieldAscending": "{{field}} (artan)", + "fieldDescending": "{{field}} (azalan)", + "fields": "Alanlar", + "repos_one": "{{count}} repo", + "repos_other": "{{count}} repo", + "selectTarget": "Hedef seç", + "selectedFields": "{{selected}}/{{total}} alan", + "sortAscending": "Artan düzende sırala", + "sources_one": "{{count}} kaynak", + "sources_other": "{{count}} kaynak", + "unsupportedLayout": "Bu düzen mobilde desteklenmiyor", + "updatedSort": "Son güncelleme", + "usesFieldAscending": "{{field}} için artan sıralama kullanır", + "usesFieldDescending": "{{field}} için azalan sıralama kullanır", + "usesGitHubRankOrder": "GitHub sırasını kullanır", + "viewNumber": "Görünüm #{{number}}", + "viewOrder": "Görünüm sırası" + }, + "prFileDiff": { + "commentOnLine": "{{line}}. satıra yorum ekle", + "commentPlaceholder": "İnceleme yorumu ekleyin", + "noTextChanges": "Metin değişikliği bulunamadı.", + "showingDiffLines": "{{total}} diff satırından ilk {{limit}} satır gösteriliyor." + }, + "projectComments": { + "comments_one": "{{count}} yorum", + "comments_other": "{{count}} yorum", + "discussion": "Tartışma", + "editComment": "Yorumu düzenle", + "noComments": "Yorum yok.", + "reopenThread": "Yorum dizisini yeniden aç", + "reply": "Yanıtla", + "resolveThread": "Yorum dizisini çöz", + "resolvedCommentBy": "Çözülmüş yorum · {{author}}", + "resolvedThreadBy": "Çözülmüş yorum dizisi · {{author}}", + "show": "Göster" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} Orca'ya eklenmemiş. Bu repository'yi masaüstü uygulamasından ekleyin, ardından mobilde Görevler bölümünü yenileyin.", + "clearType": "Türü temizle", + "closeItem": "Öğeyi kapat", + "copyGitHubLink": "GitHub bağlantısını kopyala", + "copyRepository": "Repository'yi kopyala", + "createWorkspace": "Çalışma Alanı Oluştur", + "draftIssue": "Taslak sorun", + "issue": "Sorun", + "issueType": "Sorun türü", + "loadingIssueTypes": "Sorun türleri yükleniyor…", + "mergePullRequest": "Pull request'i merge et", + "mergeRepositoryRequirement": "Merge için bu repository'nin Orca'da olması gerekir.", + "noIssueTypes": "Bu repository için sorun türü yapılandırılmamış.", + "noType": "Tür yok", + "openInGitHub": "GitHub'da aç", + "projectItem": "Proje öğesi", + "projectSubtitle": "GitHub Projesi · {{repository}}{{itemNumber}}", + "pullRequest": "Pull request", + "reopenItem": "Öğeyi yeniden aç", + "repositoryNotInOrca": "Repository Orca'da değil", + "status": "Durum", + "type": "Tür", + "workspaceCreationRequirement": "Çalışma alanları yalnızca GitHub sorunlarından ve pull request'lerinden oluşturulabilir." + }, + "projectFieldEditors": { + "clearField": "Alanı temizle", + "completedIteration": "Tamamlandı · {{startDate}} · {{duration}} gün", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "YYYY-MM-DD biçiminde bir tarih girin.", + "invalidNumber": "Geçerli bir sayı girin.", + "noIterations": "Kullanılabilir yineleme yok.", + "numberPlaceholder": "Sayı", + "projectFields": "Proje alanları", + "saveField": "Alanı kaydet", + "textPlaceholder": "Metin", + "upcomingIteration": "Mevcut ve yaklaşan · {{startDate}} · {{duration}} gün" + }, + "projectMetadataEditors": { + "assignees": "Atanan kişiler", + "description": "Açıklama", + "labels": "Etiketler", + "loadingAssignees": "Atanan kişiler yükleniyor…", + "loadingLabels": "Etiketler yükleniyor…", + "noAssignableUsers": "Bu repository için atanabilecek kullanıcı bulunamadı.", + "noDescription": "Açıklama yok.", + "noLabels": "Bu repository'de etiket yok.", + "none": "Yok", + "saveDescription": "Açıklamayı kaydet", + "saveTitle": "Başlığı kaydet", + "title": "Başlık" + }, + "projectReviewPanels": { + "binaryFile": "İkili dosya.", + "changedFiles": "Değiştirilen dosyalar", + "checks": "Kontroller", + "fileUnavailable": "Dosya içeriği kullanılamıyor.", + "hideFile": "Gizle", + "loadingReviewers": "İnceleyenler yükleniyor…", + "markUnviewed": "Görülmedi olarak işaretle", + "markViewed": "Görüldü olarak işaretle", + "noChecks": "Kontrol bulunamadı.", + "noReviewers": "Kimseden inceleme istenmedi.", + "noSuggestions": "İnceleyen önerisi bulunamadı.", + "requestReview": "İnceleme iste", + "requestReviewers": "İnceleme istenecek kişiler", + "rerunAll": "Tümünü yeniden çalıştır", + "rerunFailed": "Başarısızları yeniden çalıştır", + "reviewers": "İnceleyenler", + "viewFile": "Görüntüle" + }, + "providerControls": { + "myTodos": "Yapılacaklarım", + "projectMergeRequests": "Proje MR'ları", + "sort": "Sırala: {{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "{{base}} branch'ine", + "nextPage": "Sonraki sayfa", + "page": "Sayfa {{page}}", + "pageOfTotal": "Sayfa {{page}} / {{total}}", + "previousPage": "Önceki sayfa", + "selectPage": "Sayfa seç, sayfa {{page}}", + "selectPageOfTotal": "Sayfa seç, {{total}} sayfadan {{page}}. sayfa" + }, + "providerPickers": { + "allRepositories": "Tüm repository'ler", + "githubView": "GitHub Görünümü", + "issueSources": "GitHub Sorun Kaynakları", + "issueSourcesDescription": "Her repository'nin sorgulama ve iş oluşturma için upstream mi yoksa origin mi kullanacağını seçin.", + "issues": "Sorunlar", + "noIssueSources": "Alternatif sorun kaynağı yok.", + "origin": "Origin", + "pageHint": "Yüklenmiş veya kullanılabilir bir sonuç sayfasına geçin.", + "pageLoaded": "Yüklendi", + "pageNotLoaded": "Daha eski sonuçları yükler", + "pageNumber": "Sayfa {{page}}", + "pages": "GitHub Sayfaları", + "pullRequests": "Pull Request'ler", + "queryingSource": "{{source}} sorgulanıyor", + "repoDescription": "Sorgulanacak repository'leri seçin.", + "repos": "Repository'ler", + "taskSource": "Görev Kaynağı", + "upstream": "Upstream" + }, + "providerViewProjection": { + "all": "Tümü", + "allSites": "Tüm siteler", + "allTeams": "Tüm takımlar", + "allWorkspaces": "Tüm çalışma alanları", + "chooseProject": "Proje seç", + "default": "Varsayılan", + "defaultSubtitle": "{{subtitle}} · Varsayılan", + "issues": "Sorunlar", + "list": "Liste", + "noGrouping": "Gruplama yok", + "openState": "Açık", + "priority": "Öncelik", + "projects": "Projeler", + "pullRequests": "PR'lar", + "teams_one": "{{count}} takım", + "teams_other": "{{count}} takım", + "workspace": "Çalışma Alanı" + }, + "reviewerLinear": { + "issues": "Sorunlar", + "unassigned": "Atanmamış" + }, + "screenChrome": { + "connectLinear": "Linear'ı bağla", + "newGitHubIssue": "Yeni GitHub sorunu", + "newLinearIssue": "Yeni Linear sorunu", + "refreshGitHub": "GitHub işini yenile", + "refreshGitLab": "GitLab iş öğelerini yenile", + "refreshJira": "Jira sorunlarını yenile", + "refreshLinear": "Linear'ı yenile", + "title": "Görevler" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL, ör. project = ABC AND statusCategory != Done", + "projectPlaceholder": "Proje görünümünde ara…", + "providerPlaceholder": "{{provider}} görevlerinde ara…" + }, + "smartSourceModes": { + "allStates": "Tümü", + "branch": "Branch", + "closedState": "Kapalı", + "mergedState": "Merge edildi", + "name": "Ad", + "openState": "Açık", + "smart": "Akıllı" + }, + "sparsePresetDraft": { + "directoryRequired": "En az bir dizin ekleyin.", + "repoRelativeDirectoriesRequired": "Kök, mutlak yollar veya üst dizin segmentleri yerine repository'ye göreli dizinler kullanın." + }, + "taskViewOptions": { + "allSubtitle": "Seçili sitelerdeki çözülmemiş sorunlar", + "assignedSubtitle": "Size atanmış çözülmemiş sorunlar", + "doneSubtitle": "Yakın zamanda çözülen sorunlarınız", + "noGitHubTasks": "GitHub görevi yok", + "noGitLabTasks": "GitLab görevi yok", + "noJiraTasks": "Jira görevi yok", + "noLinearTasks": "Linear görevi yok", + "reportedSubtitle": "Bildirdiğiniz çözülmemiş sorunlar" + }, + "tasksCreateDrawers": { + "connect": "Bağlan", + "connectLinearWorkspace": "Linear çalışma alanına bağlan", + "createIssue": "Sorun Oluştur", + "createWorkspaceIn": "Çalışma Alanı İçin Repo", + "description": "Açıklama", + "descriptionPlaceholder": "Bağlam ekleyin", + "fileIn": "Oluşturulacağı yer: {{slug}}", + "issueSource": "Sorun kaynağı", + "keySecurityHint": "Anahtarınız, sunucunun işletim sistemi anahtar zinciriyle şifrelenir ve yerel olarak saklanır.", + "linearConnectSubtitle": "Bu çalışma alanındaki sorunlara göz atmak için bir kişisel API anahtarı yapıştırın.", + "linearSettingsLink": "Linear Settings / Security / New API key", + "linearTeam": "Linear Takımı", + "linearTeamSubtitle": "Seçili Linear takımında bir sorun oluşturun.", + "newIssueTitle": "Yeni {{providerLabel}} Sorunu", + "origin": "Origin", + "personalApiKey": "Kişisel API anahtarı", + "repository": "Repository", + "repositorySubtitle": "Seçili repository'de bir sorun oluşturun.", + "team": "Takım", + "title": "Başlık", + "titlePlaceholder": "Görev başlığı", + "upstream": "Upstream" + }, + "workspaceAgentSelection": { + "blankTerminal": "Boş Terminal" + }, + "workspaceCreateDrawer": { + "addRepository": "Linear çalışma alanı oluşturmadan önce bir Git repository'si ekleyin.", + "advanced": "Gelişmiş", + "agent": "Ajan", + "connect": "Bağlan", + "connectFirst": "Önce repository'ye bağlanın", + "connectRepository": "Repository'ye Bağlan", + "connecting": "Bağlanıyor…", + "createFrom": "{{branch}} branch'inden oluştur", + "defaultBranch": "Varsayılan branch", + "detectingAgents": "Ajanlar algılanıyor…", + "optional": "[İsteğe bağlı]", + "remoteRepository": "Uzak repository", + "repository": "Repository", + "repositoryNotFound": "Repository bulunamadı.", + "selectRepository": "Bir repository seçin", + "sshConnection": "SSH Bağlantısı", + "startFrom": "Başlangıç noktası", + "title": "Çalışma Alanı Oluştur", + "workspaceName": "Çalışma Alanı Adı" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "“{{name}}” zaten var.", + "nameRequired": "Ad gereklidir.", + "nameTooLong": "Ad en fazla 80 karakter olmalıdır.", + "openShell": "Bir kabuk aç" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "Mevcut bir branch veya ref seçin.", + "baseBranchTitle": "Başlangıç Noktası", + "branchName": "Branch adı: {{name}}", + "defaultBranch": "Varsayılan branch", + "defaultBranchSubtitle": "Bu repository için ayarlanan temel branch'i kullanın", + "editPreset": "{{name}} ön ayarını düzenle", + "fullCheckout": "Tam checkout", + "fullCheckoutSubtitle": "Repository'nin tamamını kullanın", + "newPreset": "Yeni ön ayar", + "noBranches": "Eşleşen branch yok.", + "searchBranches": "Branch'lerde ara", + "sparseCheckoutTitle": "Sparse Checkout" + }, + "workspaceSshGate": { + "authenticationFailed": "Kimlik doğrulanamadı", + "connected": "Bağlı", + "connecting": "Bağlanıyor", + "connectionFailed": "Bağlantı kurulamadı", + "deployingRelay": "Aktarıcı kuruluyor", + "disconnected": "Bağlantı kesildi", + "reconnectFailed": "Yeniden bağlanılamadı", + "reconnecting": "Yeniden bağlanılıyor" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "Her zaman güven ve çalıştır", + "creating": "Oluşturuluyor…", + "directoriesLabel": "Dizinler", + "directories_one": "{{count}} dizin", + "directories_other": "{{count}} dizin", + "dontRun": "Çalıştırma", + "editSparsePreset": "Sparse Ön Ayarını Düzenle", + "nameLabel": "Ad", + "namePlaceholder": "İşleyici Arayüzü", + "newSetupScript": "Yeni kurulum betiği", + "newSparsePreset": "Yeni Sparse Ön Ayarı", + "runHooks": "Hook'ları çalıştır", + "runSetupAndCreate": "Kurulumu çalıştır ve oluştur", + "runSetupTitle": "{{name}} içindeki kurulum çalıştırılsın mı?", + "setupChangedTitle": "{{name}} için kurulum betiği değişti", + "setupScript": "Kurulum betiği", + "setupSubtitle": "Bu çalışma alanını oluşturmadan önce {{name}} için bir kurulum seçeneği belirlemeniz gerekiyor.", + "setupTitle": "Kurulum Betiği Çalıştırılsın mı?", + "skipSetupAndCreate": "Kurulumu atla ve oluştur", + "trustFailed": "Kurulum betiği güvenilir olarak işaretlenemedi.", + "trustSubtitle": "Bu repository'nin orca.yaml dosyası, çalışma alanı başlamadan önce makinenizde çalıştırılır. Yalnızca bu repository'ye güveniyorsanız çalıştırın." + }, + "worktreeCreateRetry": { + "createFailed": "Çalışma alanı oluşturulamadı" } }, "terminal": { @@ -2753,11 +3590,11 @@ "hostWorkspaceListStates": { "checkHost": "Bilgisayarınızın uyanık ve Orca'nın çalışır durumda olduğunu kontrol edin", "empty": "Çalışma alanı yok", - "loadFailed": "Bu ana makineden çalışma alanları yüklenemedi", + "loadFailed": "Bu sunucudan çalışma alanları yüklenemedi", "noFilterMatches": "Filtrelerle eşleşen çalışma alanı yok", "noMatches": "Eşleşen çalışma alanı yok", "reopen": "Güncellemek için yeniden açın", - "reopenDetail": "Bu ana bilgisayar, çalışma alanlarını bu sayfanın henüz tanımadığı bir biçimde listeliyor.", + "reopenDetail": "Bu sunucu, çalışma alanlarını bu sayfanın henüz tanımadığı bir biçimde listeliyor.", "retrying": "worktree.ps tamamlanamadı ({{error}}) — otomatik olarak yeniden deneniyor" }, "workspaceListSections": { diff --git a/mobile/src/i18n/locales/zh-Hant.json b/mobile/src/i18n/locales/zh-Hant.json index 320981d35a8..98c88c84c0b 100644 --- a/mobile/src/i18n/locales/zh-Hant.json +++ b/mobile/src/i18n/locales/zh-Hant.json @@ -8,7 +8,7 @@ "hostNotFound": "找不到主機", "invalidSnapshot": "主機傳回的帳戶快照無效", "loadingAccounts": "正在載入帳戶…", - "manageAccountsHint": "請至電腦版的「設定」→「帳戶」,新增帳戶或重新驗證。", + "manageAccountsHint": "請至桌面版的「設定」→「帳戶」,新增帳戶或重新驗證。", "refreshAccounts": "重新整理帳戶", "sessionWindow": "5 小時", "switchFailed": "無法切換帳戶", @@ -117,12 +117,12 @@ "autocompleteOn": "開啟", "defaultText": "預設(100%)", "keepPhoneSize": "保持手機尺寸(預設)", - "keyboardInputDescription": "自動完成、自動修正和拼字建議僅適用於暫存指令輸入模式。點一下鍵盤上方的雙箭頭按鈕,從即時輸入切換至此模式,編輯好指令後再點「傳送」。預設為關閉,以免指令、旗標或路徑遭到改寫。", + "keyboardInputDescription": "自動完成、自動修正和拼字建議僅適用於緩衝命令輸入模式。點一下鍵盤上方的雙箭頭按鈕,從即時輸入切換至此模式,編輯好命令後再點「傳送」。預設為關閉,以免命令、旗標或路徑遭到改寫。", "keyboardInputHeading": "鍵盤輸入", "largeText": "大(125%)", "largerText": "較大(150%)", "largestText": "最大(200%)", - "leaveAppDescription": "在手機上使用終端機時,Orca 會將終端機縮小以符合螢幕大小。關閉 App 或切換到其他 App 時,此設定決定終端機要保持手機尺寸(避免互動式 CLI 工具重新排版),還是還原為電腦上的尺寸。你隨時都能使用電腦版橫幅上的「還原」手動調整尺寸。", + "leaveAppDescription": "在手機上使用終端機時,Orca 會將終端機縮小以符合螢幕大小。關閉 App 或切換到其他 App 時,此設定決定終端機要保持手機尺寸(避免互動式 CLI 工具重新排版),還是還原為電腦上的尺寸。您隨時都能使用桌面版橫幅上的「還原」手動調整尺寸。", "leaveAppHeading": "離開 App 時", "noPairedDesktops": "尚未配對任何電腦。配對一台電腦後,即可設定終端機行為。", "restoreAfterMinutes_one": "{{count}} 分鐘後", @@ -133,7 +133,7 @@ "smallerText": "較小(75%)", "smallestText": "最小(50%)", "textSize": "文字大小", - "textSizeDescription": "調整終端機文字大小。文字較小時可顯示更多欄,並保留兩側邊距;文字較大時顯示的欄數較少,可向左右拖曳來平移。你也可以直接在終端機中用雙指縮放,同時更新此設定。此設定僅影響此裝置的顯示,不會變更電腦上的終端機。", + "textSizeDescription": "調整終端機文字大小。文字較小時可顯示更多欄,並保留兩側邊距;文字較大時顯示的欄數較少,可向左右拖曳來平移。您也可以直接在終端機中用雙指縮放,同時更新此設定。此設定僅影響此裝置的顯示,不會變更電腦上的終端機。", "textSizeHeading": "文字大小", "textSizePickerTitle": "終端機文字大小", "title": "終端機" @@ -168,7 +168,7 @@ }, "chat": { "ask": { - "answerPlaceholder": "輸入你的回答", + "answerPlaceholder": "輸入您的回答", "next": "下一步", "other": "其他…", "skip": "跳過", @@ -281,7 +281,7 @@ "stoppedManually": "已手動停止" }, "orcaStop": { - "canContinue": "你可以在此對話中繼續。", + "canContinue": "您可以在此對話中繼續。", "crash": "此回覆進行期間,{{machine}} 上的 Orca 意外停止。", "quit": "此回覆進行期間,{{machine}} 上的 Orca 已關閉。", "remote": "此回覆進行期間,{{machine}} 上的 Orca 已停止。", @@ -303,7 +303,7 @@ }, "question": { "otherReplyPlaceholder": "或輸入回覆…", - "replyPlaceholder": "輸入你的回覆…", + "replyPlaceholder": "輸入您的回覆…", "sendReply": "傳送回覆", "submit": "送出", "submitCount": "送出({{count}})", @@ -678,8 +678,8 @@ "editFileNote": "編輯檔案備註", "hunk": "差異區塊", "nextHunk": "下一個差異區塊", - "notes_one": "{{count}} 則筆記", - "notes_other": "{{count}} 則筆記", + "notes_one": "{{count}} 則備註", + "notes_other": "{{count}} 則備註", "previousHunk": "上一個差異區塊", "reviewed": "已審查", "staged": "已暫存", @@ -707,7 +707,7 @@ "diffReviewHeader": { "filterAll": "全部", "filterBranch": "分支", - "filterNotes": "筆記", + "filterNotes": "備註", "filterStaged": "已暫存", "filterUnreviewed": "未審查", "filterUnstaged": "未暫存", @@ -716,7 +716,7 @@ "reviewedProgress": "已審查 {{reviewedCount}}/{{queueLength}}", "showAllFiles": "顯示所有審查檔案", "showBranchFiles": "顯示分支的審查檔案", - "showNotesFiles": "顯示有筆記的檔案", + "showNotesFiles": "顯示有備註的檔案", "showStagedFiles": "顯示已暫存的檔案", "showUnreviewedFiles": "顯示未審查的檔案", "showUnstagedFiles": "顯示未暫存的檔案", @@ -752,7 +752,7 @@ "pairingTemporarilyUnavailable": "配對暫時無法使用", "repairHint": "點一下以重新與電腦配對", "unlockHint": "解鎖手機後,點一下以重試", - "updateDesktopHint": "更新電腦版 Orca 並登入,即可隨時隨地連線", + "updateDesktopHint": "更新桌面版 Orca 並登入,即可隨時隨地連線", "worktreeAccessibilitySummary": "{{summary}},{{activeCount}} 個使用中" }, "hostDiagnosticsLink": { @@ -773,10 +773,10 @@ }, "jiraConnectPrompt": { "checkAgain": "再次檢查", - "connectHint": "在 Orca 電腦版的「設定 → 整合」中新增 Jira 網站,然後再次檢查。", + "connectHint": "在 Orca 桌面版的「設定 → 整合」中新增 Jira 網站,然後再次檢查。", "connectOnDesktop": "在電腦上連線至 Jira", "credentialUnreadable": "Jira 憑證已儲存,但無法讀取:{{credentialError}}", - "updateDesktop": "更新 Orca 電腦版" + "updateDesktop": "更新 Orca 桌面版" }, "markdownBlocks": { "copyCode": "複製程式碼", @@ -792,14 +792,14 @@ "hooks": "鉤子", "label": "設定指令碼", "run": "執行", - "runSetupCommand": "執行設定指令", + "runSetupCommand": "執行設定命令", "skip": "跳過" }, "newWorkspaceSshConnectionField": { "connect": "連線", "connecting": "連線中…", "label": "SSH 連線", - "serverRecovery": "需要從電腦版復原此伺服器:「設定」→「SSH 主機」→「復原伺服器」。" + "serverRecovery": "需要從桌面版復原此伺服器:「設定」→「SSH 主機」→「復原伺服器」。" }, "newWorktreeAgentSelection": { "blankTerminal": "空白終端機" @@ -854,7 +854,7 @@ "workspaceNeedsUpdateGitHubReleases": "此桌面版的行動版工作區需要較新版本的 Orca Mobile。請從 GitHub Releases 更新 Orca Mobile,再重新連線至此主機。" }, "richMarkdownEditor": { - "imageUrl": "影像網址", + "imageUrl": "圖片網址", "insert": "插入", "linkUrl": "連結網址" }, @@ -867,7 +867,7 @@ "heading1": "標題 1", "heading2": "標題 2", "heading3": "標題 3", - "image": "影像", + "image": "圖片", "inlineCode": "行內程式碼", "italic": "斜體", "link": "連結", @@ -895,7 +895,7 @@ "workspaceName": "工作區名稱" }, "smartWorkspaceSourceDrawer": { - "connectRepository": "請連接存放庫以搜尋來源。", + "connectRepository": "請連線至存放庫以搜尋來源。", "crossRepoMessage": "此項目位於 {{owner}}/{{repo}}。", "gitHubRemoteRequired": "此 SSH 存放庫需要 GitHub 遠端存放庫,才能列出議題和 PR。", "noResults": "找不到結果。", @@ -989,7 +989,7 @@ "disconnected": "已中斷連線", "hostFallback": "主機", "hostOffline": "{{host}} 已離線", - "hostOfflineDetail": "確認電腦已喚醒、Orca 正在執行,且你已登入", + "hostOfflineDetail": "確認電腦已喚醒、Orca 正在執行,且您已登入", "labelWithHint": "{{label}} — {{hint}}", "pairingInvalid": "配對已失效,請重新與電腦配對", "rePairDetail": "重新與電腦配對", @@ -1066,7 +1066,7 @@ }, "troubleshootCommonIssues": { "allowNotifications": "確認系統設定允許 Orca 傳送通知,且「專注模式」或「勿擾模式」已關閉。", - "checkTailnet": "確認電腦未進入睡眠,且在你的 tailnet 中顯示為已連線。", + "checkTailnet": "確認電腦未進入睡眠,且在您的 tailnet 中顯示為已連線。", "desktopTitle": "桌面版應用程式未執行", "disableVpn": "停用該 VPN,或啟用分割通道/「允許 LAN」。", "firewallTitle": "防火牆封鎖連接埠 6768", @@ -1181,13 +1181,13 @@ "fileExplorerPanel": { "backToSession": "返回工作階段", "closeFiles": "關閉檔案", - "connecting": "正在連線至桌面版…", + "connecting": "正在連線至電腦…", "emptyState": "找不到檔案", "loadFailed": "無法載入檔案", "loadInterrupted": "資料夾載入中斷", "title": "檔案", "truncatedList": "{{worktreeLabel}} - 僅顯示前 5000 筆", - "waiting": "正在等待桌面版…" + "waiting": "正在等待電腦…" }, "fileExplorerRow": { "fileUnavailable": "{{name}} 無法在行動版使用", @@ -1208,7 +1208,7 @@ "downloading": "正在下載 {{bytes}},共 {{total}}", "loadFailed": "無法載入媒體", "loading": "正在載入媒體…", - "waiting": "正在等待桌面版…" + "waiting": "正在等待電腦…" }, "fileMutationOwnership": { "sshOwnerChanged": "無法驗證 SSH 連線。請重新連線至主機後再試一次。" @@ -1247,7 +1247,7 @@ "saveFailed": "無法儲存檔案", "stay": "留在此頁", "title": "預覽", - "waiting": "正在等待桌面版…" + "waiting": "正在等待電腦…" }, "filePreviewSourceText": { "previewLabel": "檔案預覽", @@ -1280,7 +1280,7 @@ "updateHint": "點一下即可更新" }, "emptyState": { - "connectedDescription": "你的電腦會顯示在這裡。所有資料皆採端對端加密。", + "connectedDescription": "您的電腦會顯示在這裡。所有資料皆採端對端加密。", "connectedTitle": "已連線", "description": "與電腦上的 Orca 配對,即可用手機查看代理程式狀態、開啟任何終端機,並推進工作。", "openDesktopDescription": "前往「設定」→「行動版」,產生配對用的 QR Code。", @@ -1289,7 +1289,7 @@ "scanCodeDescription": "點一下上方按鈕開啟掃描器,對準電腦螢幕上的 QR Code。", "scanCodeTitle": "掃描 QR Code", "stepsHeading": "使用方式", - "title": "連線至你的電腦" + "title": "連線至您的電腦" }, "listFooter": { "hostPickerTitle": "選擇開啟任務的主機", @@ -1467,13 +1467,13 @@ "localWindows": "本機 Windows", "projectOrder": "專案排序", "projects": "專案", - "savingToDesktop": "正在儲存至電腦版", + "savingToDesktop": "正在儲存至電腦", "show": "顯示", "showProperties": "顯示屬性", "sortBy": "排序方式", - "syncedAcrossDevices": "已在你的裝置間同步", + "syncedAcrossDevices": "已在您的裝置間同步", "thisComputer": "本機", - "waitingForDesktop": "仍在等待電腦版回應", + "waitingForDesktop": "仍在等待電腦回應", "workspaceOptions": "工作區選項" } }, @@ -1491,7 +1491,21 @@ "workspace": "工作區" } }, + "newWorkspace": { + "hostPicker": { + "title": "選擇建立工作區的主機" + }, + "loadingDrawer": { + "downloadProgress": "正在下載… {{progress}}", + "downloading": "正在下載", + "loading": "載入中" + } + }, "notifications": { + "desktopChannel": { + "name": "桌面通知", + "silentName": "Orca 靜音通知" + }, "notificationDeliverySection": { "footer": "通知類型依各台已配對電腦的通知設定而定。若連續 7 天未使用此應用程式,通知將暫停;開啟應用程式並重新連線即可恢復。", "onlyWhenAway": "僅在離開電腦時", @@ -1503,20 +1517,20 @@ }, "onboarding": { "notificationOnboardingPreview": { - "claudeNeedsInput": "Claude 需要你的輸入", + "claudeNeedsInput": "Claude 需要您的輸入", "codexFinished": "Codex 已完成", "now": "現在", "testsPassing": "測試已通過。", - "waitingOnYou": "正在等待你回應。" + "waitingOnYou": "正在等待您回應。" }, "onboardingPage": { "enableAgentNotifications": "啟用代理程式通知", "enableNotifications": "啟用通知", "keepTerminal": "繼續使用終端機", "notNow": "暫時不要", - "notificationsDescription": "即使未使用應用程式,代理程式完成工作或等待你回應時,此手機也會收到通知。", - "notificationsDisclosure": "電腦閒置 3 分鐘後,便會透過 Orca 推播服務傳送通知。你隨時可在「設定」中變更。", - "notificationsTitle": "代理程式需要你時,別錯過通知", + "notificationsDescription": "即使未使用應用程式,代理程式完成工作或等待您回應時,此手機也會收到通知。", + "notificationsDisclosure": "電腦閒置 3 分鐘後,便會透過 Orca 推播服務傳送通知。您隨時可在「設定」中變更。", + "notificationsTitle": "代理程式需要您時,別錯過通知", "openInChatUi": "以聊天介面開啟工作階段", "openInTerminal": "在終端機中開啟工作階段", "sessionViewDescription": "選擇在此裝置上以終端機或聊天介面開啟支援此功能的代理程式工作階段。長按工作階段分頁可切換檢視方式,也可稍後在「設定」中變更預設值。", @@ -1544,7 +1558,7 @@ "noChecks": "無檢查", "openOnWeb": "在網頁上開啟 {{name}}", "passed": "{{count}} 項通過", - "pending": "等待中", + "pending": "待處理", "pendingCount": "{{count}} 項待處理", "queued": "已加入佇列", "rerunFailing": "重新執行失敗的檢查", @@ -1728,7 +1742,7 @@ "stateClosed": "已關閉", "stateDraft": "草稿", "stateMerged": "已合併", - "stateOpen": "開啟中", + "stateOpen": "開放", "unavailable": "無法取得檢查結果" }, "prCommentAudienceLabels": { @@ -1935,7 +1949,7 @@ "desktopUpdateRequired": "請更新 Orca 桌面版,以便在手機上審查變更。", "diffLoadFailed": "無法載入差異", "invalidSourceControlResponse": "原始碼控制回應無效", - "reviewNotesLoadFailed": "無法載入審查註記" + "reviewNotesLoadFailed": "無法載入審查備註" }, "diffReviewQueue": { "committedOnBranch": "已在分支上提交", @@ -1972,13 +1986,13 @@ "moreActions": "更多工作階段操作", "openFileExplorer": "開啟檔案總管", "openSourceControl": "開啟原始碼控制", - "reconnectToDesktop": "重新連線至桌面版", + "reconnectToDesktop": "重新連線至電腦", "showSidebar": "顯示側邊欄", "terminalTitle": "終端機" }, "headerMoreActionsSheet": { "agentHistory": "代理程式歷史紀錄", - "agentHistoryHint": "瀏覽並繼續代理程式工作階段", + "agentHistoryHint": "瀏覽並恢復代理程式工作階段", "checks": "檢查項目", "checksHint": "開啟 PR 檢查項目" }, @@ -2007,7 +2021,7 @@ "collapse": "收合" }, "nativeChatCliFork": { - "resumeInNewCli": "在新的 CLI 中繼續" + "resumeInNewCli": "在新的 CLI 中恢復" }, "nativeChatFloatingControls": { "scrollToLatest": "捲動至最新內容" @@ -2073,7 +2087,7 @@ "steerHint": "提交且不中斷模型" }, "queuedMessageComposer": { - "commandsNotAllowed": "無法將指令儲存在排隊中的訊息內。", + "commandsNotAllowed": "無法將命令儲存在排隊中的訊息內。", "editing": "正在編輯訊息", "editingAttributed": "正在編輯訊息 · {{attribution}}" }, @@ -2158,7 +2172,7 @@ "discard": "放棄", "discardAndLeave": "放棄並離開", "discardChanges": "放棄變更", - "discardMessage": "要以桌面版的最新檔案取代手機草稿嗎?", + "discardMessage": "要以電腦上的最新檔案取代手機草稿嗎?", "draftsHint": "離開前請先複製或放棄手機草稿。", "file": "檔案", "markdown": "Markdown", @@ -2199,7 +2213,7 @@ "terminalActionSheetActions": { "clearTerminal": "清除終端機", "rename": "重新命名", - "switchToDesktop": "切換為電腦模式", + "switchToDesktop": "切換為桌面模式", "switchToPhone": "切換為手機模式" }, "terminalInputActions": { @@ -2249,7 +2263,7 @@ "browserCreateFailed": "建立瀏覽器失敗", "browserUnavailable": "瀏覽器頁面尚未就緒。", "browserUpdateRequired": "需更新桌面版才能使用行動版瀏覽器串流", - "invalidUrl": "請輸入有效的 URL", + "invalidUrl": "請輸入有效的網址", "noteCreateFailed": "建立 Markdown 筆記失敗", "untitledNoteCreateFailed": "無法建立未命名的 Markdown 筆記" }, @@ -2260,7 +2274,7 @@ "notesCopied": "已複製備註", "saveNoteFailed": "儲存備註失敗", "saveNotesFailed": "儲存審查備註失敗", - "waitingForDesktop": "等待桌面版…" + "waitingForDesktop": "等待電腦…" }, "useDiffReviewCommentActions": { "saveFailed": "儲存審查失敗", @@ -2318,9 +2332,9 @@ "inserted": "已插入聽寫內容" }, "useNativeChatStop": { - "stopNotSent": "未送出停止指令", + "stopNotSent": "未送出停止命令", "stopUnconfirmed": "尚未確認是否已停止,請先查看聊天再重試", - "terminalNotReady": "未送出停止指令(終端機尚未就緒)" + "terminalNotReady": "未送出停止命令(終端機尚未就緒)" }, "usePanelRouteActions": { "checkHostHint": "請檢查主機連線", @@ -2334,13 +2348,13 @@ }, "usePrAiTriage": { "launchFailed": "啟動代理程式失敗", - "waitingForDesktop": "等待桌面版…" + "waitingForDesktop": "等待電腦…" }, "usePrCommentActions": { "actionFailed": "留言操作失敗" }, "usePrTitleAction": { - "disconnected": "尚未連線至桌面版。", + "disconnected": "尚未連線至電腦。", "updateFailed": "更新標題失敗。" }, "useQuickCommands": { @@ -2448,7 +2462,7 @@ "support": "支援" }, "nativeChatSettingsScreen": { - "defaultViewDescription": "選擇此裝置上受支援的代理程式工作階段(Claude、Codex 及其他支援聊天的代理程式)的開啟方式。「終端機」會顯示原始 CLI;「聊天介面」則提供類似電腦版的聊天介面。你仍可透過長按選單,切換個別工作階段的顯示方式。", + "defaultViewDescription": "選擇此裝置上受支援的代理程式工作階段(Claude、Codex 及其他支援聊天的代理程式)的開啟方式。「終端機」會顯示原始 CLI;「聊天介面」則提供類似桌面版的聊天介面。您仍可透過長按選單,切換個別工作階段的顯示方式。", "defaultViewHeading": "預設檢視", "off": "關閉", "on": "開啟", @@ -2478,7 +2492,7 @@ "updateDesktop": "請更新電腦上的 Orca,以執行此測試。" }, "notificationSettingsScreen": { - "description": "當代理程式需要你的回應或完成任務時,在此裝置上接收通知。", + "description": "當代理程式需要您的回應或完成任務時,在此裝置上接收通知。", "enableNotifications": "啟用通知", "loadFailed": "無法載入通知設定,請再試一次。", "notificationsBlocked": "系統設定已停用通知。", @@ -2520,11 +2534,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "沒有可供變基的基底分支", + "waitingForDesktop": "等待電腦…" + }, "actions": { + "checkingReviewStatus": "正在檢查審查狀態。", + "checkoutBeforePublish": "請先檢出分支再發布提交。", + "commitStagedChanges": "提交已暫存的變更。", "commits": "提交", + "committing": "正在提交。", "createPr": "建立 PR", + "enterCommitMessage": "請輸入提交訊息以進行提交。", + "forcePushWithLease": "使用租約強制推送,以更新遠端分支。", + "forcePushing": "正在強制推送。", + "linkedReviewUnavailable": "已連結的審查分支無法使用。", + "publishToOrigin": "將此分支發布至 origin。", + "pullCommits_one": "拉取 {{count}} 筆提交。", + "pullCommits_other": "拉取 {{count}} 筆提交。", "pushAndCreatePr": "推送並建立 PR", - "switchBranch": "切換分支" + "pushCommits_one": "推送 {{count}} 筆提交。", + "pushCommits_other": "推送 {{count}} 筆提交。", + "pushLinkedReview": "將更新推送至已連結的審查分支。", + "remoteOperationInProgress": "正在執行遠端操作。", + "resolveConflicts": "請先解決衝突再提交。", + "reviewAlreadyMerged": "沒有可提交的內容。審查已合併。", + "stageAllChanges": "暫存所有變更。", + "stageFileToCommit": "請至少暫存一個檔案再提交。", + "switchBranch": "切換分支", + "syncCounts": "拉取 {{behind}} 筆,推送 {{ahead}} 筆。", + "upToDate": "沒有可提交的內容。分支已是最新狀態。", + "waitForRemoteOperation": "請等待遠端操作完成後再試。" + }, + "branchBaseRef": { + "resolveFailed": "無法判定分支基準" + }, + "branchCard": { + "branchCount": "已提交 {{count}} 項", + "changedCount": "已變更 {{count}} 項", + "cherryPickState": "挑選", + "mergeState": "合併", + "rebaseState": "變基", + "stagedCount": "已暫存 {{count}} 項" + }, + "branchCompare": { + "commits_one": "{{count}} 筆提交", + "commits_other": "{{count}} 筆提交", + "files_one": "{{count}} 個檔案", + "files_other": "{{count}} 個檔案", + "sectionTitle": "已在分支上提交", + "summary": "{{files}} - 與 {{baseRef}} 比較", + "summaryWithCommits": "{{files}} - {{commits}} - 與 {{baseRef}} 比較" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "無法判定用於比較的基礎分支。", + "loadFailed": "無法載入已提交的變更" + }, + "branchDiffPreviewDrawer": { + "closePreview": "關閉已提交的差異預覽", + "committedOnBranch": "已在分支上提交", + "loadFailed": "無法載入差異", + "truncated": "行動版預覽的差異內容已截斷。" }, "commitDropdown": { "checkOutBranchToPush": "推送提交前請先檢出分支", @@ -2549,8 +2619,49 @@ "stageFile": "暫存至少一個要提交的檔案", "useCommitAndForcePush": "使用「提交並強制推送」;遠端只有本機提交的舊版本" }, + "commitFailurePanel": { + "fix": "修復", + "fixWithAi": "使用 AI 解決提交失敗的問題", + "hideDetails": "隱藏詳情", + "hideFailureDetails": "隱藏提交失敗詳情", + "showDetails": "顯示詳情", + "showFailureDetails": "顯示提交失敗詳情", + "summary": "提交失敗。", + "title": "提交失敗" + }, + "commitMessageAi": { + "generateFailed": "產生提交訊息失敗" + }, + "commitRunners": { + "actionFailed": "原始碼控制操作失敗", + "commitFailed": "提交失敗" + }, + "conflictAbort": { + "abortMerge": "中止合併", + "abortOperation": "中止 {{operation}}", + "abortRebase": "中止變基", + "aborting": "正在中止…" + }, + "content": { + "cancelGeneration": "取消產生提交訊息", + "commitMessageDisabled": "提交訊息已停用。沒有已暫存的檔案。", + "commitMessagePlaceholder": "提交訊息", + "emptyMessage": "工作樹沒有變更。", + "emptyTitle": "沒有本機變更", + "generateMessage": "使用 AI 產生提交訊息", + "noStagedFiles": "沒有已暫存的檔案", + "openActions": "開啟原始碼控制操作", + "reconnecting": "正在重新連線至電腦…", + "regenerateHint": "清除訊息以重新產生。", + "stageAll": "暫存全部", + "unstageAll": "全部取消暫存" + }, "createPrAction": { - "createReview": "建立 {{titleLabel}}" + "checkingStatus": "正在檢查審查狀態…", + "createPullRequest": "建立 PR", + "createReview": "建立 {{titleLabel}}", + "providerUnavailable": "此提供者無法建立審查", + "statusUnavailable": "無法取得審查狀態" }, "dropdownCounts": { "fastForwardCount_one": "快轉 {{count}} 筆提交", @@ -2572,6 +2683,64 @@ "titleUnpublishedForcePushCount_one": "使用租約強制推送此分支的 {{count}} 筆提交,並視需要設定上游分支。", "titleUnpublishedForcePushCount_other": "使用租約強制推送此分支的 {{count}} 筆提交,並視需要設定上游分支。" }, + "fileList": { + "committedSection": "已在分支上提交" + }, + "fileRows": { + "addedByThem": "對方已新增", + "addedByUs": "我方已新增", + "bothAdded": "雙方皆已新增", + "bothDeleted": "雙方皆已刪除", + "bothModified": "雙方皆已修改", + "committedSection": "已在分支上提交", + "committedUnavailable": "無法取得已提交的變更。", + "deletedByThem": "對方已刪除", + "deletedByUs": "我方已刪除", + "discardFile": "放棄 {{path}} 的變更", + "loadingCommitted": "正在載入已提交的變更…", + "openChangedFile": "開啟已變更的檔案 {{path}}", + "openCommittedChange": "開啟 {{path}} 的已提交變更", + "renamedFrom": "原為 {{path}}", + "stageFile": "暫存 {{path}}", + "unresolvedConflict": "未解決的衝突", + "unstageFile": "取消暫存 {{path}}" + }, + "gitHistory": { + "days_one": "{{count}} 天", + "days_other": "{{count}} 天", + "hours_one": "{{count}} 小時", + "hours_other": "{{count}} 小時", + "justNow": "剛剛", + "loadFailed": "載入提交記錄失敗", + "minutes_one": "{{count}} 分鐘", + "minutes_other": "{{count}} 分鐘", + "months_one": "{{count}} 個月", + "months_other": "{{count}} 個月", + "noCommitMessage": "(無提交訊息)", + "years_one": "{{count}} 年", + "years_other": "{{count}} 年" + }, + "gitHistoryList": { + "loadFailed": "無法載入歷史記錄", + "loadFilesFailed": "無法載入該次提交的檔案", + "noCommits": "沒有提交記錄。", + "noFileChanges": "沒有檔案變更", + "retryFiles": "重新載入提交的檔案", + "waitingForDesktop": "正在等待電腦…" + }, + "gitStatus": { + "changes": "變更", + "conflicts": "衝突", + "stagedChanges": "已暫存的變更" + }, + "header": { + "backToSession": "返回工作階段", + "close": "關閉原始碼控制", + "openNumberedPrWeb": "在瀏覽器中開啟 PR #{{number}}", + "openPrWeb": "在瀏覽器中開啟 PR", + "refresh": "重新整理原始碼控制", + "title": "原始碼控制" + }, "hostedReview": { "mrCopy": { "reviewLabel": "合併請求", @@ -2584,9 +2753,81 @@ "titleLabel": "PR" } }, + "hostedReviewCopy": { + "committingChanges": "正在提交變更…", + "creatingReview": "正在建立審查…", + "forcePushing": "正在使用租約強制推送…", + "generatingCommitMessage": "正在產生提交訊息…", + "publishingBranch": "正在發布分支…", + "pushingCommits": "正在推送提交…", + "stagingChanges": "正在暫存變更…", + "updatingBranch": "正在更新分支…" + }, "hostedReviewCreate": { "pushSucceeded": "推送成功,但建立 {{shortLabel}} 失敗:{{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "準備 PR 期間,分支已變更。", + "generateMessageFailed": "無法產生提交訊息。請在「原始碼控制」中新增提交訊息後再試一次。", + "resolveConflicts": "請先解決衝突,再建立 PR。", + "resolveOrStageChanges": "請先解決衝突或暫存變更,再建立 PR。", + "reviewCommitMessage": "請先檢查提交訊息,然後重試「建立 PR」。" + }, + "hostedReviewGitPreparation": { + "commitFailed": "提交失敗", + "refreshFailed": "無法重新整理原始碼控制", + "stageFailed": "暫存變更失敗", + "updateBranchFailed": "無法更新遠端分支。請重試「建立 PR」。" + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "使用租約強制推送失敗", + "publishFailed": "發布分支失敗", + "pushFailed": "推送提交失敗" + }, + "hostedReviewService": { + "createFailed": "建立 PR 失敗", + "pushBeforeCreateFailed": "推送失敗。請解決推送錯誤後再試一次。" + }, + "hubTab": { + "changes": "變更", + "commits": "提交", + "pullRequest": "PR" + }, + "loaders": { + "connectingToDesktop": "正在連線至電腦…", + "loadFailed": "無法載入原始碼控制", + "updateDesktop": "請更新 Orca 桌面版,才能在行動裝置上使用原始碼控制。", + "waitingForDesktop": "等待電腦…" + }, + "modals": { + "actionsTitle": "原始碼控制", + "currentBranch": "目前分支", + "discardButton": "放棄", + "discardConfirmMessage": "要放棄「{{path}}」的變更嗎?此操作無法復原。", + "discardTitle": "放棄變更", + "openPrMessage": "要在瀏覽器中開啟嗎?", + "openPrWithWarning": "要在瀏覽器中開啟嗎?\n\n{{warning}}", + "prCreatedTitle": "已建立 PR", + "switchBranchTitle": "切換分支" + }, + "openers": { + "openDiffFailed": "無法開啟差異", + "tabNotReady": "檔案已開啟,但分頁尚未就緒。請再試一次。", + "waitingForDesktop": "等待電腦…" + }, + "panel": { + "loadFailedTitle": "無法載入", + "unavailableTitle": "無法使用原始碼控制" + }, + "prChip": { + "createPr": "建立 PR", + "loading": "正在載入 PR…", + "loadingLabel": "正在載入 PR", + "openLabel": "PR #{{number}},{{state}},{{checks}}。開啟 PR。", + "openWithComments_one": "PR #{{number}},{{state}},{{checks}},有 {{count}} 則未解決的留言。開啟 PR。", + "openWithComments_other": "PR #{{number}},{{state}},{{checks}},有 {{count}} 則未解決的留言。開啟 PR。", + "unavailableLabel": "無法取得 PR:{{message}}" + }, "prCreate": { "authRequired": "請在建立 {{reviewLabel}} 之前完成身分驗證。", "baseNotOnRemote": "建立 {{reviewLabel}} 前,請先推送基準分支。", @@ -2605,8 +2846,19 @@ "unsupportedMergeRequests": "此存放庫不支援建立合併請求。", "unsupportedPullRequests": "此存放庫不支援建立 PR。" }, + "prLink": { + "updatePullRequestFailed": "更新 PR 連結失敗", + "updateReviewFailed": "更新審查連結失敗" + }, "primaryAction": { - "forcePushFromDesktop": "從桌面版強制推送此 PR 的分支" + "commit": "提交", + "forcePush": "強制推送", + "forcePushFromDesktop": "從桌面版強制推送此 PR 的分支", + "publishBranch": "發布分支", + "pull": "拉取", + "push": "推送", + "stageAll": "暫存全部", + "sync": "同步" }, "remoteDropdown": { "branchAlreadyPublished": "分支已發布", @@ -2646,7 +2898,7 @@ "push": "推送", "pushAndSetUpstream": "推送此分支,並視需要設定上游分支", "pushMayNeedSync": "推送本機提交;git 可能要求先同步", - "pushToLinkedReview": "將更新推送到已關聯的審查分支", + "pushToLinkedReview": "將更新推送到已連結的審查分支", "rebaseChooseRemoteBase": "選擇要作為變基基準的遠端分支", "rebaseDirtyHint": "嘗試變基;git 可能要求先提交或儲藏本機變更", "rebaseFromBase": "以基準分支進行變基", @@ -2656,6 +2908,591 @@ "tryFastForwardPull": "嘗試以快轉方式拉取;git 可能因本機提交而拒絕拉取", "tryRegularPush": "嘗試一般推送;git 可能要求強制推送", "useForcePushToSync": "使用「強制推送」;遠端只有本機提交的舊版本" + }, + "runners": { + "actionFailed": "原始碼控制操作失敗" + }, + "screenState": { + "noBranch": "無分支" + }, + "state": { + "noUpstream": "無上游分支", + "syncStatus": "領先 {{ahead}} 個提交,落後 {{behind}} 個提交" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "無法啟動代理程式", + "waitingForDesktop": "等待電腦…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "無法產生提交訊息" + }, + "useMobileCreatePrRunner": { + "branchRequired": "建立 PR 前,請先檢出分支。" + }, + "useMobileGitRequests": { + "actionFailed": "原始碼控制操作失敗", + "branchUnavailable": "無法取得分支狀態", + "commitFailed": "提交失敗", + "waitingForDesktop": "等待電腦…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "無法解析基礎分支。", + "forkPushWarning": "此 PR 未啟用「允許維護者編輯」;推送至分叉存放庫可能會遭 GitHub 拒絕。" + }, + "detailCommentRenderers": { + "commentPlaceholder": "新增留言", + "comments_one": "{{count}} 則留言", + "comments_other": "{{count}} 則留言", + "reopenThread": "重新開啟討論串", + "reply": "回覆", + "resolveThread": "標記為已解決", + "resolvedCommentBy": "{{author}} 的留言(已解決)", + "resolvedThreadBy": "{{author}} 的討論串(已解決)", + "sendComment": "傳送留言", + "show": "顯示" + }, + "filterPickers": { + "allTeams": "所有團隊", + "changeStatus": "更改狀態", + "fieldHidden": "不顯示於卡片", + "fieldShown": "顯示於卡片", + "fieldsSubtitle": "選擇要在項目卡片上顯示的專案欄位。", + "fieldsTitle": "專案欄位", + "gitlabFilter": "GitLab 篩選", + "gitlabView": "GitLab 檢視", + "jiraFilter": "Jira 篩選", + "jiraSite": "Jira 網站", + "linearFilter": "Linear 篩選", + "linearIssue": "Linear 議題", + "linearWorkspace": "Linear 工作區", + "loadingStates": "正在載入狀態…", + "noFields": "此檢視沒有其他可顯示的欄位。", + "noStates": "沒有可用的狀態", + "switchWorkspaceFailed": "無法切換工作區", + "teamsSubtitle": "選擇要在「任務」中顯示的團隊。", + "teamsTitle": "Linear 團隊", + "teams_one": "{{count}} 個團隊", + "teams_other": "{{count}} 個團隊" + }, + "githubProjectList": { + "browseProjects": "瀏覽專案", + "chooseProject": "選擇 GitHub 專案", + "emptyField": "空白", + "issueSubtitle": "議題 · {{repository}}{{number}}", + "itemSubtitle": "專案項目 · {{repository}}{{number}}", + "items": "項目", + "moreFields_one": "+{{count}} 個欄位", + "moreFields_other": "+{{count}} 個欄位", + "noItems": "沒有專案項目", + "pullRequestSubtitle": "PR · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "新增", + "addByUrlHint": "透過 URL 新增未列出的專案。", + "addPlaceholder": "透過 URL 或擁有者/編號新增", + "adding": "正在新增…", + "browseAll": "瀏覽全部", + "browseLoading": "瀏覽全部(載入中…)", + "chooseView": "選擇專案檢視", + "loadFailed": "無法載入專案", + "noMatches": "沒有符合的專案。", + "noMoreProjects": "沒有更多專案。", + "noProjects": "尚未載入任何專案", + "organizationsError": "組織:{{message}}", + "organizationsLoadFailed": "部分組織未能載入({{count}} 個)。", + "ownerLoadFailed": "無法載入 {{owner}} 的專案。", + "pin": "固定", + "pinned": "已固定", + "recent": "最近的", + "retryHint": "點一下以重試。", + "searchProjects": "搜尋專案", + "sort": "專案排序", + "subtitle": "選擇要在「任務」頁面使用的專案檢視。", + "title": "GitHub 專案", + "unsupportedLayout": "Orca 尚不支援此 GitHub 專案版面配置。", + "view": "專案檢視" + }, + "githubViewControls": { + "fields": "欄位:{{fields}}", + "openView": "在 GitHub 中開啟檢視", + "sort": "排序:{{sort}}", + "source": "來源:{{source}}" + }, + "itemActions": { + "changeStatus": "更改狀態", + "copyGitHubLink": "複製 GitHub 連結", + "copyLinearLink": "複製 Linear 連結", + "createWorkspace": "建立工作區", + "creating": "建立中…", + "mergeConflicts": "GitHub 回報有合併衝突。", + "mergeMergeRequest": "合併 MR", + "mergePullRequest": "合併 PR" + }, + "itemDetailContent": { + "addSubIssue": "新增子議題", + "assignee": "負責人", + "assignees": "負責人", + "checks": "檢查項目", + "description": "描述", + "discussion": "討論", + "noChecks": "找不到檢查項目。", + "noComments": "沒有留言。", + "noPipelineRuns": "此 MR 沒有管線執行紀錄。", + "noSubIssues": "沒有子議題。", + "none": "無", + "pipeline": "管線", + "pipelineJobs_one": "{{count}} 項作業", + "pipelineJobs_other": "{{count}} 項作業", + "project": "專案", + "rerunAll": "全部重新執行", + "rerunFailed": "重新執行失敗項目", + "status": "狀態", + "subIssueTitle": "子議題標題", + "subIssues": "子議題", + "type": "類型" + }, + "itemDetailDrawer": { + "refreshDetails": "重新整理詳細資訊" + }, + "itemFieldEditors": { + "addLabels": "新增標籤,以逗號分隔", + "addUsernames": "新增使用者名稱,以逗號分隔", + "assignees": "負責人", + "labels": "標籤", + "loadingAssignees": "正在載入負責人…", + "loadingLabels": "正在載入標籤…", + "noAssignableUsers": "找不到此存放庫可指派的使用者。", + "noLabels": "此存放庫沒有標籤。", + "none": "無", + "removeLabels": "移除標籤,以逗號分隔", + "removeUsernames": "移除使用者名稱,以逗號分隔", + "saveTitle": "儲存標題", + "title": "標題", + "updateAssignees": "更新負責人", + "updateLabels": "更新標籤" + }, + "itemReviewSections": { + "binaryFile": "二進位檔案。", + "changedFilesTitle": "已變更檔案", + "descriptionPlaceholder": "描述", + "fileContentsUnavailable": "無法取得檔案內容。", + "hideFile": "隱藏", + "loadingReviewers": "正在載入審查人…", + "markUnviewed": "標記未檢視", + "markViewed": "標記已檢視", + "noDescription": "沒有描述。", + "noReviewerSuggestions": "找不到建議的審查人。", + "noReviewersRequested": "尚未邀請審查人。", + "requestReview": "請求審查", + "reviewersPlaceholder": "邀請審查人", + "reviewersTitle": "審查人", + "saveDescription": "儲存描述", + "viewFile": "檢視" + }, + "legacySurface": { + "loadIssuesFailed": "無法從 {{source}} 載入議題。", + "mergeAction": "合併", + "mergeMethodTitle": "合併方式", + "mergePullRequestTitle": "合併 PR", + "mergeRequestMergeMessage": "選擇此合併請求的合併方式。", + "mergeRequestTitle": "合併請求", + "pullRequestMergeMessage": "選擇此 PR 的合併方式。", + "retryLoadingIssues": "重新嘗試從 {{source}} 載入議題", + "retrying": "正在重試…", + "sourceFallback": "{{repo}} 的偏好議題來源 upstream 無法使用,已改用 origin。", + "subIssueDataUnavailable": "您的權杖無法取得子議題資料。", + "updateItemTitle": "更新項目" + }, + "linearList": { + "changeStatusFrom": "變更狀態(目前為 {{status}})" + }, + "linearViewControls": { + "displayButton": "顯示", + "groupLabel": "分組:{{group}}", + "orderLabel": "排序:{{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "顯示屬性", + "linearGroupTitle": "Linear 議題分組", + "linearOrderTitle": "Linear 議題排序", + "linearViewTitle": "Linear 檢視", + "sortTasksTitle": "任務排序" + }, + "listSurface": { + "connectLinearButton": "連線 Linear", + "connectLinearMessage": "直接從「任務」瀏覽並開始處理指派給您的 Linear 議題。", + "connectLinearTitle": "連線您的 Linear 帳戶", + "jiraStatusFailed": "無法讀取 Jira 狀態", + "updateDesktopMessage": "此行動版「任務」檢視需要較新版的桌面執行環境。", + "updateDesktopTitle": "更新 Orca 桌面版" + }, + "options": { + "all": "全部", + "assignedToMe": "指派給我", + "assignee": "負責人", + "board": "看板", + "boardDescription": "依群組分欄", + "closedState": "已關閉", + "completedState": "已完成", + "createdState": "由我建立", + "githubAssignedIssuesDescription": "尚未關閉且指派給您的議題", + "githubDescription": "議題與 PR", + "githubIssuesDescription": "GitHub 議題", + "githubOpenIssuesDescription": "尚未關閉的 GitHub 議題", + "githubProjectsDescription": "GitHub Projects 檢視", + "githubPullRequestsDescription": "GitHub PR", + "gitlabAllDescription": "所有 GitLab 狀態", + "gitlabClosedDescription": "已關閉的議題與合併請求", + "gitlabDescription": "議題與合併請求", + "gitlabMergedDescription": "已合併的合併請求", + "gitlabOpenDescription": "開放的議題與合併請求", + "identifier": "識別符號", + "issues": "議題", + "jiraDescription": "已指派及已回報的議題", + "labels": "標籤", + "linearAllDescription": "已連線工作區中的開放議題", + "linearAssignedDescription": "指派給您的議題", + "linearCompletedDescription": "最近完成的議題", + "linearCreatedDescription": "由您建立的議題", + "linearDescription": "已指派的議題與團隊議題", + "list": "清單", + "listDescription": "精簡的議題列", + "mergedState": "已合併", + "mine": "我的", + "myIssues": "我的議題", + "myPullRequestsDescription": "您建立的 PR", + "myTodos": "我的待辦事項", + "myTodosDescription": "待處理的 GitLab 待辦事項", + "needsReview": "待審查", + "noGrouping": "沒有分組", + "openPullRequestsDescription": "尚未關閉的 PR", + "openState": "開放", + "priority": "優先等級", + "projectMergeRequests": "專案 MR", + "projectMergeRequestsDescription": "依存放庫顯示合併請求與議題", + "projects": "專案", + "pullRequests": "PR", + "repository": "存放庫", + "repositorySortDescription": "依存放庫分組,再依活動時間由新到舊排序", + "reviewRequestsDescription": "指派給您的審查請求", + "status": "狀態", + "team": "團隊", + "updated": "更新時間", + "updatedSortDescription": "最新活動優先" + }, + "pickerProjection": { + "allRepos": "所有存放庫", + "allSites": "所有網站", + "currentlyAscending": "目前遞增 · 點一下改為遞減", + "currentlyDescending": "目前遞減 · 點一下改為遞增", + "fieldAscending": "{{field}} 遞增", + "fieldDescending": "{{field}} 遞減", + "fields": "欄位", + "repos_one": "{{count}} 個存放庫", + "repos_other": "{{count}} 個存放庫", + "selectTarget": "選擇目標", + "selectedFields": "{{selected}}/{{total}} 個欄位", + "sortAscending": "遞增排序", + "sources_one": "{{count}} 來源", + "sources_other": "{{count}} 來源", + "unsupportedLayout": "行動版不支援此版面配置", + "updatedSort": "更新時間", + "usesFieldAscending": "依 {{field}} 遞增排序", + "usesFieldDescending": "依 {{field}} 遞減排序", + "usesGitHubRankOrder": "依 GitHub 中的項目順序排列", + "viewNumber": "檢視 #{{number}}", + "viewOrder": "檢視順序" + }, + "prFileDiff": { + "commentOnLine": "在第 {{line}} 行留言", + "commentPlaceholder": "新增審查留言", + "noTextChanges": "找不到文字變更。", + "showingDiffLines": "顯示前 {{limit}} 行差異,共 {{total}} 行。" + }, + "projectComments": { + "comments_one": "{{count}} 則留言", + "comments_other": "{{count}} 則留言", + "discussion": "討論", + "editComment": "編輯留言", + "noComments": "沒有留言。", + "reopenThread": "重新開啟討論串", + "reply": "回覆", + "resolveThread": "將討論串標為已解決", + "resolvedCommentBy": "{{author}} 的留言(已解決)", + "resolvedThreadBy": "{{author}} 的討論串(已解決)", + "show": "顯示" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} 尚未新增至 Orca。請先從桌面版應用程式新增此存放庫,再重新整理行動版的「任務」頁面。", + "clearType": "清除類型", + "closeItem": "關閉項目", + "copyGitHubLink": "複製 GitHub 連結", + "copyRepository": "複製存放庫名稱", + "createWorkspace": "建立工作區", + "draftIssue": "草稿議題", + "issue": "議題", + "issueType": "議題類型", + "loadingIssueTypes": "正在載入議題類型…", + "mergePullRequest": "合併 PR", + "mergeRepositoryRequirement": "必須先將此存放庫新增至 Orca,才能合併。", + "noIssueTypes": "此存放庫尚未設定議題類型。", + "noType": "無類型", + "openInGitHub": "在 GitHub 中開啟", + "projectItem": "專案項目", + "projectSubtitle": "GitHub 專案 · {{repository}}{{itemNumber}}", + "pullRequest": "PR", + "reopenItem": "重新開啟項目", + "repositoryNotInOrca": "存放庫不在 Orca 中", + "status": "狀態", + "type": "類型", + "workspaceCreationRequirement": "僅能從 GitHub 議題和 PR 建立工作區。" + }, + "projectFieldEditors": { + "clearField": "清除欄位", + "completedIteration": "已完成 · {{startDate}} · {{duration}} 天", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "請以 YYYY-MM-DD 格式輸入日期。", + "invalidNumber": "請輸入有效的數字。", + "noIterations": "沒有可用的迭代。", + "numberPlaceholder": "數字", + "projectFields": "專案欄位", + "saveField": "儲存欄位", + "textPlaceholder": "文字", + "upcomingIteration": "目前與即將開始 · {{startDate}} · {{duration}} 天" + }, + "projectMetadataEditors": { + "assignees": "負責人", + "description": "描述", + "labels": "標籤", + "loadingAssignees": "正在載入負責人…", + "loadingLabels": "正在載入標籤…", + "noAssignableUsers": "此存放庫沒有可指派的使用者。", + "noDescription": "沒有描述。", + "noLabels": "此存放庫沒有標籤。", + "none": "無", + "saveDescription": "儲存描述", + "saveTitle": "儲存標題", + "title": "標題" + }, + "projectReviewPanels": { + "binaryFile": "二進位檔案。", + "changedFiles": "已變更檔案", + "checks": "檢查項目", + "fileUnavailable": "無法取得檔案內容。", + "hideFile": "隱藏", + "loadingReviewers": "正在載入審查人…", + "markUnviewed": "標記未檢視", + "markViewed": "標記已檢視", + "noChecks": "找不到檢查項目。", + "noReviewers": "尚未邀請審查人。", + "noSuggestions": "找不到建議的審查人。", + "requestReview": "請求審查", + "requestReviewers": "邀請審查人", + "rerunAll": "全部重新執行", + "rerunFailed": "重新執行失敗項目", + "reviewers": "審查人", + "viewFile": "檢視" + }, + "providerControls": { + "myTodos": "我的待辦事項", + "projectMergeRequests": "專案 MR", + "sort": "排序:{{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "合併至 {{base}}", + "nextPage": "前往下一頁", + "page": "第 {{page}} 頁", + "pageOfTotal": "第 {{page}} 頁,共 {{total}} 頁", + "previousPage": "前往上一頁", + "selectPage": "選擇頁面,第 {{page}} 頁", + "selectPageOfTotal": "選擇頁面,第 {{page}} 頁,共 {{total}} 頁" + }, + "providerPickers": { + "allRepositories": "所有存放庫", + "githubView": "GitHub 檢視", + "issueSources": "GitHub 議題來源", + "issueSourcesDescription": "為各存放庫選擇查詢及建立工作的來源:upstream 或 origin。", + "issues": "議題", + "noIssueSources": "沒有其他可用的議題來源。", + "origin": "origin", + "pageHint": "跳至已載入或可載入的結果頁面。", + "pageLoaded": "已載入", + "pageNotLoaded": "載入較舊的結果", + "pageNumber": "第 {{page}} 頁", + "pages": "GitHub 結果頁", + "pullRequests": "PR", + "queryingSource": "正在查詢 {{source}}", + "repoDescription": "選擇要查詢的存放庫。", + "repos": "存放庫", + "taskSource": "任務來源", + "upstream": "上游" + }, + "providerViewProjection": { + "all": "全部", + "allSites": "所有網站", + "allTeams": "所有團隊", + "allWorkspaces": "所有工作區", + "chooseProject": "選擇專案", + "default": "預設", + "defaultSubtitle": "{{subtitle}} · 預設", + "issues": "議題", + "list": "清單", + "noGrouping": "沒有分組", + "openState": "開放", + "priority": "優先等級", + "projects": "專案", + "pullRequests": "PR", + "teams_one": "{{count}} 個團隊", + "teams_other": "{{count}} 個團隊", + "workspace": "工作區" + }, + "reviewerLinear": { + "issues": "議題", + "unassigned": "未指派" + }, + "screenChrome": { + "connectLinear": "連線 Linear", + "newGitHubIssue": "新增 GitHub 議題", + "newLinearIssue": "新增 Linear 議題", + "refreshGitHub": "重新整理 GitHub 工作", + "refreshGitLab": "重新整理 GitLab 工作項", + "refreshJira": "重新整理 Jira 議題", + "refreshLinear": "重新整理 Linear", + "title": "任務" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL,例如 project = ABC AND statusCategory != Done", + "projectPlaceholder": "在專案檢視中搜尋…", + "providerPlaceholder": "搜尋 {{provider}} 任務…" + }, + "smartSourceModes": { + "allStates": "全部", + "branch": "分支", + "closedState": "已關閉", + "mergedState": "已合併", + "name": "名稱", + "openState": "開放", + "smart": "智慧" + }, + "sparsePresetDraft": { + "directoryRequired": "新增至少一個目錄。", + "repoRelativeDirectoriesRequired": "使用相對於存放庫的目錄,而不是根目錄、絕對路徑或上層目錄路徑片段。" + }, + "taskViewOptions": { + "allSubtitle": "所選網站中的未解決議題", + "assignedSubtitle": "指派給您的未解決議題", + "doneSubtitle": "指派給您且最近已解決的議題", + "noGitHubTasks": "沒有 GitHub 任務", + "noGitLabTasks": "沒有 GitLab 任務", + "noJiraTasks": "沒有 Jira 任務", + "noLinearTasks": "沒有 Linear 任務", + "reportedSubtitle": "您回報的未解決議題" + }, + "tasksCreateDrawers": { + "connect": "連線", + "connectLinearWorkspace": "連線至 Linear 工作區", + "createIssue": "建立議題", + "createWorkspaceIn": "選擇建立工作區的存放庫", + "description": "描述", + "descriptionPlaceholder": "補充上下文", + "fileIn": "在 {{slug}} 建立議題", + "issueSource": "議題來源", + "keySecurityHint": "您的金鑰會透過主機作業系統的鑰匙圈加密,並儲存於本機。", + "linearConnectSubtitle": "貼上個人 API 金鑰,即可瀏覽該工作區的議題。", + "linearSettingsLink": "Linear 設定 / 安全性 / 新增 API 金鑰", + "linearTeam": "Linear 團隊", + "linearTeamSubtitle": "在所選 Linear 團隊中建立議題。", + "newIssueTitle": "新增 {{providerLabel}} 議題", + "origin": "origin", + "personalApiKey": "個人 API 金鑰", + "repository": "存放庫", + "repositorySubtitle": "在所選存放庫中建立議題。", + "team": "團隊", + "title": "標題", + "titlePlaceholder": "任務標題", + "upstream": "上游" + }, + "workspaceAgentSelection": { + "blankTerminal": "空白終端機" + }, + "workspaceCreateDrawer": { + "addRepository": "請先新增 Git 存放庫,再建立 Linear 工作區。", + "advanced": "進階", + "agent": "代理程式", + "connect": "連線", + "connectFirst": "請先連線存放庫", + "connectRepository": "連線存放庫", + "connecting": "正在連線…", + "createFrom": "從 {{branch}} 建立", + "defaultBranch": "預設分支", + "detectingAgents": "正在偵測代理程式…", + "optional": "[可選]", + "remoteRepository": "遠端存放庫", + "repository": "存放庫", + "repositoryNotFound": "找不到存放庫。", + "selectRepository": "選擇存放庫", + "sshConnection": "SSH 連線", + "startFrom": "起始來源", + "title": "建立工作區", + "workspaceName": "工作區名稱" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "「{{name}}」已存在。", + "nameRequired": "請輸入名稱。", + "nameTooLong": "名稱不能超過 80 個字元。", + "openShell": "開啟殼層" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "選擇現有的分支或參照。", + "baseBranchTitle": "起始來源", + "branchName": "分支名稱:{{name}}", + "defaultBranch": "預設分支", + "defaultBranchSubtitle": "使用此存放庫設定的基礎分支", + "editPreset": "編輯 {{name}}", + "fullCheckout": "完整檢出", + "fullCheckoutSubtitle": "使用整個存放庫", + "newPreset": "新預設", + "noBranches": "沒有符合的分支。", + "searchBranches": "搜尋分支", + "sparseCheckoutTitle": "稀疏檢出" + }, + "workspaceSshGate": { + "authenticationFailed": "身分驗證失敗", + "connected": "已連線", + "connecting": "連線中", + "connectionFailed": "連線失敗", + "deployingRelay": "正在部署中繼", + "disconnected": "已中斷連線", + "reconnectFailed": "重新連線失敗", + "reconnecting": "重新連線中" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "一律信任並執行", + "creating": "建立中…", + "directoriesLabel": "目錄", + "directories_one": "{{count}} 個目錄", + "directories_other": "{{count}} 個目錄", + "dontRun": "不執行", + "editSparsePreset": "編輯稀疏預設", + "nameLabel": "名稱", + "namePlaceholder": "算繪器介面", + "newSetupScript": "新的設定指令碼", + "newSparsePreset": "新增稀疏預設", + "runHooks": "執行鉤子", + "runSetupAndCreate": "執行設定並建立", + "runSetupTitle": "要執行 {{name}} 的設定指令碼嗎?", + "setupChangedTitle": "{{name}} 的設定指令碼已變更", + "setupScript": "設定指令碼", + "setupSubtitle": "建立此工作區前,請先選擇是否為 {{name}} 執行設定。", + "setupTitle": "要執行設定指令碼嗎?", + "skipSetupAndCreate": "略過設定並建立", + "trustFailed": "無法將設定指令碼設為信任。", + "trustSubtitle": "此存放庫的 orca.yaml 會在工作區啟動前於您的電腦上執行。請僅在信任此存放庫時執行。" + }, + "worktreeCreateRetry": { + "createFailed": "建立工作區失敗" } }, "terminal": { diff --git a/mobile/src/i18n/locales/zh.json b/mobile/src/i18n/locales/zh.json index 5c9719c1e87..2e2d3583d3b 100644 --- a/mobile/src/i18n/locales/zh.json +++ b/mobile/src/i18n/locales/zh.json @@ -13,7 +13,7 @@ "sessionWindow": "5小时", "switchFailed": "无法切换账户", "title": "账户", - "useReset": "使用重置机会", + "useReset": "使用重置额度", "weeklyWindow": "7天" } }, @@ -168,7 +168,7 @@ }, "chat": { "ask": { - "answerPlaceholder": "输入你的回答", + "answerPlaceholder": "输入您的回答", "next": "下一步", "other": "其他…", "skip": "跳过", @@ -281,7 +281,7 @@ "stoppedManually": "已手动停止" }, "orcaStop": { - "canContinue": "你可以在此对话中继续。", + "canContinue": "您可以在此对话中继续。", "crash": "此回复进行期间,{{machine}} 上的 Orca 意外停止。", "quit": "此回复进行期间,{{machine}} 上的 Orca 已关闭。", "remote": "此回复进行期间,{{machine}} 上的 Orca 已停止。", @@ -834,7 +834,7 @@ "loadFailed": "发生错误。", "loading": "正在加载 PR…", "notPermitted": "无权访问:您的 GitHub 账户尚未连接。", - "retryLoading": "重新加载 PR" + "retryLoading": "重试加载 PR" }, "protocolBlockScreen": { "backToHosts": "返回主机列表", @@ -1491,7 +1491,21 @@ "workspace": "工作区" } }, + "newWorkspace": { + "hostPicker": { + "title": "选择创建工作区的主机" + }, + "loadingDrawer": { + "downloadProgress": "正在下载… {{progress}}", + "downloading": "正在下载", + "loading": "加载中" + } + }, "notifications": { + "desktopChannel": { + "name": "桌面通知", + "silentName": "Orca 静默通知" + }, "notificationDeliverySection": { "footer": "提醒类型遵循各个已配对桌面的通知设置。连续 7 天未使用此应用后,通知将暂停;打开应用并重新连接即可恢复。", "onlyWhenAway": "仅在离开桌面时", @@ -1545,7 +1559,7 @@ "openOnWeb": "在网页上打开 {{name}}", "passed": "{{count}} 项通过", "pending": "待处理", - "pendingCount": "{{count}} 项待完成", + "pendingCount": "{{count}} 项待处理", "queued": "已加入队列", "rerunFailing": "重新运行失败的检查", "skipped": "已跳过", @@ -1948,14 +1962,14 @@ "unstaged": "未暂存" }, "fileReader": { - "copyReviewNotes": "复制评论注释", + "copyReviewNotes": "复制评审备注", "imageLabel": "{{title}} 图片", - "noReviewNotes": "暂无评论注释", + "noReviewNotes": "暂无评审备注", "previewLabel": "{{title}} 预览", - "reviewNotes_one": "{{count}} 条评论注释", - "reviewNotes_other": "{{count}} 条评论注释", + "reviewNotes_one": "{{count}} 条评审备注", + "reviewNotes_other": "{{count}} 条评审备注", "send": "发送", - "sendReviewNotes": "将评论注释发送给 AI" + "sendReviewNotes": "将评审备注发送给 AI" }, "floatingWorkspace": { "title": "浮动工作区" @@ -2169,7 +2183,7 @@ "notesHint": "选择接收当前注释的智能体会话。", "removeShortcutMessage": "移除此自定义快捷键?", "renameTerminal": "重命名终端", - "sendReviewNotes": "发送评论注释", + "sendReviewNotes": "发送评审备注", "shortcut": "快捷键", "terminal": "终端", "terminalName": "终端名称", @@ -2293,7 +2307,7 @@ "notesCopied": "评审笔记已复制", "notesSent": "评审笔记已发送", "notesSentWithWarning": "评审笔记已发送。{{warning}}", - "promptNotSent": "智能体已启动,但笔记未发送。请使用“复制笔记”复制后粘贴。", + "promptNotSent": "智能体已启动,但笔记未发送。请使用“复制备注”复制后粘贴。", "sendFailed": "发送笔记失败", "startingAgent": "正在启动智能体…", "waitingForDesktop": "等待桌面连接…" @@ -2344,7 +2358,7 @@ "updateFailed": "更新标题失败。" }, "useQuickCommands": { - "loadFailed": "加载快速命令失败", + "loadFailed": "加载快捷命令失败", "saveFailed": "保存快速命令失败" }, "useSessionTerminalSendActions": { @@ -2520,11 +2534,67 @@ } }, "sourceControl": { + "actionSheetRunners": { + "noBaseBranch": "没有可作为变基目标的基础分支", + "waitingForDesktop": "正在等待桌面…" + }, "actions": { + "checkingReviewStatus": "正在检查评审状态。", + "checkoutBeforePublish": "请先检出分支再发布提交。", + "commitStagedChanges": "提交已暂存的更改。", "commits": "提交", + "committing": "正在提交。", "createPr": "创建PR", + "enterCommitMessage": "请输入提交信息后再提交。", + "forcePushWithLease": "使用 lease 强制推送以更新远程分支。", + "forcePushing": "正在强制推送。", + "linkedReviewUnavailable": "关联的评审分支不可用。", + "publishToOrigin": "将此分支发布到 origin。", + "pullCommits_one": "拉取 {{count}} 个提交。", + "pullCommits_other": "拉取 {{count}} 个提交。", "pushAndCreatePr": "推送并创建 PR", - "switchBranch": "切换分支" + "pushCommits_one": "推送 {{count}} 个提交。", + "pushCommits_other": "推送 {{count}} 个提交。", + "pushLinkedReview": "将更新推送到关联的评审分支。", + "remoteOperationInProgress": "正在执行远程操作。", + "resolveConflicts": "请先解决冲突再提交。", + "reviewAlreadyMerged": "没有可提交的内容。评审已合并。", + "stageAllChanges": "暂存全部更改。", + "stageFileToCommit": "请至少暂存一个文件后再提交。", + "switchBranch": "切换分支", + "syncCounts": "拉取 {{behind}} 个提交,推送 {{ahead}} 个提交。", + "upToDate": "没有可提交的内容。分支已是最新状态。", + "waitForRemoteOperation": "请在远程操作完成后重试。" + }, + "branchBaseRef": { + "resolveFailed": "无法解析基础分支" + }, + "branchCard": { + "branchCount": "已提交 {{count}} 个文件", + "changedCount": "已更改 {{count}} 个文件", + "cherryPickState": "cherry-pick", + "mergeState": "合并", + "rebaseState": "变基", + "stagedCount": "已暂存 {{count}} 个文件" + }, + "branchCompare": { + "commits_one": "{{count}} 次提交", + "commits_other": "{{count}} 次提交", + "files_one": "{{count}} 个文件", + "files_other": "{{count}} 个文件", + "sectionTitle": "已提交的更改", + "summary": "{{files}} - 与 {{baseRef}} 比较", + "summaryWithCommits": "{{files}} - {{commits}} - 与 {{baseRef}} 比较" + }, + "branchCompareOutcome": { + "baseBranchUnavailable": "无法解析用于比较的基础分支。", + "loadFailed": "无法加载已提交的更改" + }, + "branchDiffPreviewDrawer": { + "closePreview": "关闭已提交更改的差异预览", + "committedOnBranch": "已提交到分支", + "loadFailed": "无法加载差异", + "truncated": "移动端预览中的差异已截断。" }, "commitDropdown": { "checkOutBranchToPush": "请先检出分支再推送提交", @@ -2549,8 +2619,49 @@ "stageFile": "暂存至少一个要提交的文件", "useCommitAndForcePush": "使用提交并强制推送 — 远程只有本地提交的旧副本" }, + "commitFailurePanel": { + "fix": "修复", + "fixWithAi": "使用 AI 修复提交失败", + "hideDetails": "隐藏详情", + "hideFailureDetails": "隐藏提交失败详情", + "showDetails": "显示详情", + "showFailureDetails": "显示提交失败详情", + "summary": "提交失败。", + "title": "提交失败" + }, + "commitMessageAi": { + "generateFailed": "生成提交信息失败" + }, + "commitRunners": { + "actionFailed": "源代码控制操作失败", + "commitFailed": "提交失败" + }, + "conflictAbort": { + "abortMerge": "中止合并", + "abortOperation": "中止 {{operation}}", + "abortRebase": "中止变基", + "aborting": "正在中止…" + }, + "content": { + "cancelGeneration": "取消生成提交信息", + "commitMessageDisabled": "提交信息输入已禁用。没有已暂存的文件。", + "commitMessagePlaceholder": "提交信息", + "emptyMessage": "工作树无更改。", + "emptyTitle": "无本地更改", + "generateMessage": "使用 AI 生成提交信息", + "noStagedFiles": "没有已暂存的文件", + "openActions": "打开源代码控制操作菜单", + "reconnecting": "正在重新连接桌面…", + "regenerateHint": "清除消息以重新生成。", + "stageAll": "暂存全部", + "unstageAll": "取消全部暂存" + }, "createPrAction": { - "createReview": "创建 {{titleLabel}}" + "checkingStatus": "正在检查评审状态…", + "createPullRequest": "创建PR", + "createReview": "创建 {{titleLabel}}", + "providerUnavailable": "此提供商无法创建评审", + "statusUnavailable": "评审状态不可用" }, "dropdownCounts": { "fastForwardCount_one": "快进 {{count}} 个提交", @@ -2572,6 +2683,64 @@ "titleUnpublishedForcePushCount_one": "使用 lease 强制推送 {{count}} 个分支提交,并在需要时设置上游。", "titleUnpublishedForcePushCount_other": "使用 lease 强制推送 {{count}} 个分支提交,并在需要时设置上游。" }, + "fileList": { + "committedSection": "已提交的更改" + }, + "fileRows": { + "addedByThem": "对方已添加", + "addedByUs": "我方已添加", + "bothAdded": "双方均已添加", + "bothDeleted": "双方均已删除", + "bothModified": "双方均已修改", + "committedSection": "已提交的更改", + "committedUnavailable": "已提交的更改不可用。", + "deletedByThem": "对方已删除", + "deletedByUs": "我方已删除", + "discardFile": "放弃 {{path}} 的更改", + "loadingCommitted": "正在加载已提交的更改…", + "openChangedFile": "打开已更改的文件 {{path}}", + "openCommittedChange": "打开 {{path}} 中已提交的更改", + "renamedFrom": "原路径 {{path}}", + "stageFile": "暂存 {{path}}", + "unresolvedConflict": "未解决的冲突", + "unstageFile": "取消暂存 {{path}}" + }, + "gitHistory": { + "days_one": "{{count}} 天", + "days_other": "{{count}} 天", + "hours_one": "{{count}} 小时", + "hours_other": "{{count}} 小时", + "justNow": "刚刚", + "loadFailed": "加载提交历史失败", + "minutes_one": "{{count}} 分钟", + "minutes_other": "{{count}} 分钟", + "months_one": "{{count}} 个月", + "months_other": "{{count}} 个月", + "noCommitMessage": "(无提交信息)", + "years_one": "{{count}} 年", + "years_other": "{{count}} 年" + }, + "gitHistoryList": { + "loadFailed": "加载历史记录失败", + "loadFilesFailed": "无法加载提交文件", + "noCommits": "暂无提交。", + "noFileChanges": "无文件更改", + "retryFiles": "重试加载提交文件", + "waitingForDesktop": "正在等待桌面…" + }, + "gitStatus": { + "changes": "更改", + "conflicts": "冲突", + "stagedChanges": "已暂存的更改" + }, + "header": { + "backToSession": "返回会话", + "close": "关闭源代码控制", + "openNumberedPrWeb": "在网页上打开 PR #{{number}}", + "openPrWeb": "在网页上打开 PR", + "refresh": "刷新源代码控制", + "title": "源代码控制" + }, "hostedReview": { "mrCopy": { "reviewLabel": "合并请求", @@ -2584,9 +2753,81 @@ "titleLabel": "PR" } }, + "hostedReviewCopy": { + "committingChanges": "正在提交更改…", + "creatingReview": "正在创建评审…", + "forcePushing": "正在使用 lease 强制推送…", + "generatingCommitMessage": "正在生成提交信息…", + "publishingBranch": "正在发布分支…", + "pushingCommits": "正在推送提交…", + "stagingChanges": "正在暂存更改…", + "updatingBranch": "正在更新分支…" + }, "hostedReviewCreate": { "pushSucceeded": "推送成功,但创建 {{shortLabel}} 失败:{{error}}" }, + "hostedReviewCreateIntent": { + "branchChanged": "准备创建 PR 时分支发生了变化。", + "generateMessageFailed": "无法生成提交信息。请在“源代码控制”中填写后重试。", + "resolveConflicts": "请先解决冲突,再创建 PR。", + "resolveOrStageChanges": "请先处理或暂存更改,再创建 PR。", + "reviewCommitMessage": "请先检查提交信息,然后重试创建 PR。" + }, + "hostedReviewGitPreparation": { + "commitFailed": "提交失败", + "refreshFailed": "无法刷新源代码控制", + "stageFailed": "暂存更改失败", + "updateBranchFailed": "无法更新远程分支。请重试创建 PR。" + }, + "hostedReviewRemotePrerequisite": { + "forcePushFailed": "使用 lease 强制推送失败", + "publishFailed": "发布分支失败", + "pushFailed": "推送提交失败" + }, + "hostedReviewService": { + "createFailed": "创建 PR 失败", + "pushBeforeCreateFailed": "推送失败。请解决推送错误后重试。" + }, + "hubTab": { + "changes": "更改", + "commits": "提交", + "pullRequest": "PR" + }, + "loaders": { + "connectingToDesktop": "正在连接桌面…", + "loadFailed": "无法加载源代码控制", + "updateDesktop": "请更新 Orca 桌面端,以在手机上使用源代码控制。", + "waitingForDesktop": "正在等待桌面…" + }, + "modals": { + "actionsTitle": "源代码控制", + "currentBranch": "当前", + "discardButton": "放弃", + "discardConfirmMessage": "放弃对“{{path}}”的更改?此操作无法撤销。", + "discardTitle": "放弃更改", + "openPrMessage": "在浏览器中打开?", + "openPrWithWarning": "在浏览器中打开?\n\n{{warning}}", + "prCreatedTitle": "PR 已创建", + "switchBranchTitle": "切换分支" + }, + "openers": { + "openDiffFailed": "无法打开差异", + "tabNotReady": "文件已打开,但标签页尚未就绪。请重试。", + "waitingForDesktop": "正在等待桌面…" + }, + "panel": { + "loadFailedTitle": "无法加载", + "unavailableTitle": "源代码控制不可用" + }, + "prChip": { + "createPr": "创建 PR", + "loading": "正在加载 PR…", + "loadingLabel": "正在加载 PR", + "openLabel": "PR #{{number}},{{state}},{{checks}}。打开 PR。", + "openWithComments_one": "PR #{{number}},{{state}},{{checks}},{{count}} 条未解决的评论。打开 PR。", + "openWithComments_other": "PR #{{number}},{{state}},{{checks}},{{count}} 条未解决的评论。打开 PR。", + "unavailableLabel": "PR 不可用:{{message}}" + }, "prCreate": { "authRequired": "请在创建 {{reviewLabel}} 之前完成身份验证。", "baseNotOnRemote": "请先推送基础分支,再创建 {{reviewLabel}}。", @@ -2605,8 +2846,19 @@ "unsupportedMergeRequests": "此仓库不支持创建合并请求。", "unsupportedPullRequests": "此仓库不支持创建 PR。" }, + "prLink": { + "updatePullRequestFailed": "更新关联的 PR 失败", + "updateReviewFailed": "更新关联的评审失败" + }, "primaryAction": { - "forcePushFromDesktop": "从桌面强制推送此 PR 的分支" + "commit": "提交", + "forcePush": "强制推送", + "forcePushFromDesktop": "从桌面强制推送此 PR 的分支", + "publishBranch": "发布分支", + "pull": "拉", + "push": "推", + "stageAll": "暂存全部", + "sync": "同步" }, "remoteDropdown": { "branchAlreadyPublished": "分支已发布", @@ -2656,6 +2908,591 @@ "tryFastForwardPull": "尝试快进拉取;git 可能会拒绝本地提交", "tryRegularPush": "尝试常规推送;git 可能要求强制推送", "useForcePushToSync": "请使用强制推送——远程只有本地提交的旧副本" + }, + "runners": { + "actionFailed": "源代码控制操作失败" + }, + "screenState": { + "noBranch": "无分支" + }, + "state": { + "noUpstream": "无上游分支", + "syncStatus": "领先 {{ahead}},落后 {{behind}}" + }, + "useMobileCommitFailureRecovery": { + "launchFailed": "启动智能体失败", + "waitingForDesktop": "正在等待桌面…" + }, + "useMobileCommitMessageGeneration": { + "generateFailed": "生成提交信息失败" + }, + "useMobileCreatePrRunner": { + "branchRequired": "创建 PR 前,请先检出分支。" + }, + "useMobileGitRequests": { + "actionFailed": "源代码控制操作失败", + "branchUnavailable": "无法获取分支状态", + "commitFailed": "提交失败", + "waitingForDesktop": "正在等待桌面…" + } + }, + "tasks": { + "composerSource": { + "baseFailed": "无法解析基础分支。", + "forkPushWarning": "此 PR 未开启“允许维护者编辑”;向 fork 仓库推送可能会被 GitHub 拒绝。" + }, + "detailCommentRenderers": { + "commentPlaceholder": "添加评论", + "comments_one": "{{count}} 条评论", + "comments_other": "{{count}} 条评论", + "reopenThread": "重新打开讨论串", + "reply": "回复", + "resolveThread": "解决讨论串", + "resolvedCommentBy": "{{author}} 的评论(已解决)", + "resolvedThreadBy": "{{author}} 的讨论串(已解决)", + "sendComment": "发送评论", + "show": "显示" + }, + "filterPickers": { + "allTeams": "所有团队", + "changeStatus": "更改状态", + "fieldHidden": "不在卡片上显示", + "fieldShown": "在卡片上显示", + "fieldsSubtitle": "选择要在条目卡片上显示的项目字段。", + "fieldsTitle": "项目字段", + "gitlabFilter": "GitLab 筛选", + "gitlabView": "GitLab 视图", + "jiraFilter": "Jira 筛选", + "jiraSite": "Jira 站点", + "linearFilter": "Linear 筛选", + "linearIssue": "Linear 议题", + "linearWorkspace": "Linear 工作区", + "loadingStates": "正在加载状态…", + "noFields": "此视图没有可显示的额外字段。", + "noStates": "无可用状态", + "switchWorkspaceFailed": "切换工作区失败", + "teamsSubtitle": "选择要在“任务”中显示的团队。", + "teamsTitle": "Linear 团队", + "teams_one": "{{count}} 个团队", + "teams_other": "{{count}} 个团队" + }, + "githubProjectList": { + "browseProjects": "浏览项目", + "chooseProject": "选择 GitHub 项目", + "emptyField": "空的", + "issueSubtitle": "议题 · {{repository}}{{number}}", + "itemSubtitle": "项目条目 · {{repository}}{{number}}", + "items": "条目", + "moreFields_one": "+{{count}} 个字段", + "moreFields_other": "+{{count}} 个字段", + "noItems": "没有项目条目", + "pullRequestSubtitle": "PR · {{repository}}{{number}}" + }, + "githubProjectPickers": { + "add": "添加", + "addByUrlHint": "使用“通过 URL 添加”来访问未列出的项目。", + "addPlaceholder": "通过 URL 或 owner/number 添加", + "adding": "添加中…", + "browseAll": "浏览全部", + "browseLoading": "浏览全部(加载中…)", + "chooseView": "选择项目视图", + "loadFailed": "无法加载项目", + "noMatches": "没有匹配的项目。", + "noMoreProjects": "没有更多项目。", + "noProjects": "尚未加载任何项目", + "organizationsError": "组织:{{message}}", + "organizationsLoadFailed": "{{count}} 个组织未能加载。", + "ownerLoadFailed": "无法加载 {{owner}} 的项目。", + "pin": "固定", + "pinned": "已固定", + "recent": "最近的", + "retryHint": "点按重试。", + "searchProjects": "搜索项目", + "sort": "项目排序", + "subtitle": "为“任务”页面选择项目视图。", + "title": "GitHub 项目", + "unsupportedLayout": "Orca 暂不支持此 GitHub 项目布局。", + "view": "项目视图" + }, + "githubViewControls": { + "fields": "字段:{{fields}}", + "openView": "在 GitHub 中打开视图", + "sort": "排序:{{sort}}", + "source": "来源:{{source}}" + }, + "itemActions": { + "changeStatus": "更改状态", + "copyGitHubLink": "复制 GitHub 链接", + "copyLinearLink": "复制 Linear 链接", + "createWorkspace": "创建工作区", + "creating": "创建中…", + "mergeConflicts": "GitHub 报告存在合并冲突。", + "mergeMergeRequest": "合并合并请求", + "mergePullRequest": "合并 PR" + }, + "itemDetailContent": { + "addSubIssue": "添加子议题", + "assignee": "负责人", + "assignees": "负责人", + "checks": "检查项", + "description": "描述", + "discussion": "讨论", + "noChecks": "未找到检查项。", + "noComments": "暂无评论。", + "noPipelineRuns": "此 MR 没有运行任何管道。", + "noSubIssues": "没有子议题。", + "none": "没有任何", + "pipeline": "管道", + "pipelineJobs_one": "{{count}} 个作业", + "pipelineJobs_other": "{{count}} 个作业", + "project": "项目", + "rerunAll": "重新运行全部", + "rerunFailed": "重新运行失败项", + "status": "状态", + "subIssueTitle": "子议题标题", + "subIssues": "子议题", + "type": "类型" + }, + "itemDetailDrawer": { + "refreshDetails": "刷新详情" + }, + "itemFieldEditors": { + "addLabels": "添加标签,以英文逗号分隔", + "addUsernames": "添加用户名,以英文逗号分隔", + "assignees": "负责人", + "labels": "标签", + "loadingAssignees": "正在加载负责人…", + "loadingLabels": "正在加载标签…", + "noAssignableUsers": "未找到此仓库中可指派的用户。", + "noLabels": "此仓库没有标签。", + "none": "没有任何", + "removeLabels": "移除标签,以英文逗号分隔", + "removeUsernames": "移除用户名,以英文逗号分隔", + "saveTitle": "保存标题", + "title": "标题", + "updateAssignees": "更新负责人", + "updateLabels": "更新标签" + }, + "itemReviewSections": { + "binaryFile": "二进制文件。", + "changedFilesTitle": "已更改文件", + "descriptionPlaceholder": "描述", + "fileContentsUnavailable": "文件内容不可用。", + "hideFile": "隐藏", + "loadingReviewers": "正在加载评审人…", + "markUnviewed": "标记未查看", + "markViewed": "标记已查看", + "noDescription": "没有描述。", + "noReviewerSuggestions": "未找到推荐的评审人。", + "noReviewersRequested": "未请求评审人", + "requestReview": "请求评审", + "reviewersPlaceholder": "邀请评审人", + "reviewersTitle": "评审人", + "saveDescription": "保存描述", + "viewFile": "查看" + }, + "legacySurface": { + "loadIssuesFailed": "无法从 {{source}} 加载议题。", + "mergeAction": "合并", + "mergeMethodTitle": "合并方式", + "mergePullRequestTitle": "合并 PR", + "mergeRequestMergeMessage": "请选择此合并请求的合并方式。", + "mergeRequestTitle": "合并请求", + "pullRequestMergeMessage": "请选择此 PR 的合并方式。", + "retryLoadingIssues": "重试从 {{source}} 加载议题", + "retrying": "正在重试…", + "sourceFallback": "{{repo}} 的首选议题来源 upstream 不可用,已改用 origin。", + "subIssueDataUnavailable": "您的token无法获取子议题数据。", + "updateItemTitle": "更新条目" + }, + "linearList": { + "changeStatusFrom": "更改状态,当前为 {{status}}" + }, + "linearViewControls": { + "displayButton": "显示", + "groupLabel": "分组:{{group}}", + "orderLabel": "排序:{{order}}" + }, + "listDisplayPickers": { + "displayPropertiesTitle": "显示属性", + "linearGroupTitle": "Linear 议题分组", + "linearOrderTitle": "Linear 议题排序", + "linearViewTitle": "Linear 视图", + "sortTasksTitle": "任务排序" + }, + "listSurface": { + "connectLinearButton": "连接 Linear", + "connectLinearMessage": "直接在“任务”中浏览并开始处理分配给您的 Linear 议题。", + "connectLinearTitle": "连接您的 Linear 账户", + "jiraStatusFailed": "读取 Jira 状态失败", + "updateDesktopMessage": "此移动端“任务”视图需要更高版本的桌面端运行时。", + "updateDesktopTitle": "更新 Orca 桌面端" + }, + "options": { + "all": "全部", + "assignedToMe": "分配给我", + "assignee": "负责人", + "board": "看板", + "boardDescription": "按组分列显示", + "closedState": "已关闭", + "completedState": "已完成", + "createdState": "我创建的", + "githubAssignedIssuesDescription": "分配给您的开放议题", + "githubDescription": "议题和 PR", + "githubIssuesDescription": "GitHub 议题", + "githubOpenIssuesDescription": "开放的 GitHub 议题", + "githubProjectsDescription": "GitHub 项目视图", + "githubPullRequestsDescription": "GitHub PR", + "gitlabAllDescription": "所有 GitLab 状态", + "gitlabClosedDescription": "已关闭的议题和合并请求", + "gitlabDescription": "议题和合并请求", + "gitlabMergedDescription": "已合并的合并请求", + "gitlabOpenDescription": "开放的议题和合并请求", + "identifier": "标识符", + "issues": "议题", + "jiraDescription": "分配给您及由您报告的议题", + "labels": "标签", + "linearAllDescription": "所有已连接工作区中的开放议题", + "linearAssignedDescription": "分配给您的议题", + "linearCompletedDescription": "最近完成的议题", + "linearCreatedDescription": "您创建的议题", + "linearDescription": "分配给您的议题和团队议题", + "list": "列表", + "listDescription": "以紧凑行显示议题", + "mergedState": "已合并", + "mine": "我的", + "myIssues": "我的议题", + "myPullRequestsDescription": "您创建的 PR", + "myTodos": "我的待办事项", + "myTodosDescription": "待处理的 GitLab 待办事项", + "needsReview": "待评审", + "noGrouping": "没有分组", + "openPullRequestsDescription": "开放的 PR", + "openState": "开放", + "priority": "优先级", + "projectMergeRequests": "项目 MR", + "projectMergeRequestsDescription": "按仓库查看合并请求和议题", + "projects": "项目", + "pullRequests": "PR", + "repository": "仓库", + "repositorySortDescription": "按仓库分组,组内最新活动优先", + "reviewRequestsDescription": "分配给您的评审请求", + "status": "状态", + "team": "团队", + "updated": "已更新", + "updatedSortDescription": "最新活动优先" + }, + "pickerProjection": { + "allRepos": "所有仓库", + "allSites": "所有站点", + "currentlyAscending": "当前升序 · 点按切换为降序", + "currentlyDescending": "当前降序 · 点按切换为升序", + "fieldAscending": "{{field}} 升序", + "fieldDescending": "{{field}} 降序", + "fields": "字段", + "repos_one": "{{count}} 个仓库", + "repos_other": "{{count}} 个仓库", + "selectTarget": "选择目标", + "selectedFields": "{{selected}}/{{total}} 个字段", + "sortAscending": "升序排列", + "sources_one": "{{count}} 个来源", + "sources_other": "{{count}} 个来源", + "unsupportedLayout": "移动端不支持此布局", + "updatedSort": "已更新", + "usesFieldAscending": "按 {{field}} 升序排列", + "usesFieldDescending": "按 {{field}} 降序排列", + "usesGitHubRankOrder": "采用 GitHub 排列顺序", + "viewNumber": "视图 #{{number}}", + "viewOrder": "视图顺序" + }, + "prFileDiff": { + "commentOnLine": "在第 {{line}} 行添加评论", + "commentPlaceholder": "添加评审评论", + "noTextChanges": "未发现文本更改。", + "showingDiffLines": "显示前 {{limit}} 行差异,共 {{total}} 行。" + }, + "projectComments": { + "comments_one": "{{count}} 条评论", + "comments_other": "{{count}} 条评论", + "discussion": "讨论", + "editComment": "编辑评论", + "noComments": "暂无评论。", + "reopenThread": "重新打开讨论串", + "reply": "回复", + "resolveThread": "解决讨论串", + "resolvedCommentBy": "{{author}} 的评论(已解决)", + "resolvedThreadBy": "{{author}} 发起的讨论串(已解决)", + "show": "显示" + }, + "projectDetailDrawer": { + "addRepositoryFromDesktop": "{{repository}} 尚未添加到 Orca。请在桌面应用中添加此仓库,然后刷新移动端的“任务”。", + "clearType": "清除类型", + "closeItem": "关闭条目", + "copyGitHubLink": "复制 GitHub 链接", + "copyRepository": "复制仓库名", + "createWorkspace": "创建工作区", + "draftIssue": "草稿议题", + "issue": "议题", + "issueType": "议题类型", + "loadingIssueTypes": "正在加载议题类型…", + "mergePullRequest": "合并 PR", + "mergeRepositoryRequirement": "合并前需在 Orca 中添加此仓库。", + "noIssueTypes": "此仓库未配置议题类型。", + "noType": "无类型", + "openInGitHub": "在 GitHub 中打开", + "projectItem": "项目条目", + "projectSubtitle": "GitHub 项目 · {{repository}}{{itemNumber}}", + "pullRequest": "PR", + "reopenItem": "重新打开条目", + "repositoryNotInOrca": "仓库不在 Orca 中", + "status": "状态", + "type": "类型", + "workspaceCreationRequirement": "只能从 GitHub 议题和 PR 创建工作区。" + }, + "projectFieldEditors": { + "clearField": "清空字段", + "completedIteration": "已完成 · {{startDate}} · {{duration}} 天", + "datePlaceholder": "YYYY-MM-DD", + "invalidDate": "请按 YYYY-MM-DD 格式输入日期。", + "invalidNumber": "请输入有效数字。", + "noIterations": "暂无可用迭代。", + "numberPlaceholder": "数字", + "projectFields": "项目字段", + "saveField": "保存字段", + "textPlaceholder": "文本", + "upcomingIteration": "当前及即将开始 · {{startDate}} · {{duration}} 天" + }, + "projectMetadataEditors": { + "assignees": "负责人", + "description": "描述", + "labels": "标签", + "loadingAssignees": "正在加载负责人…", + "loadingLabels": "正在加载标签…", + "noAssignableUsers": "未找到此仓库中可设为负责人的用户。", + "noDescription": "没有描述。", + "noLabels": "此仓库中没有标签。", + "none": "无", + "saveDescription": "保存描述", + "saveTitle": "保存标题", + "title": "标题" + }, + "projectReviewPanels": { + "binaryFile": "二进制文件。", + "changedFiles": "已更改文件", + "checks": "检查项", + "fileUnavailable": "文件内容不可用。", + "hideFile": "隐藏", + "loadingReviewers": "正在加载评审人…", + "markUnviewed": "标记未查看", + "markViewed": "标记已查看", + "noChecks": "未找到检查项。", + "noReviewers": "未请求评审人", + "noSuggestions": "未找到推荐的评审人。", + "requestReview": "请求评审", + "requestReviewers": "邀请评审人", + "rerunAll": "全部重新运行", + "rerunFailed": "重新运行失败项", + "reviewers": "评审人", + "viewFile": "查看" + }, + "providerControls": { + "myTodos": "我的待办", + "projectMergeRequests": "项目 MR", + "sort": "排序:{{sortLabel}}" + }, + "providerItemList": { + "intoBranch": "合并到 {{base}}", + "nextPage": "前往下一页", + "page": "第 {{page}} 页", + "pageOfTotal": "第 {{page}} 页,共 {{total}} 页", + "previousPage": "前往上一页", + "selectPage": "选择页码,当前第 {{page}} 页", + "selectPageOfTotal": "选择页码,当前第 {{page}} 页,共 {{total}} 页" + }, + "providerPickers": { + "allRepositories": "所有仓库", + "githubView": "GitHub 视图", + "issueSources": "GitHub 议题来源", + "issueSourcesDescription": "选择每个仓库从 upstream 还是 origin 查询和创建工作项。", + "issues": "议题", + "noIssueSources": "没有其他可用的议题来源。", + "origin": "origin", + "pageHint": "跳转到已加载或可用的结果页。", + "pageLoaded": "已加载", + "pageNotLoaded": "加载更早的结果", + "pageNumber": "第 {{page}} 页", + "pages": "GitHub 结果页", + "pullRequests": "PR", + "queryingSource": "正在查询 {{source}}", + "repoDescription": "选择要查询的仓库。", + "repos": "仓库", + "taskSource": "任务来源", + "upstream": "上游" + }, + "providerViewProjection": { + "all": "全部", + "allSites": "所有站点", + "allTeams": "所有团队", + "allWorkspaces": "所有工作区", + "chooseProject": "选择项目", + "default": "默认", + "defaultSubtitle": "{{subtitle}} · 默认", + "issues": "议题", + "list": "列表", + "noGrouping": "没有分组", + "openState": "开放", + "priority": "优先级", + "projects": "项目", + "pullRequests": "PR", + "teams_one": "{{count}} 个团队", + "teams_other": "{{count}} 个团队", + "workspace": "工作区" + }, + "reviewerLinear": { + "issues": "议题", + "unassigned": "未分配" + }, + "screenChrome": { + "connectLinear": "连接 Linear", + "newGitHubIssue": "新的 GitHub 议题", + "newLinearIssue": "新建 Linear 议题", + "refreshGitHub": "刷新 GitHub 工作", + "refreshGitLab": "刷新 GitLab 工作项", + "refreshJira": "刷新 Jira 议题", + "refreshLinear": "刷新 Linear", + "title": "任务" + }, + "searchControl": { + "jiraPlaceholder": "Jira JQL,例如 project = ABC AND statusCategory != Done", + "projectPlaceholder": "搜索项目视图…", + "providerPlaceholder": "搜索 {{provider}} 任务…" + }, + "smartSourceModes": { + "allStates": "全部", + "branch": "分支", + "closedState": "已关闭", + "mergedState": "已合并", + "name": "名称", + "openState": "开放", + "smart": "智能" + }, + "sparsePresetDraft": { + "directoryRequired": "添加至少一个目录。", + "repoRelativeDirectoriesRequired": "使用仓库相对目录,而不是根目录、绝对路径或父段。" + }, + "taskViewOptions": { + "allSubtitle": "所选站点中未解决的议题", + "assignedSubtitle": "分配给您的未解决议题", + "doneSubtitle": "分配给您且最近已解决的议题", + "noGitHubTasks": "暂无 GitHub 任务", + "noGitLabTasks": "暂无 GitLab 任务", + "noJiraTasks": "暂无 Jira 任务", + "noLinearTasks": "暂无 Linear 任务", + "reportedSubtitle": "您报告的未解决议题" + }, + "tasksCreateDrawers": { + "connect": "连接", + "connectLinearWorkspace": "连接 Linear 工作区", + "createIssue": "创建议题", + "createWorkspaceIn": "选择创建工作区的仓库", + "description": "描述", + "descriptionPlaceholder": "补充背景信息", + "fileIn": "在 {{slug}} 中创建议题", + "issueSource": "议题来源", + "keySecurityHint": "密钥通过主机操作系统的钥匙串加密,并存储在本地。", + "linearConnectSubtitle": "粘贴个人 API 密钥,即可浏览该工作区的议题。", + "linearSettingsLink": "Linear 设置 / 安全 / 新建 API 密钥", + "linearTeam": "Linear 团队", + "linearTeamSubtitle": "在所选 Linear 团队中创建议题。", + "newIssueTitle": "新建 {{providerLabel}} 议题", + "origin": "origin", + "personalApiKey": "个人API密钥", + "repository": "仓库", + "repositorySubtitle": "在所选仓库中创建议题。", + "team": "团队", + "title": "标题", + "titlePlaceholder": "任务标题", + "upstream": "上游" + }, + "workspaceAgentSelection": { + "blankTerminal": "空白终端" + }, + "workspaceCreateDrawer": { + "addRepository": "创建 Linear 工作区前,请先添加 Git 仓库。", + "advanced": "高级", + "agent": "智能体", + "connect": "连接", + "connectFirst": "请先连接仓库", + "connectRepository": "连接仓库", + "connecting": "连接中…", + "createFrom": "基于 {{branch}} 创建", + "defaultBranch": "默认分支", + "detectingAgents": "正在检测智能体…", + "optional": "[可选]", + "remoteRepository": "远程仓库", + "repository": "仓库", + "repositoryNotFound": "未找到仓库。", + "selectRepository": "选择仓库", + "sshConnection": "SSH 连接", + "startFrom": "创建起点", + "title": "创建工作区", + "workspaceName": "工作区名称" + }, + "workspaceCreateProjection": { + "nameAlreadyExists": "“{{name}}”已存在。", + "nameRequired": "请输入名称。", + "nameTooLong": "名称不能超过80个字符。", + "openShell": "打开 shell" + }, + "workspaceOptionPickers": { + "baseBranchSubtitle": "选择现有分支或引用。", + "baseBranchTitle": "创建起点", + "branchName": "分支名称:{{name}}", + "defaultBranch": "默认分支", + "defaultBranchSubtitle": "使用此仓库配置的基础分支", + "editPreset": "编辑 {{name}}", + "fullCheckout": "完整检出", + "fullCheckoutSubtitle": "使用整个仓库", + "newPreset": "新预设", + "noBranches": "没有匹配的分支。", + "searchBranches": "搜索分支", + "sparseCheckoutTitle": "稀疏检出" + }, + "workspaceSshGate": { + "authenticationFailed": "身份验证失败", + "connected": "已连接", + "connecting": "连接中", + "connectionFailed": "连接失败", + "deployingRelay": "正在部署中继", + "disconnected": "已断开连接", + "reconnectFailed": "重新连接失败", + "reconnecting": "重新连接中" + }, + "workspaceTrustDrawers": { + "alwaysTrustAndRun": "始终信任并运行", + "creating": "创建中…", + "directoriesLabel": "目录", + "directories_one": "{{count}} 个目录", + "directories_other": "{{count}} 个目录", + "dontRun": "不运行", + "editSparsePreset": "编辑稀疏检出预设", + "nameLabel": "名称", + "namePlaceholder": "渲染器界面", + "newSetupScript": "新设置脚本", + "newSparsePreset": "新建稀疏检出预设", + "runHooks": "运行钩子", + "runSetupAndCreate": "运行设置脚本并创建", + "runSetupTitle": "运行 {{name}} 的设置脚本?", + "setupChangedTitle": "{{name}} 的设置脚本已更改", + "setupScript": "设置脚本", + "setupSubtitle": "创建此工作区前,请选择是否运行 {{name}} 的设置脚本。", + "setupTitle": "运行设置脚本?", + "skipSetupAndCreate": "跳过设置脚本并创建", + "trustFailed": "无法将设置脚本设为可信。", + "trustSubtitle": "工作区启动前,此仓库的 orca.yaml 会在您的电脑上运行。请仅在信任此仓库时运行。" + }, + "worktreeCreateRetry": { + "createFailed": "创建工作区失败" } }, "terminal": { diff --git a/mobile/src/new-workspace/NewWorkspaceHostPicker.tsx b/mobile/src/new-workspace/NewWorkspaceHostPicker.tsx index 8686e755bf9..b013a1585b8 100644 --- a/mobile/src/new-workspace/NewWorkspaceHostPicker.tsx +++ b/mobile/src/new-workspace/NewWorkspaceHostPicker.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef, useState } from 'react' import { useRouter } from 'expo-router' import { PickerModal } from '../components/PickerModal' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { hostPickerOptions } from '../components/use-connected-host-picker' import { selectConnectableHostProfiles } from '../transport/host-catalog-selection' import { loadHostCatalog } from '../transport/host-store' @@ -14,6 +15,7 @@ export function NewWorkspaceHostPicker({ hostIds: readonly string[] onPick: (hostId: string) => void }) { + const t = useMobileTranslation() const router = useRouter() const hosts = useOfferedHosts(hostIds) const [open, setOpen] = useState(true) @@ -27,7 +29,7 @@ export function NewWorkspaceHostPicker({ }, [nothingToPick, router]) return ( void }) { + const t = useMobileTranslation() useMobileColorScheme() const insets = useWindowSafeAreaInsets() const { isWideLayout, modalMaxWidth } = useResponsiveLayout() @@ -85,7 +87,7 @@ export function NewWorkspaceLoadingDrawer({ {download === null ? ( - + ) : ( )} @@ -125,6 +130,7 @@ export function NewWorkspaceLoadingDrawer({ } function DownloadProgress({ download }: { download: ShellOverlayDownload }) { + const t = useMobileTranslation() useMobileColorScheme() return ( <> @@ -132,10 +138,12 @@ function DownloadProgress({ download }: { download: ShellOverlayDownload }) { feed={download.feed} receivedBytes={download.receivedBytes} totalBytes={download.totalBytes} - accessibilityLabel="Downloading" + accessibilityLabel={t('newWorkspace.loadingDrawer.downloading', 'Downloading')} /> - Downloading… {downloadedMegabytesCaption(download.receivedBytes, download.totalBytes)} + {t('newWorkspace.loadingDrawer.downloadProgress', 'Downloading… {{progress}}', { + progress: downloadedMegabytesCaption(download.receivedBytes, download.totalBytes) + })} ) diff --git a/mobile/src/notifications/desktop-notification-channel.ts b/mobile/src/notifications/desktop-notification-channel.ts index 9e869e1b755..34286ce2111 100644 --- a/mobile/src/notifications/desktop-notification-channel.ts +++ b/mobile/src/notifications/desktop-notification-channel.ts @@ -1,22 +1,23 @@ import * as Notifications from 'expo-notifications' import { Platform } from 'react-native' +import { translate } from '../i18n/mobile-i18n' // Create the shared FCM channel before socket subscription: a background push can arrive first, and Android drops notifications for missing channels. export const DESKTOP_NOTIFICATION_CHANNEL_ID = 'orca-desktop' -// Android updates existing channels; other platforms do nothing. +// Android updates existing channels, so calling again after a language change renames them; other platforms do nothing. export async function ensureDesktopNotificationChannel(): Promise { if (Platform.OS !== 'android') { return } await Notifications.setNotificationChannelAsync(`${DESKTOP_NOTIFICATION_CHANNEL_ID}-silent`, { - name: 'Orca silent notifications', + name: translate('notifications.desktopChannel.silentName', 'Orca silent notifications'), importance: Notifications.AndroidImportance.HIGH, sound: null, enableVibrate: false }) await Notifications.setNotificationChannelAsync(DESKTOP_NOTIFICATION_CHANNEL_ID, { - name: 'Desktop Notifications', + name: translate('notifications.desktopChannel.name', 'Desktop Notifications'), importance: Notifications.AndroidImportance.HIGH, vibrationPattern: [0, 250], lightColor: '#6366f1' diff --git a/mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx b/mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx index 84d4068b1bd..33592c72be9 100644 --- a/mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx +++ b/mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx @@ -2,6 +2,7 @@ import { ActivityIndicator, Pressable, Text, View } from 'react-native' import { X } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { BottomDrawer } from '../components/BottomDrawer' import { MobileSyntaxSegments } from '../components/MobileSyntaxSegments' import { mobileDiffLineNumber, mobileDiffLinePrefix } from './mobile-diff-format' @@ -15,6 +16,7 @@ type Props = { export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Props) { useMobileColorScheme() + const t = useMobileTranslation() if (!branchDiffPreview) { return null } @@ -34,14 +36,17 @@ export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Pr {branchDiffPreview.kind === 'ready' ? `${branchDiffPreview.summary.baseRef}..HEAD` - : 'Committed on branch'} + : t('sourceControl.branchDiffPreviewDrawer.committedOnBranch', 'Committed on branch')} [styles.diffCloseButton, pressed && styles.iconButtonPressed]} onPress={onClose} hitSlop={8} - accessibilityLabel="Close committed diff preview" + accessibilityLabel={t( + 'sourceControl.branchDiffPreviewDrawer.closePreview', + 'Close committed diff preview' + )} > @@ -52,13 +57,20 @@ export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Pr ) : branchDiffPreview.kind === 'error' ? ( - Unable to Load Diff + + {t('sourceControl.branchDiffPreviewDrawer.loadFailed', 'Unable to Load Diff')} + {branchDiffPreview.message} ) : ( {branchDiffPreview.truncated ? ( - Diff truncated for mobile preview. + + {t( + 'sourceControl.branchDiffPreviewDrawer.truncated', + 'Diff truncated for mobile preview.' + )} + ) : null} {branchDiffPreview.lines.map((line, index) => ( - Commit failed + + {t('sourceControl.commitFailurePanel.title', 'Commit failed')} + - {action.summary ?? 'Commit failed.'} + {action.summary ?? t('sourceControl.commitFailurePanel.summary', 'Commit failed.')} void action.launch()} disabled={action.launching || action.availability !== 'available'} accessibilityRole="button" - accessibilityLabel="Fix commit failure with AI" + accessibilityLabel={t( + 'sourceControl.commitFailurePanel.fixWithAi', + 'Fix commit failure with AI' + )} > {action.launching ? ( ) : ( )} - Fix + + {t('sourceControl.commitFailurePanel.fix', 'Fix')} + {action.hasDetails && detailsText ? ( @@ -58,12 +67,22 @@ export function MobileCommitFailurePanel({ failure, action }: Props) { onPress={() => setExpanded((current) => !current)} accessibilityRole="button" accessibilityLabel={ - expanded ? 'Hide commit failure details' : 'Show commit failure details' + expanded + ? t( + 'sourceControl.commitFailurePanel.hideFailureDetails', + 'Hide commit failure details' + ) + : t( + 'sourceControl.commitFailurePanel.showFailureDetails', + 'Show commit failure details' + ) } > - {expanded ? 'Hide details' : 'Show details'} + {expanded + ? t('sourceControl.commitFailurePanel.hideDetails', 'Hide details') + : t('sourceControl.commitFailurePanel.showDetails', 'Show details')} {expanded ? {detailsText} : null} diff --git a/mobile/src/source-control/MobileGitHistoryList.tsx b/mobile/src/source-control/MobileGitHistoryList.tsx index c84b6f4511b..1bcefb182f3 100644 --- a/mobile/src/source-control/MobileGitHistoryList.tsx +++ b/mobile/src/source-control/MobileGitHistoryList.tsx @@ -1,9 +1,11 @@ -import { memo, useCallback, useEffect, useState } from 'react' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import { ActivityIndicator, FlatList, Pressable, Text, View } from 'react-native' import { ChevronDown, ChevronRight } from 'lucide-react-native' import { colors, radii, spacing, typography } from '../theme/mobile-theme' import { themedStyleSheet } from '../theme/themed-styles' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { translate } from '../i18n/mobile-i18n' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import type { ConnectionState } from '../transport/types' import type { RpcClient } from '../transport/rpc-client' import { useForceReconnect } from '../transport/host-client-hooks' @@ -16,6 +18,7 @@ import { type MobileCommitRow } from './mobile-git-history' import { resolveMobileHistoryScreenView } from './mobile-history-screen-state' +import type { MobileGitHistoryResult } from './git-history-reply-schema' type CommitFilesState = { files?: MobileGitChangedFile[] @@ -42,8 +45,14 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ refreshNonce = 0 }: Props) { const colorScheme = useMobileColorScheme() + const t = useMobileTranslation() const forceReconnect = useForceReconnect() - const [rows, setRows] = useState(null) + // Keep the fetched page, not formatted rows, so relative times follow a language switch. + const [rows, setRows] = useState<{ result: MobileGitHistoryResult; nowMs: number } | null>(null) + const commitRows = useMemo( + () => (rows ? mapMobileCommitRows(rows.result, rows.nowMs) : null), + [rows, t] + ) const [error, setError] = useState(null) const [reloadNonce, setReloadNonce] = useState(0) const [expanded, setExpanded] = useState(null) @@ -70,11 +79,15 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ try { const result = await fetchMobileGitHistory(client, worktreeId) if (active) { - setRows(mapMobileCommitRows(result, Date.now())) + setRows({ result, nowMs: Date.now() }) } } catch (err) { if (active) { - setError(err instanceof Error ? err.message : 'Failed to load history') + setError( + err instanceof Error + ? err.message + : translate('sourceControl.gitHistoryList.loadFailed', 'Failed to load history') + ) } } })() @@ -124,7 +137,13 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ ...prev, [commitId]: { files: prev[commitId]?.files, - error: err instanceof Error ? err.message : 'Unable to load commit files' + error: + err instanceof Error + ? err.message + : translate( + 'sourceControl.gitHistoryList.loadFilesFailed', + 'Unable to load commit files' + ) } })) } @@ -169,7 +188,10 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ {connected || retryAction ? ( { if (connState !== 'connected') { retryAction?.() @@ -178,7 +200,7 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ } }} > - Retry + {t('common.retry', 'Retry')} ) : null} @@ -187,12 +209,16 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ connected ? ( ) : ( - Waiting for desktop... + + {t('sourceControl.gitHistoryList.waitingForDesktop', 'Waiting for desktop...')} + ) ) : null} {files !== undefined ? ( files.length === 0 ? ( - No file changes + + {t('sourceControl.gitHistoryList.noFileChanges', 'No file changes')} + ) : ( files.map((file) => ( @@ -212,20 +238,26 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ ) }, - [colorScheme, connected, connState, expanded, filesById, retryAction, toggleCommit] + [colorScheme, connected, connState, expanded, filesById, retryAction, toggleCommit, t] ) - const view = resolveMobileHistoryScreenView({ connected, rows, error }) + const view = resolveMobileHistoryScreenView({ connected, rows: commitRows, error }) if (view.kind === 'error' || view.kind === 'waiting') { return ( - {view.kind === 'waiting' ? 'Waiting for desktop...' : view.message} + {view.kind === 'waiting' + ? t('sourceControl.gitHistoryList.waitingForDesktop', 'Waiting for desktop...') + : view.message} {retry ? ( - - Retry + + {t('common.retry', 'Retry')} ) : null} @@ -241,7 +273,9 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({ if (view.kind === 'empty') { return ( - No commits. + + {t('sourceControl.gitHistoryList.noCommits', 'No commits.')} + ) } diff --git a/mobile/src/source-control/MobileSourceControlBranchCard.tsx b/mobile/src/source-control/MobileSourceControlBranchCard.tsx index 51506a1e1d8..44862bcddb9 100644 --- a/mobile/src/source-control/MobileSourceControlBranchCard.tsx +++ b/mobile/src/source-control/MobileSourceControlBranchCard.tsx @@ -2,6 +2,7 @@ import { Pressable, Text, View } from 'react-native' import { GitBranch } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { styles } from './mobile-source-control-styles' import { MobileSourceControlPrChip } from './MobileSourceControlPrChip' import type { MobilePrChipSummary } from './mobile-pr-chip-summary' @@ -35,7 +36,16 @@ export function MobileSourceControlBranchCard({ onOpenPr }: Props) { useMobileColorScheme() + const t = useMobileTranslation() const showConflict = conflictOperation !== null && conflictOperation !== 'unknown' + const conflictLabel = + conflictOperation === 'merge' + ? t('sourceControl.branchCard.mergeState', 'merge') + : conflictOperation === 'rebase' + ? t('sourceControl.branchCard.rebaseState', 'rebase') + : conflictOperation === 'cherry-pick' + ? t('sourceControl.branchCard.cherryPickState', 'cherry-pick') + : conflictOperation return ( @@ -48,14 +58,26 @@ export function MobileSourceControlBranchCard({ {syncLabel ? {syncLabel} : null} - {unstagedCount} changed - {stagedCount} staged - {branchCount > 0 ? {branchCount} on branch : null} + + {t('sourceControl.branchCard.changedCount', '{{count}} changed', { + count: unstagedCount + })} + + + {t('sourceControl.branchCard.stagedCount', '{{count}} staged', { count: stagedCount })} + + {branchCount > 0 ? ( + + {t('sourceControl.branchCard.branchCount', '{{count}} on branch', { + count: branchCount + })} + + ) : null} {/* Keep Abort on its own row so long counts cannot overflow the card. */} {showConflict ? ( - {conflictOperation} + {conflictLabel} {conflictOperation === 'merge' || conflictOperation === 'rebase' ? ( [ diff --git a/mobile/src/source-control/MobileSourceControlContent.tsx b/mobile/src/source-control/MobileSourceControlContent.tsx index 56daf5996c8..8d1434ba1e0 100644 --- a/mobile/src/source-control/MobileSourceControlContent.tsx +++ b/mobile/src/source-control/MobileSourceControlContent.tsx @@ -3,6 +3,7 @@ import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-nativ import { Minus, MoreHorizontal, Plus, Sparkles } from 'lucide-react-native' import { colors, spacing } from '../theme/mobile-theme' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { MobileSourceControlCreatePrEntry } from './MobileSourceControlCreatePrEntry' import { MobileCommitFailurePanel } from './MobileCommitFailurePanel' import { KEYBOARD_COMMIT_BAR_CLEARANCE } from './mobile-source-control-screen-state' @@ -20,6 +21,7 @@ type Props = { export function MobileSourceControlContent({ state, primaryAction }: Props) { useMobileColorScheme() + const t = useMobileTranslation() const { insets, connState, @@ -102,7 +104,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { // Retained rows look actionable offline; show reconnect state beside them. - Reconnecting to desktop... + + {t('sourceControl.content.reconnecting', 'Reconnecting to desktop...')} + ) : null} @@ -134,7 +138,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { ) : ( )} - Stage All + + {t('sourceControl.content.stageAll', 'Stage All')} + [ @@ -150,7 +156,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { ) : ( )} - Unstage All + + {t('sourceControl.content.unstageAll', 'Unstage All')} + [ @@ -161,7 +169,10 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { onPress={() => setShowActionSheet(true)} disabled={ioBusy} hitSlop={8} - accessibilityLabel="Open source control actions" + accessibilityLabel={t( + 'sourceControl.content.openActions', + 'Open source control actions' + )} > @@ -170,8 +181,12 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { {!hasVisibleChanges ? ( - No local changes - Working tree is clean. + + {t('sourceControl.content.emptyTitle', 'No local changes')} + + + {t('sourceControl.content.emptyMessage', 'Working tree is clean.')} + ) : ( fileList @@ -192,16 +207,21 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) { style={[styles.commitInput, styles.commitInputDisabled]} accessibilityRole="text" accessibilityState={{ disabled: true }} - accessibilityLabel="Commit message disabled. No staged files." + accessibilityLabel={t( + 'sourceControl.content.commitMessageDisabled', + 'Commit message disabled. No staged files.' + )} > - No staged files + + {t('sourceControl.content.noStagedFiles', 'No staged files')} + ) : ( generatingMessage ? cancelGenerateCommitMessage() : void generateCommitMessage() } accessibilityLabel={ generatingMessage - ? 'Cancel commit message generation' - : 'Generate commit message with AI' + ? t('sourceControl.content.cancelGeneration', 'Cancel commit message generation') + : t('sourceControl.content.generateMessage', 'Generate commit message with AI') } > {generatingMessage ? ( diff --git a/mobile/src/source-control/MobileSourceControlFileList.tsx b/mobile/src/source-control/MobileSourceControlFileList.tsx index 47c90fcf1ea..230320c8af7 100644 --- a/mobile/src/source-control/MobileSourceControlFileList.tsx +++ b/mobile/src/source-control/MobileSourceControlFileList.tsx @@ -10,6 +10,7 @@ import type { } from './mobile-source-control-screen-state' import type { MobileSourceControlState } from './use-mobile-source-control-state' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { styles } from './mobile-source-control-styles' import { hubStyles } from './mobile-source-control-hub-styles' @@ -39,6 +40,7 @@ export type FileListState = Pick< export function MobileSourceControlFileList({ state }: { state: FileListState }) { const colorScheme = useMobileColorScheme() + const t = useMobileTranslation() const sections: FileSection[] = state.sections.map((section) => ({ ...section, key: section.id @@ -46,7 +48,7 @@ export function MobileSourceControlFileList({ state }: { state: FileListState }) if (state.shouldShowBranchCompareSection) { sections.push({ key: 'committed', - title: 'Committed on Branch', + title: t('sourceControl.fileList.committedSection', 'Committed on Branch'), data: state.branchCompareState.kind === 'ready' && state.branchCompareResult?.summary.status === 'ready' @@ -54,7 +56,7 @@ export function MobileSourceControlFileList({ state }: { state: FileListState }) : [] }) } - const renderFileRow = makeRenderFileRow(state) + const renderFileRow = makeRenderFileRow(state, t) return ( style={hubStyles.tabBody} diff --git a/mobile/src/source-control/MobileSourceControlFileRows.tsx b/mobile/src/source-control/MobileSourceControlFileRows.tsx index bc3fa6ee2cb..0a94a348882 100644 --- a/mobile/src/source-control/MobileSourceControlFileRows.tsx +++ b/mobile/src/source-control/MobileSourceControlFileRows.tsx @@ -2,8 +2,10 @@ import { ActivityIndicator, Pressable, Text, View } from 'react-native' import { ChevronRight, FileText, Minus, Plus, Trash2 } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { STATUS_LABELS } from '../../../src/shared/git-status-labels' -import { CONFLICT_KIND_LABELS } from '../../../src/shared/source-control-conflict-prompts' +import type { GitConflictKind } from '../../../src/shared/git-status-types' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import type { Translate } from '../i18n/mobile-i18n' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { formatMobileBranchEntryMeta } from './mobile-branch-entry-format' import { statusColor, @@ -23,10 +25,31 @@ type RowState = Pick< | 'setDiscardTarget' > -export function makeRenderFileRow(state: RowState) { +function conflictKindLabel(kind: GitConflictKind | undefined, t: Translate): string { + switch (kind) { + case 'both_modified': + return t('sourceControl.fileRows.bothModified', 'Both modified') + case 'both_added': + return t('sourceControl.fileRows.bothAdded', 'Both added') + case 'deleted_by_us': + return t('sourceControl.fileRows.deletedByUs', 'Deleted by us') + case 'deleted_by_them': + return t('sourceControl.fileRows.deletedByThem', 'Deleted by them') + case 'added_by_us': + return t('sourceControl.fileRows.addedByUs', 'Added by us') + case 'added_by_them': + return t('sourceControl.fileRows.addedByThem', 'Added by them') + case 'both_deleted': + return t('sourceControl.fileRows.bothDeleted', 'Both deleted') + default: + return t('sourceControl.fileRows.unresolvedConflict', 'Unresolved conflict') + } +} + +export function makeRenderFileRow(state: RowState, t: Translate) { const { busyAction, openingPath, openingBranchPath, openFile, runGitAction, setDiscardTarget } = state - return function FileRow({ item }: { item: MobileGitStatusEntryView }) { + return function renderFileRow({ item }: { item: MobileGitStatusEntryView }) { const rowBusy = busyAction === item.stageActionId || busyAction === item.unstageActionId || @@ -45,7 +68,13 @@ export function makeRenderFileRow(state: RowState) { ]} onPress={() => void openFile(item)} disabled={rowDisabled} - accessibilityLabel={`Open changed file ${item.path}`} + accessibilityLabel={t( + 'sourceControl.fileRows.openChangedFile', + 'Open changed file {{path}}', + { + path: item.path + } + )} > @@ -66,11 +95,11 @@ export function makeRenderFileRow(state: RowState) { {item.oldPath ? ( - from {item.oldPath} + {t('sourceControl.fileRows.renamedFrom', 'from {{path}}', { path: item.oldPath })} ) : item.conflictStatus === 'unresolved' ? ( - {item.conflictKind ? CONFLICT_KIND_LABELS[item.conflictKind] : 'Unresolved conflict'} + {conflictKindLabel(item.conflictKind, t)} ) : null} @@ -88,7 +117,9 @@ export function makeRenderFileRow(state: RowState) { void runGitAction(item.unstageActionId, 'git.unstage', { filePath: item.path }) } hitSlop={8} - accessibilityLabel={`Unstage ${item.path}`} + accessibilityLabel={t('sourceControl.fileRows.unstageFile', 'Unstage {{path}}', { + path: item.path + })} > @@ -106,7 +137,9 @@ export function makeRenderFileRow(state: RowState) { void runGitAction(item.stageActionId, 'git.stage', { filePath: item.path }) } hitSlop={8} - accessibilityLabel={`Stage ${item.path}`} + accessibilityLabel={t('sourceControl.fileRows.stageFile', 'Stage {{path}}', { + path: item.path + })} > @@ -121,7 +154,9 @@ export function makeRenderFileRow(state: RowState) { disabled={ioBusy} onPress={() => setDiscardTarget(item)} hitSlop={8} - accessibilityLabel={`Discard ${item.path}`} + accessibilityLabel={t('sourceControl.fileRows.discardFile', 'Discard {{path}}', { + path: item.path + })} > @@ -151,6 +186,7 @@ type BranchState = Pick< export function BranchCompareHeader({ state }: { state: BranchState }) { useMobileColorScheme() + const t = useMobileTranslation() const { shouldShowBranchCompareSection, branchCompareSummaryText, @@ -166,7 +202,9 @@ export function BranchCompareHeader({ state }: { state: BranchState }) { - Committed on Branch + + {t('sourceControl.fileRows.committedSection', 'Committed on Branch')} + {branchCompareSummaryText ? ( {branchCompareSummaryText} @@ -178,7 +216,9 @@ export function BranchCompareHeader({ state }: { state: BranchState }) { {branchCompareState.kind === 'loading' ? ( - Loading committed changes... + + {t('sourceControl.fileRows.loadingCommitted', 'Loading committed changes...')} + ) : branchCompareState.kind === 'error' ? ( @@ -187,7 +227,8 @@ export function BranchCompareHeader({ state }: { state: BranchState }) { ) : branchCompareResult && branchCompareResult.summary.status !== 'ready' ? ( - {branchCompareResult.summary.errorMessage ?? 'Committed changes unavailable.'} + {branchCompareResult.summary.errorMessage ?? + t('sourceControl.fileRows.committedUnavailable', 'Committed changes unavailable.')} ) : null} @@ -203,6 +244,7 @@ export function BranchFileRow({ state: BranchState }) { useMobileColorScheme() + const t = useMobileTranslation() const { busyAction, openBranchDiff, openingBranchPath, openingPath } = state const rowBusy = openingBranchPath === entry.path const rowDisabled = @@ -218,7 +260,13 @@ export function BranchFileRow({ ]} onPress={() => void openBranchDiff(entry)} disabled={rowDisabled} - accessibilityLabel={`Open committed change ${entry.path}`} + accessibilityLabel={t( + 'sourceControl.fileRows.openCommittedChange', + 'Open committed change {{path}}', + { + path: entry.path + } + )} > diff --git a/mobile/src/source-control/MobileSourceControlHeader.tsx b/mobile/src/source-control/MobileSourceControlHeader.tsx index c2d14b0e321..ab5a5baea1c 100644 --- a/mobile/src/source-control/MobileSourceControlHeader.tsx +++ b/mobile/src/source-control/MobileSourceControlHeader.tsx @@ -2,6 +2,7 @@ import { Pressable, Text, View } from 'react-native' import { ChevronLeft, ExternalLink, RefreshCw, X } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { styles } from './mobile-source-control-styles' type Props = { @@ -28,6 +29,7 @@ export function MobileSourceControlHeader({ prNumber = null }: Props) { useMobileColorScheme() + const t = useMobileTranslation() return ( {/* Dock dismissal and route Back have distinct semantics. */} @@ -37,7 +39,7 @@ export function MobileSourceControlHeader({ onPress={onClose} hitSlop={8} accessibilityRole="button" - accessibilityLabel="Close source control" + accessibilityLabel={t('sourceControl.header.close', 'Close source control')} > @@ -47,14 +49,14 @@ export function MobileSourceControlHeader({ onPress={onBack} hitSlop={8} accessibilityRole="button" - accessibilityLabel="Back to session" + accessibilityLabel={t('sourceControl.header.backToSession', 'Back to session')} > )} - Source Control + {t('sourceControl.header.title', 'Source Control')} {worktreeLabel} @@ -68,8 +70,14 @@ export function MobileSourceControlHeader({ accessibilityRole="link" accessibilityLabel={ prNumber != null - ? `Open pull request #${prNumber} on the web` - : 'Open pull request on the web' + ? t( + 'sourceControl.header.openNumberedPrWeb', + 'Open pull request #{{number}} on the web', + { + number: prNumber + } + ) + : t('sourceControl.header.openPrWeb', 'Open pull request on the web') } > @@ -85,7 +93,7 @@ export function MobileSourceControlHeader({ disabled={ioBusy} hitSlop={8} accessibilityRole="button" - accessibilityLabel="Refresh source control" + accessibilityLabel={t('sourceControl.header.refresh', 'Refresh source control')} > diff --git a/mobile/src/source-control/MobileSourceControlModals.tsx b/mobile/src/source-control/MobileSourceControlModals.tsx index 74bf587ae00..5d84c31eb2e 100644 --- a/mobile/src/source-control/MobileSourceControlModals.tsx +++ b/mobile/src/source-control/MobileSourceControlModals.tsx @@ -2,6 +2,7 @@ import { ActionSheetModal, type ActionSheetAction } from '../components/ActionSh import { ConfirmModal } from '../components/ConfirmModal' import { PickerModal } from '../components/PickerModal' import { openMobilePrUrl } from '../components/mobile-pr-url' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { MobileBranchDiffPreviewDrawer } from './MobileBranchDiffPreviewDrawer' import type { MobileSourceControlState } from './use-mobile-source-control-state' @@ -11,6 +12,7 @@ type Props = { } export function MobileSourceControlModals({ state, actionSheetActions }: Props) { + const t = useMobileTranslation() const { branchDiffPreview, setBranchDiffPreview, @@ -39,7 +41,7 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props) setShowActionSheet(false)} @@ -47,13 +49,17 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props) { if (discardTarget) { @@ -68,11 +74,14 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props) ({ value: b, label: b, - subtitle: b === localBranches?.current ? 'current' : undefined + subtitle: + b === localBranches?.current + ? t('sourceControl.modals.currentBranch', 'current') + : undefined }))} selected={localBranches?.current ?? ''} onSelect={(branch) => { @@ -87,13 +96,19 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props) { if (createdPrUrl) { openMobilePrUrl(createdPrUrl) diff --git a/mobile/src/source-control/MobileSourceControlPanel.tsx b/mobile/src/source-control/MobileSourceControlPanel.tsx index 83325a35761..a6537f72453 100644 --- a/mobile/src/source-control/MobileSourceControlPanel.tsx +++ b/mobile/src/source-control/MobileSourceControlPanel.tsx @@ -264,12 +264,14 @@ export function MobileSourceControlPanel({ ) : screenState.kind === 'error' || screenState.kind === 'unavailable' ? ( - {screenState.kind === 'unavailable' ? 'Source Control Unavailable' : 'Unable to Load'} + {screenState.kind === 'unavailable' + ? t('sourceControl.panel.unavailableTitle', 'Source Control Unavailable') + : t('sourceControl.panel.loadFailedTitle', 'Unable to Load')} {screenState.message} {screenState.kind === 'error' && statusRetry ? ( - Retry + {t('common.retry', 'Retry')} ) : null} diff --git a/mobile/src/source-control/MobileSourceControlPrChip.tsx b/mobile/src/source-control/MobileSourceControlPrChip.tsx index 2e5a6e63543..32318b52eb3 100644 --- a/mobile/src/source-control/MobileSourceControlPrChip.tsx +++ b/mobile/src/source-control/MobileSourceControlPrChip.tsx @@ -10,6 +10,8 @@ import { } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { useMobileColorScheme } from '../theme/use-mobile-color-scheme' +import type { Translate } from '../i18n/mobile-i18n' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { statusColor } from '../components/pr-sidebar/pr-sidebar-status-color' import { hubStyles } from './mobile-source-control-hub-styles' import type { MobilePrChipRollup, MobilePrChipSummary } from './mobile-pr-chip-summary' @@ -21,12 +23,13 @@ type Props = { export function MobileSourceControlPrChip({ summary, onPress }: Props) { useMobileColorScheme() + const t = useMobileTranslation() return ( [hubStyles.chip, pressed && hubStyles.chipPressed]} onPress={onPress} accessibilityRole="button" - accessibilityLabel={chipAccessibilityLabel(summary)} + accessibilityLabel={chipAccessibilityLabel(summary, t)} > @@ -35,12 +38,14 @@ export function MobileSourceControlPrChip({ summary, onPress }: Props) { <> - Loading pull request… + {t('sourceControl.prChip.loading', 'Loading pull request…')} ) : summary.kind === 'none' ? ( <> - Create pull request + + {t('sourceControl.prChip.createPr', 'Create pull request')} + @@ -102,20 +107,41 @@ function RollupIcon({ kind, color }: { kind: MobilePrChipRollup['kind']; color: } } -function chipAccessibilityLabel(summary: MobilePrChipSummary): string { +function chipAccessibilityLabel(summary: MobilePrChipSummary, t: Translate): string { switch (summary.kind) { case 'loading': - return 'Loading pull request' + return t('sourceControl.prChip.loadingLabel', 'Loading pull request') case 'none': - return 'Create pull request' + return t('sourceControl.prChip.createPr', 'Create pull request') case 'unavailable': - return `Pull request unavailable: ${summary.message}` + return t('sourceControl.prChip.unavailableLabel', 'Pull request unavailable: {{message}}', { + message: summary.message + }) case 'ready': { - const comments = - summary.commentCount != null && summary.commentCount > 0 - ? `, ${summary.commentCount} unresolved comments` - : '' - return `Pull request #${summary.number}, ${summary.stateLabel}, ${summary.rollup.text}${comments}. Open pull request.` + const count = summary.commentCount + const details = { + number: summary.number, + state: summary.stateLabel, + checks: summary.rollup.text + } + if (count != null && count > 0) { + return count === 1 + ? t( + 'sourceControl.prChip.openWithComments_one', + 'Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.', + { ...details, count } + ) + : t( + 'sourceControl.prChip.openWithComments_other', + 'Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.', + { ...details, count } + ) + } + return t( + 'sourceControl.prChip.openLabel', + 'Pull request #{{number}}, {{state}}, {{checks}}. Open pull request.', + details + ) } } } diff --git a/mobile/src/source-control/hosted-review-copy.ts b/mobile/src/source-control/hosted-review-copy.ts index cd2a4b4ad0f..f12c3034711 100644 --- a/mobile/src/source-control/hosted-review-copy.ts +++ b/mobile/src/source-control/hosted-review-copy.ts @@ -1,4 +1,5 @@ import { translate } from '../i18n/mobile-i18n' +import type { MobileHostedReviewCreateIntentProgress } from './mobile-hosted-review-create-intent' // Use the desktop provider vocabulary: GitLab says Merge Request. export type HostedReviewCopy = { @@ -26,3 +27,29 @@ function mrCopy(): HostedReviewCopy { export function hostedReviewCopy(provider: string | undefined): HostedReviewCopy { return provider === 'gitlab' ? mrCopy() : prCopy() } + +export function mobileHostedReviewCreateIntentProgressMessage( + progress: MobileHostedReviewCreateIntentProgress +): string { + switch (progress) { + case 'fast_forwarding': + return translate('sourceControl.hostedReviewCopy.updatingBranch', 'Updating branch...') + case 'staging': + return translate('sourceControl.hostedReviewCopy.stagingChanges', 'Staging changes...') + case 'generating_commit_message': + return translate( + 'sourceControl.hostedReviewCopy.generatingCommitMessage', + 'Generating commit message...' + ) + case 'committing': + return translate('sourceControl.hostedReviewCopy.committingChanges', 'Committing changes...') + case 'publishing': + return translate('sourceControl.hostedReviewCopy.publishingBranch', 'Publishing branch...') + case 'pushing': + return translate('sourceControl.hostedReviewCopy.pushingCommits', 'Pushing commits...') + case 'force_pushing': + return translate('sourceControl.hostedReviewCopy.forcePushing', 'Force pushing with lease...') + case 'creating_review': + return translate('sourceControl.hostedReviewCopy.creatingReview', 'Creating review...') + } +} diff --git a/mobile/src/source-control/mobile-branch-base-ref.ts b/mobile/src/source-control/mobile-branch-base-ref.ts index 005ff5450dd..67d6593ed9d 100644 --- a/mobile/src/source-control/mobile-branch-base-ref.ts +++ b/mobile/src/source-control/mobile-branch-base-ref.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message' import { getRepoIdFromWorktreeId } from '../../../src/shared/worktree/id' import { isMobileGitUnavailableReply } from './mobile-git-status' @@ -87,6 +88,11 @@ async function readDefaultBaseRef( try { return repoDefaultBaseRefRead.interpret(defaultReply) } catch (error) { - throw new Error(refusedRpcMessageOrFallback(error, 'Unable to resolve branch base')) + throw new Error( + refusedRpcMessageOrFallback( + error, + translate('sourceControl.branchBaseRef.resolveFailed', 'Unable to resolve branch base') + ) + ) } } diff --git a/mobile/src/source-control/mobile-branch-compare-outcome.ts b/mobile/src/source-control/mobile-branch-compare-outcome.ts index 56d75c127b0..2b2a54a3e1f 100644 --- a/mobile/src/source-control/mobile-branch-compare-outcome.ts +++ b/mobile/src/source-control/mobile-branch-compare-outcome.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import type { RpcOperationSender } from '../transport/rpc-operation-sender' import type { RequestCurrency } from '../transport/generation-scoped-request-owner' import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message' @@ -51,7 +52,13 @@ async function readCompare( baseRef: string | null ): Promise { if (!baseRef) { - return { kind: 'failed', message: 'Unable to resolve the base branch for comparison.' } + return { + kind: 'failed', + message: translate( + 'sourceControl.branchCompareOutcome.baseBranchUnavailable', + 'Unable to resolve the base branch for comparison.' + ) + } } try { const reply = await gitBranchCompareRead.request(client, { @@ -67,7 +74,13 @@ async function readCompare( } catch (error) { return { kind: 'failed', - message: refusedRpcMessageOrFallback(error, 'Unable to load committed changes') + message: refusedRpcMessageOrFallback( + error, + translate( + 'sourceControl.branchCompareOutcome.loadFailed', + 'Unable to load committed changes' + ) + ) } } } catch (err) { @@ -78,7 +91,13 @@ async function readCompare( function failedCompare(err: unknown): BranchCompareOutcome { return { kind: 'failed', - message: err instanceof Error ? err.message : 'Unable to load committed changes' + message: + err instanceof Error + ? err.message + : translate( + 'sourceControl.branchCompareOutcome.loadFailed', + 'Unable to load committed changes' + ) } } diff --git a/mobile/src/source-control/mobile-branch-compare.ts b/mobile/src/source-control/mobile-branch-compare.ts index 700ca3b25a2..298a41f3e81 100644 --- a/mobile/src/source-control/mobile-branch-compare.ts +++ b/mobile/src/source-control/mobile-branch-compare.ts @@ -1,4 +1,5 @@ import { compareFileNames } from '../../../src/shared/file-name-sort' +import { translate } from '../i18n/mobile-i18n' import type { MobileGitBranchChangeEntry, MobileGitBranchCompareReply, @@ -11,7 +12,7 @@ export type MobileGitBranchCompareResult = MobileGitBranchCompareReply export type MobileBranchCompareSection< TEntry extends MobileGitBranchChangeEntry = MobileGitBranchChangeEntry > = { - title: 'Committed on Branch' + title: string data: TEntry[] } @@ -24,7 +25,7 @@ export function buildMobileBranchCompareSection compareFileNames(a.path, b.path)) return { - title: 'Committed on Branch', + title: translate('sourceControl.branchCompare.sectionTitle', 'Committed on Branch'), data } } @@ -35,12 +36,30 @@ export function formatMobileBranchCompareSummary( if (summary.status !== 'ready') { return summary.errorMessage ?? null } - const parts = [`${summary.changedFiles} ${summary.changedFiles === 1 ? 'file' : 'files'}`] - if (summary.commitsAhead !== undefined) { - parts.push(`${summary.commitsAhead} ${summary.commitsAhead === 1 ? 'commit' : 'commits'}`) + const files = branchCompareFiles(summary.changedFiles) + if (summary.commitsAhead === undefined) { + return translate('sourceControl.branchCompare.summary', '{{files}} - vs {{baseRef}}', { + files, + baseRef: summary.baseRef + }) } - parts.push(`vs ${summary.baseRef}`) - return parts.join(' - ') + return translate( + 'sourceControl.branchCompare.summaryWithCommits', + '{{files}} - {{commits}} - vs {{baseRef}}', + { files, commits: branchCompareCommits(summary.commitsAhead), baseRef: summary.baseRef } + ) +} + +function branchCompareFiles(count: number): string { + return count === 1 + ? translate('sourceControl.branchCompare.files_one', '{{count}} file', { count }) + : translate('sourceControl.branchCompare.files_other', '{{count}} files', { count }) +} + +function branchCompareCommits(count: number): string { + return count === 1 + ? translate('sourceControl.branchCompare.commits_one', '{{count}} commit', { count }) + : translate('sourceControl.branchCompare.commits_other', '{{count}} commits', { count }) } export function canOpenMobileBranchCompareDiff(summary: MobileGitBranchCompareSummary): boolean { diff --git a/mobile/src/source-control/mobile-commit-message-ai.ts b/mobile/src/source-control/mobile-commit-message-ai.ts index 7dbdfe2b0b6..ceaca03db41 100644 --- a/mobile/src/source-control/mobile-commit-message-ai.ts +++ b/mobile/src/source-control/mobile-commit-message-ai.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message' import { gitCancelGenerateCommitMessageRun, @@ -21,7 +22,13 @@ export async function requestMobileCommitMessage( } catch (error) { return { success: false, - error: refusedRpcMessageOrFallback(error, 'Failed to generate commit message') + error: refusedRpcMessageOrFallback( + error, + translate( + 'sourceControl.commitMessageAi.generateFailed', + 'Failed to generate commit message' + ) + ) } } } diff --git a/mobile/src/source-control/mobile-create-pr-action.ts b/mobile/src/source-control/mobile-create-pr-action.ts index 63b6eb8e592..5bb46d89ff9 100644 --- a/mobile/src/source-control/mobile-create-pr-action.ts +++ b/mobile/src/source-control/mobile-create-pr-action.ts @@ -40,7 +40,7 @@ const BUSY_ACTIONS = new Set(['create-pr', 'push-create-pr']) function hiddenAction(onPress: () => void): MobileCreatePrAction { return { visible: false, - label: 'Create Pull Request', + label: translate('sourceControl.createPrAction.createPullRequest', 'Create Pull Request'), disabled: true, loading: false, pushFirst: false, @@ -62,7 +62,10 @@ export function buildMobileCreatePrAction({ if (eligibilityState.kind === 'error') { return { visible: true, - label: 'Review status unavailable', + label: translate( + 'sourceControl.createPrAction.statusUnavailable', + 'Review status unavailable' + ), disabled: true, loading: false, pushFirst: false, @@ -73,7 +76,7 @@ export function buildMobileCreatePrAction({ if (!eligibility) { return { visible: true, - label: 'Checking review status…', + label: translate('sourceControl.createPrAction.checkingStatus', 'Checking review status…'), disabled: true, loading: true, pushFirst: false, @@ -84,7 +87,10 @@ export function buildMobileCreatePrAction({ if (!supportsHostedReviewCreation(eligibility.provider)) { return { visible: true, - label: 'Review creation unavailable for this provider', + label: translate( + 'sourceControl.createPrAction.providerUnavailable', + 'Review creation unavailable for this provider' + ), disabled: true, loading: false, pushFirst: false, diff --git a/mobile/src/source-control/mobile-git-history.ts b/mobile/src/source-control/mobile-git-history.ts index da77e94bcfd..fd98aa23359 100644 --- a/mobile/src/source-control/mobile-git-history.ts +++ b/mobile/src/source-control/mobile-git-history.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import type { MobileGitHistoryItem, MobileGitHistoryResult } from './git-history-reply-schema' import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message' import { gitHistoryRead } from './mobile-git-read-operations' @@ -19,32 +20,48 @@ export function formatCommitTime(timestampMs: number | null | undefined, nowMs: } const delta = nowMs - timestampMs if (delta < 60_000) { - return 'just now' + return translate('sourceControl.gitHistory.justNow', 'just now') } const minutes = Math.floor(delta / 60_000) if (minutes < 60) { - return `${minutes}m` + const count = minutes + return count === 1 + ? translate('sourceControl.gitHistory.minutes_one', '{{count}}m', { count }) + : translate('sourceControl.gitHistory.minutes_other', '{{count}}m', { count }) } const hours = Math.floor(minutes / 60) if (hours < 24) { - return `${hours}h` + const count = hours + return count === 1 + ? translate('sourceControl.gitHistory.hours_one', '{{count}}h', { count }) + : translate('sourceControl.gitHistory.hours_other', '{{count}}h', { count }) } const days = Math.floor(hours / 24) if (days < 30) { - return `${days}d` + const count = days + return count === 1 + ? translate('sourceControl.gitHistory.days_one', '{{count}}d', { count }) + : translate('sourceControl.gitHistory.days_other', '{{count}}d', { count }) } const months = Math.floor(days / 30) if (months < 12) { - return `${months}mo` + const count = months + return count === 1 + ? translate('sourceControl.gitHistory.months_one', '{{count}}mo', { count }) + : translate('sourceControl.gitHistory.months_other', '{{count}}mo', { count }) } - return `${Math.floor(months / 12)}y` + const count = Math.floor(months / 12) + return count === 1 + ? translate('sourceControl.gitHistory.years_one', '{{count}}y', { count }) + : translate('sourceControl.gitHistory.years_other', '{{count}}y', { count }) } export function toMobileCommitRow(item: MobileGitHistoryItem, nowMs: number): MobileCommitRow { return { id: item.id, shortId: item.displayId ?? item.id.slice(0, 7), - subject: item.subject || '(no commit message)', + subject: + item.subject || translate('sourceControl.gitHistory.noCommitMessage', '(no commit message)'), author: item.author ?? '', parentId: item.parentIds[0] ?? null, relativeTime: formatCommitTime(item.timestamp, nowMs) @@ -68,6 +85,11 @@ export async function fetchMobileGitHistory( try { return gitHistoryRead.interpret(reply) } catch (error) { - throw new Error(refusedRpcMessageOrFallback(error, 'Failed to load commit history')) + throw new Error( + refusedRpcMessageOrFallback( + error, + translate('sourceControl.gitHistory.loadFailed', 'Failed to load commit history') + ) + ) } } diff --git a/mobile/src/source-control/mobile-git-status.ts b/mobile/src/source-control/mobile-git-status.ts index 5af47044483..2982d208f9e 100644 --- a/mobile/src/source-control/mobile-git-status.ts +++ b/mobile/src/source-control/mobile-git-status.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import type { GitFileStatus, GitStagingArea } from '../../../src/shared/git-status-types' import { buildSourceControlDisplaySections, @@ -43,10 +44,12 @@ export type MobileSourceControlSection = { - conflicts: 'Conflicts', - unstaged: 'Changes', - staged: 'Staged Changes' +function sectionTitles(): Record { + return { + conflicts: translate('sourceControl.gitStatus.conflicts', 'Conflicts'), + unstaged: translate('sourceControl.gitStatus.changes', 'Changes'), + staged: translate('sourceControl.gitStatus.stagedChanges', 'Staged Changes') + } } // Desktop's sections: conflicts pinned on top, then the user's group order, sorted like desktop. @@ -54,13 +57,14 @@ export function buildMobileSourceControlSections[] { + const titles = sectionTitles() return buildSourceControlDisplaySections( groupSourceControlEntries(entries.filter(hasKnownArea)), resolveSourceControlGroupOrder(groupOrder) ).map((section) => ({ id: section.id, area: section.area, - title: SECTION_TITLES[section.id], + title: titles[section.id], data: section.items })) } diff --git a/mobile/src/source-control/mobile-hosted-review-create-intent.ts b/mobile/src/source-control/mobile-hosted-review-create-intent.ts index e6560ceb3f3..e9eeb62da1a 100644 --- a/mobile/src/source-control/mobile-hosted-review-create-intent.ts +++ b/mobile/src/source-control/mobile-hosted-review-create-intent.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import { requestMobileCommitMessage } from './mobile-commit-message-ai' import { getStageablePaths, type MobileGitStatusResult } from './mobile-git-status' import { getMobilePrEligibilityReadiness } from './mobile-open-pr-prefill' @@ -13,6 +14,8 @@ import { import { applyMobileHostedReviewRemotePrerequisite } from './mobile-hosted-review-remote-prerequisite' import type { RpcOperationSender } from '../transport/rpc-operation-sender' +export { mobileHostedReviewCreateIntentProgressMessage } from './hosted-review-copy' + export type MobileHostedReviewCreateIntentProgress = | 'fast_forwarding' | 'staging' @@ -50,29 +53,6 @@ type PrepareInput = { onProgress?: (progress: MobileHostedReviewCreateIntentProgress) => void } -export function mobileHostedReviewCreateIntentProgressMessage( - progress: MobileHostedReviewCreateIntentProgress -): string { - switch (progress) { - case 'fast_forwarding': - return 'Updating branch...' - case 'staging': - return 'Staging changes...' - case 'generating_commit_message': - return 'Generating commit message...' - case 'committing': - return 'Committing changes...' - case 'publishing': - return 'Publishing branch...' - case 'pushing': - return 'Pushing commits...' - case 'force_pushing': - return 'Force pushing with lease...' - case 'creating_review': - return 'Creating review...' - } -} - function hasUnresolvedConflicts(status: MobileGitStatusResult | null): boolean { return status?.entries.some((entry) => entry.conflictStatus === 'unresolved') === true } @@ -106,7 +86,10 @@ async function ensureLocalChangesCommitted( if (hasUnresolvedConflicts(currentStatus)) { return { ok: false, - error: 'Resolve conflicts before creating a pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.resolveConflicts', + 'Resolve conflicts before creating a pull request.' + ), committed: false, status: currentStatus } @@ -132,7 +115,10 @@ async function ensureLocalChangesCommitted( if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) { return { ok: false, - error: 'Branch changed while preparing the pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.branchChanged', + 'Branch changed while preparing the pull request.' + ), committed: false, status: currentStatus } @@ -143,7 +129,10 @@ async function ensureLocalChangesCommitted( if (!hasStagedChanges) { return { ok: false, - error: 'Resolve or stage changes before creating a pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.resolveOrStageChanges', + 'Resolve or stage changes before creating a pull request.' + ), committed: false, status: currentStatus } @@ -156,7 +145,10 @@ async function ensureLocalChangesCommitted( if (!generated.success) { return { ok: false, - error: 'Could not generate a commit message. Add one in Source Control, then retry.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.generateMessageFailed', + 'Could not generate a commit message. Add one in Source Control, then retry.' + ), committed: false, status: currentStatus } @@ -164,7 +156,10 @@ async function ensureLocalChangesCommitted( if (input.readCommitMessage?.().trim()) { return { ok: false, - error: 'Review the commit message, then retry Create PR.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.reviewCommitMessage', + 'Review the commit message, then retry Create PR.' + ), committed: false, status: currentStatus } @@ -202,7 +197,10 @@ async function ensureLocalChangesCommitted( if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) { return { ok: false, - error: 'Branch changed while preparing the pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.branchChanged', + 'Branch changed while preparing the pull request.' + ), committed: true, status: currentStatus } @@ -221,7 +219,10 @@ export async function prepareMobileHostedReviewCreateIntent( return { ok: false, error: initialStatus.ok - ? 'Branch changed while preparing the pull request.' + ? translate( + 'sourceControl.hostedReviewCreateIntent.branchChanged', + 'Branch changed while preparing the pull request.' + ) : initialStatus.error, status: currentStatus } @@ -242,7 +243,10 @@ export async function prepareMobileHostedReviewCreateIntent( if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) { return { ok: false, - error: 'Branch changed while preparing the pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.branchChanged', + 'Branch changed while preparing the pull request.' + ), status: currentStatus } } @@ -285,7 +289,10 @@ export async function prepareMobileHostedReviewCreateIntent( if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) { return { ok: false, - error: 'Branch changed while preparing the pull request.', + error: translate( + 'sourceControl.hostedReviewCreateIntent.branchChanged', + 'Branch changed while preparing the pull request.' + ), committed: committed.committed, status: currentStatus } diff --git a/mobile/src/source-control/mobile-hosted-review-git-preparation.ts b/mobile/src/source-control/mobile-hosted-review-git-preparation.ts index 858bc715496..de1cf1b500b 100644 --- a/mobile/src/source-control/mobile-hosted-review-git-preparation.ts +++ b/mobile/src/source-control/mobile-hosted-review-git-preparation.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import type { RpcSendParams } from '../transport/rpc-params-contract' import { hostReplyErrorTextOrFallback, @@ -30,7 +31,13 @@ export async function readMobileHostedReviewGitStatus( } catch (error) { return { ok: false, - error: refusedRpcMessageOrFallback(error, 'Unable to refresh source control') + error: refusedRpcMessageOrFallback( + error, + translate( + 'sourceControl.hostedReviewGitPreparation.refreshFailed', + 'Unable to refresh source control' + ) + ) } } } @@ -82,7 +89,10 @@ export function fastForwardMobileHostedReviewBranch( return settleMobileHostedReviewMutation( () => gitFastForwardRun.request(client, { worktree: `id:${worktreeId}` }), (reply) => gitFastForwardRun.interpret(reply), - 'Could not update the remote branch. Retry Create PR.' + translate( + 'sourceControl.hostedReviewGitPreparation.updateBranchFailed', + 'Could not update the remote branch. Retry Create PR.' + ) ) } @@ -94,7 +104,7 @@ export function stageMobileHostedReviewPaths( return settleMobileHostedReviewMutation( () => gitBulkStageRun.request(client, { worktree: `id:${worktreeId}`, filePaths }), (reply) => gitBulkStageRun.interpret(reply), - 'Failed to stage changes' + translate('sourceControl.hostedReviewGitPreparation.stageFailed', 'Failed to stage changes') ) } @@ -107,16 +117,34 @@ export async function commitMobileHostedReviewStagedChanges( try { reply = await gitCommitRun.request(client, { worktree: `id:${worktreeId}`, message }) } catch (error) { - return { ok: false, error: error instanceof Error ? error.message : 'Commit failed' } + return { + ok: false, + error: + error instanceof Error + ? error.message + : translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed') + } } let outcome: ReturnType try { outcome = gitCommitRun.interpret(reply) } catch (error) { - return { ok: false, error: refusedRpcMessageOrFallback(error, 'Commit failed') } + return { + ok: false, + error: refusedRpcMessageOrFallback( + error, + translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed') + ) + } } // Acceptance can still carry an in-band commit failure. return outcome.success === true ? { ok: true } - : { ok: false, error: hostReplyErrorTextOrFallback(outcome.error, 'Commit failed') } + : { + ok: false, + error: hostReplyErrorTextOrFallback( + outcome.error, + translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed') + ) + } } diff --git a/mobile/src/source-control/mobile-hosted-review-remote-prerequisite.ts b/mobile/src/source-control/mobile-hosted-review-remote-prerequisite.ts index ec9bba206b9..765919a0034 100644 --- a/mobile/src/source-control/mobile-hosted-review-remote-prerequisite.ts +++ b/mobile/src/source-control/mobile-hosted-review-remote-prerequisite.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import { resolveCreatePrIntentRemoteStep } from '../../../src/shared/source-control-create-review-intent' import type { MobileGitStatusResult } from './mobile-git-status' import type { MobileHostedReviewCreateIntentProgress } from './mobile-hosted-review-create-intent' @@ -50,19 +51,32 @@ export async function applyMobileHostedReviewRemotePrerequisite( result = await pushMobileHostedReviewBranch( client, { worktree, publish: true }, - 'Failed to publish branch' + translate( + 'sourceControl.hostedReviewRemotePrerequisite.publishFailed', + 'Failed to publish branch' + ) ) break case 'push': input.onProgress?.('pushing') - result = await pushMobileHostedReviewBranch(client, { worktree }, 'Failed to push commits') + result = await pushMobileHostedReviewBranch( + client, + { worktree }, + translate( + 'sourceControl.hostedReviewRemotePrerequisite.pushFailed', + 'Failed to push commits' + ) + ) break case 'force_push': input.onProgress?.('force_pushing') result = await pushMobileHostedReviewBranch( client, { worktree, forceWithLease: true }, - 'Failed to force push with lease' + translate( + 'sourceControl.hostedReviewRemotePrerequisite.forcePushFailed', + 'Failed to force push with lease' + ) ) break case 'fast_forward': diff --git a/mobile/src/source-control/mobile-hosted-review-service.ts b/mobile/src/source-control/mobile-hosted-review-service.ts index 01dd8349b9e..32cb4eb7d2e 100644 --- a/mobile/src/source-control/mobile-hosted-review-service.ts +++ b/mobile/src/source-control/mobile-hosted-review-service.ts @@ -162,19 +162,17 @@ export type MobileHostedReviewCreateOutcome = | { ok: true; url: string; number?: number; existing?: boolean; linkError?: string } | { ok: false; error: string } -const PUSH_BEFORE_CREATE_ERROR = 'Push failed. Resolve the push error, then try again.' - // The form intentionally uses one actionable fallback for all push failures. async function pushMobileBranchBeforeCreate( client: RpcOperationSender, worktreeId: string ): Promise<{ ok: true } | { ok: false; error: string }> { - const pushed = await pushMobileHostedReviewBranch( - client, - { worktree: `id:${worktreeId}` }, - PUSH_BEFORE_CREATE_ERROR + const error = translate( + 'sourceControl.hostedReviewService.pushBeforeCreateFailed', + 'Push failed. Resolve the push error, then try again.' ) - return pushed.ok ? { ok: true } : { ok: false, error: PUSH_BEFORE_CREATE_ERROR } + const pushed = await pushMobileHostedReviewBranch(client, { worktree: `id:${worktreeId}` }, error) + return pushed.ok ? { ok: true } : { ok: false, error } } function formatMobileHostedReviewCreateError( @@ -244,7 +242,13 @@ export async function createMobileHostedReview( } catch (error) { return { ok: false, - error: refusedRpcMessageOrFallback(error, 'Failed to create pull request') + error: refusedRpcMessageOrFallback( + error, + translate( + 'sourceControl.hostedReviewService.createFailed', + 'Failed to create pull request' + ) + ) } } if (result.ok) { @@ -271,13 +275,19 @@ export async function createMobileHostedReview( ok: false, error: formatMobileHostedReviewCreateError(result, pushed, input.provider) || - 'Failed to create pull request' + translate('sourceControl.hostedReviewService.createFailed', 'Failed to create pull request') } } catch (err) { // Inline creation must display transport errors instead of leaking rejected promises. return { ok: false, - error: err instanceof Error ? err.message : 'Failed to create pull request' + error: + err instanceof Error + ? err.message + : translate( + 'sourceControl.hostedReviewService.createFailed', + 'Failed to create pull request' + ) } } } diff --git a/mobile/src/source-control/mobile-pr-link.ts b/mobile/src/source-control/mobile-pr-link.ts index f23d54f844f..045396580ca 100644 --- a/mobile/src/source-control/mobile-pr-link.ts +++ b/mobile/src/source-control/mobile-pr-link.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import type { RpcSendParams } from '../transport/rpc-params-contract' import { CLEARED_HOSTED_REVIEW_SELECTION_UPDATES } from '../../../src/shared/worktree/hosted-review-links' import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message' @@ -79,7 +80,10 @@ export function linkMobilePr( return setWorktreeReviewLink( client, buildWorktreeSetLinkParams(worktreeId, prNumber), - 'Failed to update linked pull request' + translate( + 'sourceControl.prLink.updatePullRequestFailed', + 'Failed to update linked pull request' + ) ) } @@ -95,7 +99,11 @@ export async function linkMobileHostedReview( return { ok: true } } // Link refresh failure is nonfatal: the review already exists, so keep its URL. - return setWorktreeReviewLink(client, params, 'Failed to update linked review') + return setWorktreeReviewLink( + client, + params, + translate('sourceControl.prLink.updateReviewFailed', 'Failed to update linked review') + ) } // Like desktop, suppress the unlinked PR so branch discovery does not bring it straight back. @@ -107,7 +115,10 @@ export function unlinkMobilePr( return setWorktreeReviewLink( client, { ...buildWorktreeSetLinkParams(worktreeId, null), suppressedGitHubPR: prNumber }, - 'Failed to update linked pull request' + translate( + 'sourceControl.prLink.updatePullRequestFailed', + 'Failed to update linked pull request' + ) ) } @@ -131,7 +142,10 @@ export async function clearMobileWorktreeReviewLink( await setWorktreeReviewLink( client, { worktree: `id:${worktreeId}`, ...CLEARED_HOSTED_REVIEW_SELECTION_UPDATES }, - 'Failed to update linked pull request' + translate( + 'sourceControl.prLink.updatePullRequestFailed', + 'Failed to update linked pull request' + ) ) } diff --git a/mobile/src/source-control/mobile-source-control-actions.ts b/mobile/src/source-control/mobile-source-control-actions.ts index 59442159528..b74af62f3c7 100644 --- a/mobile/src/source-control/mobile-source-control-actions.ts +++ b/mobile/src/source-control/mobile-source-control-actions.ts @@ -1,4 +1,5 @@ -import { translate, type Translate } from '../i18n/mobile-i18n' +import { translate } from '../i18n/mobile-i18n' +import type { Translate } from '../i18n/mobile-i18n' import { mobileCommitDropdownCopy } from './mobile-commit-dropdown-copy' import { mobileRemoteDropdownCopy } from './mobile-remote-dropdown-copy' import type { GitConflictOperation } from '../../../src/shared/git-status-types' @@ -6,6 +7,7 @@ import { deriveDropdownActionContext } from '../../../src/shared/source-control- import { buildCommitDropdownItems } from '../../../src/shared/source-control-dropdown-commit-items' import type { DropdownItem } from '../../../src/shared/source-control-dropdown-item-types' import { buildRemoteDropdownItems } from '../../../src/shared/source-control-dropdown-remote-items' +import type { SourceControlCommitAreaPrimaryActionDecision } from '../../../src/shared/source-control-primary-action-decision' import type { SourceControlPrimaryActionDecisionInputs } from '../../../src/shared/source-control-primary-action-decision-types' // String identifiers keep native lucide imports out of this module. @@ -155,3 +157,100 @@ export function buildMobileSourceControlActions( } ] } + +export function getMobilePrimaryActionHint( + decision: SourceControlCommitAreaPrimaryActionDecision +): string { + switch (decision.titleIntent) { + case 'commit_in_progress': + return translate('sourceControl.actions.committing', 'Commit in progress.') + case 'force_push_in_progress': + return translate('sourceControl.actions.forcePushing', 'Force push in progress.') + case 'action_in_progress': + case 'remote_operation_in_progress': + return translate( + 'sourceControl.actions.remoteOperationInProgress', + 'Remote operation in progress.' + ) + case 'remote_operation_blocks_commit': + return translate( + 'sourceControl.actions.waitForRemoteOperation', + 'Try again once the remote operation finishes.' + ) + case 'resolve_conflicts_before_commit': + return translate( + 'sourceControl.actions.resolveConflicts', + 'Resolve conflicts before committing.' + ) + case 'commit_staged_changes': + return translate('sourceControl.actions.commitStagedChanges', 'Commit staged changes.') + case 'enter_commit_message': + return translate( + 'sourceControl.actions.enterCommitMessage', + 'Enter a commit message to commit.' + ) + case 'stage_all_changes': + return translate('sourceControl.actions.stageAllChanges', 'Stage all changes.') + case 'stage_file_to_commit': + return translate( + 'sourceControl.actions.stageFileToCommit', + 'Stage at least one file to commit.' + ) + case 'checkout_branch_before_publish': + return translate( + 'sourceControl.actions.checkoutBeforePublish', + 'Check out a branch before publishing commits.' + ) + case 'checking_review_status': + return translate('sourceControl.actions.checkingReviewStatus', 'Checking review status.') + case 'review_already_merged': + return translate( + 'sourceControl.actions.reviewAlreadyMerged', + 'Nothing to commit. The review is already merged.' + ) + case 'publish_branch': + return translate('sourceControl.actions.publishToOrigin', 'Publish this branch to origin.') + case 'push_linked_review': + return translate( + 'sourceControl.actions.pushLinkedReview', + 'Push updates to the linked review branch.' + ) + case 'linked_review_target_unavailable': + return translate( + 'sourceControl.actions.linkedReviewUnavailable', + 'The linked review branch is unavailable.' + ) + case 'force_push_with_lease': + return translate( + 'sourceControl.actions.forcePushWithLease', + 'Force push with lease to update the remote branch.' + ) + case 'sync_counts': + return translate('sourceControl.actions.syncCounts', 'Pull {{behind}}, push {{ahead}}.', { + behind: decision.behind ?? 0, + ahead: decision.ahead ?? 0 + }) + case 'pull_count': { + const count = decision.count ?? 0 + return count === 1 + ? translate('sourceControl.actions.pullCommits_one', 'Pull {{count}} commit.', { + count + }) + : translate('sourceControl.actions.pullCommits_other', 'Pull {{count}} commits.', { + count + }) + } + case 'push_count': { + const count = decision.count ?? 0 + return count === 1 + ? translate('sourceControl.actions.pushCommits_one', 'Push {{count}} commit.', { + count + }) + : translate('sourceControl.actions.pushCommits_other', 'Push {{count}} commits.', { + count + }) + } + case 'nothing_to_commit_up_to_date': + return translate('sourceControl.actions.upToDate', 'Nothing to commit. Branch is up to date.') + } +} diff --git a/mobile/src/source-control/mobile-source-control-conflict-abort.ts b/mobile/src/source-control/mobile-source-control-conflict-abort.ts index 2b73a4851e2..58ecff370e9 100644 --- a/mobile/src/source-control/mobile-source-control-conflict-abort.ts +++ b/mobile/src/source-control/mobile-source-control-conflict-abort.ts @@ -1,3 +1,5 @@ +import { translate } from '../i18n/mobile-i18n' + export function isMobileConflictAborting( busyAction: string | null, conflictOperation: string | null @@ -9,5 +11,17 @@ export function isMobileConflictAborting( } export function mobileConflictAbortLabel(conflictOperation: string, aborting: boolean): string { - return aborting ? 'Aborting…' : `Abort ${conflictOperation}` + if (aborting) { + return translate('sourceControl.conflictAbort.aborting', 'Aborting…') + } + switch (conflictOperation) { + case 'merge': + return translate('sourceControl.conflictAbort.abortMerge', 'Abort merge') + case 'rebase': + return translate('sourceControl.conflictAbort.abortRebase', 'Abort rebase') + default: + return translate('sourceControl.conflictAbort.abortOperation', 'Abort {{operation}}', { + operation: conflictOperation + }) + } } diff --git a/mobile/src/source-control/mobile-source-control-hub-tab.ts b/mobile/src/source-control/mobile-source-control-hub-tab.ts index 72906db63fc..8f3bcf928ab 100644 --- a/mobile/src/source-control/mobile-source-control-hub-tab.ts +++ b/mobile/src/source-control/mobile-source-control-hub-tab.ts @@ -1,3 +1,5 @@ +import { translate } from '../i18n/mobile-i18n' + export type SourceControlHubTab = 'changes' | 'pr' | 'history' export const SOURCE_CONTROL_HUB_TABS: readonly SourceControlHubTab[] = [ @@ -7,9 +9,15 @@ export const SOURCE_CONTROL_HUB_TABS: readonly SourceControlHubTab[] = [ ] as const export const SOURCE_CONTROL_HUB_TAB_LABELS: Record = { - changes: 'Changes', - pr: 'Pull Request', - history: 'Commits' + get changes() { + return translate('sourceControl.hubTab.changes', 'Changes') + }, + get pr() { + return translate('sourceControl.hubTab.pullRequest', 'Pull Request') + }, + get history() { + return translate('sourceControl.hubTab.commits', 'Commits') + } } export function parseSourceControlHubTab( diff --git a/mobile/src/source-control/mobile-source-control-primary-action.ts b/mobile/src/source-control/mobile-source-control-primary-action.ts index c23dd9124d1..68d50175a2b 100644 --- a/mobile/src/source-control/mobile-source-control-primary-action.ts +++ b/mobile/src/source-control/mobile-source-control-primary-action.ts @@ -1,3 +1,5 @@ +import { translate } from '../i18n/mobile-i18n' +import { getMobilePrimaryActionHint } from './mobile-source-control-actions' import { getMobileForcePushBlockedReason } from './mobile-source-control-review-copy' import type { SourceControlPrimaryActionDecisionInputs } from '../../../src/shared/source-control-primary-action-decision-types' import { @@ -197,67 +199,21 @@ export function getMobileBranchCommitsAhead( function getMobilePrimaryActionLabel(decision: MobileSourceControlPrimaryActionDecision): string { if (decision.requiresForceWithLease) { - return 'Force Push' + return translate('sourceControl.primaryAction.forcePush', 'Force Push') } switch (decision.kind) { case 'commit': - return 'Commit' + return translate('sourceControl.primaryAction.commit', 'Commit') case 'stage': - return 'Stage All' + return translate('sourceControl.primaryAction.stageAll', 'Stage All') case 'push': - return 'Push' + return translate('sourceControl.primaryAction.push', 'Push') case 'pull': - return 'Pull' + return translate('sourceControl.primaryAction.pull', 'Pull') case 'sync': - return 'Sync' + return translate('sourceControl.primaryAction.sync', 'Sync') case 'publish': - return 'Publish Branch' - } -} - -function getMobilePrimaryActionHint(decision: MobileSourceControlPrimaryActionDecision): string { - switch (decision.titleIntent) { - case 'commit_in_progress': - return 'Commit in progress.' - case 'force_push_in_progress': - return 'Force push in progress.' - case 'action_in_progress': - case 'remote_operation_in_progress': - return 'Remote operation in progress.' - case 'remote_operation_blocks_commit': - return 'Try again once the remote operation finishes.' - case 'resolve_conflicts_before_commit': - return 'Resolve conflicts before committing.' - case 'commit_staged_changes': - return 'Commit staged changes.' - case 'enter_commit_message': - return 'Enter a commit message to commit.' - case 'stage_all_changes': - return 'Stage all changes.' - case 'stage_file_to_commit': - return 'Stage at least one file to commit.' - case 'checkout_branch_before_publish': - return 'Check out a branch before publishing commits.' - case 'checking_review_status': - return 'Checking review status.' - case 'review_already_merged': - return 'Nothing to commit. The review is already merged.' - case 'publish_branch': - return 'Publish this branch to origin.' - case 'push_linked_review': - return 'Push updates to the linked review branch.' - case 'linked_review_target_unavailable': - return 'The linked review branch is unavailable.' - case 'force_push_with_lease': - return 'Force push with lease to update the remote branch.' - case 'sync_counts': - return `Pull ${decision.behind ?? 0}, push ${decision.ahead ?? 0}.` - case 'pull_count': - return `Pull ${decision.count ?? 0} commit${decision.count === 1 ? '' : 's'}.` - case 'push_count': - return `Push ${decision.count ?? 0} commit${decision.count === 1 ? '' : 's'}.` - case 'nothing_to_commit_up_to_date': - return 'Nothing to commit. Branch is up to date.' + return translate('sourceControl.primaryAction.publishBranch', 'Publish Branch') } } diff --git a/mobile/src/source-control/mobile-source-control-screen-state.ts b/mobile/src/source-control/mobile-source-control-screen-state.ts index 8e7aa97a8ce..7cb1c99d19d 100644 --- a/mobile/src/source-control/mobile-source-control-screen-state.ts +++ b/mobile/src/source-control/mobile-source-control-screen-state.ts @@ -1,3 +1,4 @@ +import { translate } from '../i18n/mobile-i18n' import { ArrowDown, ArrowDownUp, @@ -130,7 +131,7 @@ export function formatBranchLabel(branch: string | undefined, head: string | und if (branch?.startsWith('refs/heads/')) { return branch.slice('refs/heads/'.length) } - return branch || head?.slice(0, 7) || 'No branch' + return branch || head?.slice(0, 7) || translate('sourceControl.screenState.noBranch', 'No branch') } export function statusColor(status: MobileGitFileStatus): string { diff --git a/mobile/src/source-control/mobile-source-control-sections.ts b/mobile/src/source-control/mobile-source-control-sections.ts index 7075c3d4b24..b2ba4ca7050 100644 --- a/mobile/src/source-control/mobile-source-control-sections.ts +++ b/mobile/src/source-control/mobile-source-control-sections.ts @@ -1,10 +1,16 @@ import { useMemo } from 'react' import type { SourceControlGroupOrder } from '../../../src/shared/ui-chrome-types' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { buildMobileSourceControlSections, type MobileGitStatusEntry } from './mobile-git-status' export function useMobileSourceControlSections( entries: readonly TEntry[], groupOrder: SourceControlGroupOrder ) { - return useMemo(() => buildMobileSourceControlSections(entries, groupOrder), [entries, groupOrder]) + // Section titles are translated inside the builder. + const t = useMobileTranslation() + return useMemo( + () => buildMobileSourceControlSections(entries, groupOrder), + [entries, groupOrder, t] + ) } diff --git a/mobile/src/source-control/use-mobile-commit-failure-recovery.ts b/mobile/src/source-control/use-mobile-commit-failure-recovery.ts index bac41eb5d88..fac5c52aa61 100644 --- a/mobile/src/source-control/use-mobile-commit-failure-recovery.ts +++ b/mobile/src/source-control/use-mobile-commit-failure-recovery.ts @@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import type { ConnectionState } from '../transport/types' import type { RpcClient } from '../transport/rpc-client' import { triggerError, triggerSuccess } from '../platform/haptics' +import { translate } from '../i18n/mobile-i18n' import { useHostProtocolGates } from '../components/host-protocol-gates-context' import { launchAgentWithPrompt, promptedLaunchNotice } from '../session/pr-ai-triage-launch' import { resolveMobileAgentLaunchAvailability } from '../session/mobile-agent-launch-availability' @@ -79,7 +80,12 @@ export function useMobileCommitFailureRecovery({ return false } if (!client || connState !== 'connected') { - setLaunchError('Waiting for desktop...') + setLaunchError( + translate( + 'sourceControl.useMobileCommitFailureRecovery.waitingForDesktop', + 'Waiting for desktop...' + ) + ) triggerError() return false } @@ -113,7 +119,14 @@ export function useMobileCommitFailureRecovery({ return notice.succeeded } catch (err) { triggerError() - setLaunchError(err instanceof Error ? err.message : 'Failed to launch agent') + setLaunchError( + err instanceof Error + ? err.message + : translate( + 'sourceControl.useMobileCommitFailureRecovery.launchFailed', + 'Failed to launch agent' + ) + ) return false } finally { inFlightRef.current = false diff --git a/mobile/src/source-control/use-mobile-commit-message-generation.ts b/mobile/src/source-control/use-mobile-commit-message-generation.ts index f7b3c475c64..0c23b8a70f2 100644 --- a/mobile/src/source-control/use-mobile-commit-message-generation.ts +++ b/mobile/src/source-control/use-mobile-commit-message-generation.ts @@ -8,6 +8,7 @@ import { } from 'react' import type { RpcClient } from '../transport/rpc-client' import { triggerError, triggerSuccess } from '../platform/haptics' +import { translate } from '../i18n/mobile-i18n' import { cancelMobileCommitMessage, requestMobileCommitMessage } from './mobile-commit-message-ai' type Params = { @@ -70,7 +71,14 @@ export function useMobileCommitMessageGeneration(params: Params) { // Catch transport drops because callers void this handler; retain error feedback. if (mountedRef.current && run === runRef.current) { triggerError() - setActionError(err instanceof Error ? err.message : 'Failed to generate commit message') + setActionError( + err instanceof Error + ? err.message + : translate( + 'sourceControl.useMobileCommitMessageGeneration.generateFailed', + 'Failed to generate commit message' + ) + ) } } finally { if (activeRunRef.current === run) { diff --git a/mobile/src/source-control/use-mobile-create-pr-runner.ts b/mobile/src/source-control/use-mobile-create-pr-runner.ts index dfb23c6ea14..882ce7ad41c 100644 --- a/mobile/src/source-control/use-mobile-create-pr-runner.ts +++ b/mobile/src/source-control/use-mobile-create-pr-runner.ts @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, type MutableRefObject } from 'react' import type { RpcClient } from '../transport/rpc-client' import { triggerError } from '../platform/haptics' +import { translate } from '../i18n/mobile-i18n' import type { MobileGitStatusResult } from './mobile-git-status' import type { LoadStatusOptions } from './mobile-source-control-screen-state' import { @@ -68,7 +69,12 @@ export function useMobileCreatePrRunner({ const branch = status?.branch if (!client || !branch) { triggerError() - setActionError('Check out a branch before creating a pull request.') + setActionError( + translate( + 'sourceControl.useMobileCreatePrRunner.branchRequired', + 'Check out a branch before creating a pull request.' + ) + ) return } const created: { current: MobileHostedReviewCreateIntentRunOutcome | null } = { diff --git a/mobile/src/source-control/use-mobile-git-requests.ts b/mobile/src/source-control/use-mobile-git-requests.ts index 42e7a0380b9..5ca488296b9 100644 --- a/mobile/src/source-control/use-mobile-git-requests.ts +++ b/mobile/src/source-control/use-mobile-git-requests.ts @@ -1,6 +1,7 @@ import { useCallback } from 'react' import type { ConnectionState, RpcSuccess } from '../transport/types' import type { RpcClient } from '../transport/rpc-client' +import { translate } from '../i18n/mobile-i18n' import { isMobileGitUnavailable, type MobileGitStatusResult, @@ -18,16 +19,25 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params) const sendGitRequest = useCallback( async (method: string, params?: Record): Promise => { if (!client || connState !== 'connected') { - throw new Error('Waiting for desktop...') + throw new Error( + translate( + 'sourceControl.useMobileGitRequests.waitingForDesktop', + 'Waiting for desktop...' + ) + ) } const response = await client.sendRequest(method, { worktree: `id:${worktreeId}`, ...params }) if (!response.ok) { - const error = new Error( - response.error?.message || 'Source control action failed' - ) as GitRequestError + const error: GitRequestError = new Error( + response.error?.message || + translate( + 'sourceControl.useMobileGitRequests.actionFailed', + 'Source control action failed' + ) + ) error.code = response.error?.code throw error } @@ -40,7 +50,10 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params) async (message: string): Promise => { const result = await sendGitRequest('git.commit', { message }) if (!result || result.success !== true) { - throw new Error(result?.error || 'Commit failed') + throw new Error( + result?.error || + translate('sourceControl.useMobileGitRequests.commitFailed', 'Commit failed') + ) } return result }, @@ -58,7 +71,12 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params) } const status = await sendGitRequest('git.status') if (!status.upstreamStatus) { - throw new Error('Branch status unavailable') + throw new Error( + translate( + 'sourceControl.useMobileGitRequests.branchUnavailable', + 'Branch status unavailable' + ) + ) } return status.upstreamStatus } diff --git a/mobile/src/source-control/use-mobile-source-control-action-sheet-runners.ts b/mobile/src/source-control/use-mobile-source-control-action-sheet-runners.ts index f17cb8aa2e4..0e239438ce4 100644 --- a/mobile/src/source-control/use-mobile-source-control-action-sheet-runners.ts +++ b/mobile/src/source-control/use-mobile-source-control-action-sheet-runners.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react' +import { translate } from '../i18n/mobile-i18n' import type { RpcClient } from '../transport/rpc-client' type GitStep = { method: string; params?: Record } @@ -66,10 +67,20 @@ export function useMobileSourceControlActionSheetRunners(params: Params) { async (baseRef: string | null) => { await runGitWorkflow('rebase', async () => { if (!client) { - throw new Error('Waiting for desktop...') + throw new Error( + translate( + 'sourceControl.actionSheetRunners.waitingForDesktop', + 'Waiting for desktop...' + ) + ) } if (!baseRef) { - throw new Error('No base branch to rebase onto') + throw new Error( + translate( + 'sourceControl.actionSheetRunners.noBaseBranch', + 'No base branch to rebase onto' + ) + ) } await sendGitRequest('git.rebaseFromBase', { baseRef }) }) diff --git a/mobile/src/source-control/use-mobile-source-control-commit-runners.ts b/mobile/src/source-control/use-mobile-source-control-commit-runners.ts index feff09f58e4..d8278bc65cc 100644 --- a/mobile/src/source-control/use-mobile-source-control-commit-runners.ts +++ b/mobile/src/source-control/use-mobile-source-control-commit-runners.ts @@ -1,4 +1,5 @@ import { useCallback, type MutableRefObject } from 'react' +import { translate } from '../i18n/mobile-i18n' import { triggerError, triggerSuccess } from '../platform/haptics' import type { LoadStatusOptions } from './mobile-source-control-screen-state' import type { @@ -69,7 +70,10 @@ export function useMobileSourceControlCommitRunners(params: Params) { await sendCommitRequest(message) } catch (err) { recordCommitFailure({ - error: err instanceof Error ? err.message : 'Commit failed', + error: + err instanceof Error + ? err.message + : translate('sourceControl.commitRunners.commitFailed', 'Commit failed'), commitMessage: message, stagedEntries }) @@ -110,7 +114,10 @@ export function useMobileSourceControlCommitRunners(params: Params) { return false } triggerError() - const errorMessage = err instanceof Error ? err.message : 'Source control action failed' + const errorMessage = + err instanceof Error + ? err.message + : translate('sourceControl.commitRunners.actionFailed', 'Source control action failed') if (!didCommit) { recordCommitFailure({ error: errorMessage, commitMessage: message, stagedEntries }) } diff --git a/mobile/src/source-control/use-mobile-source-control-loaders.ts b/mobile/src/source-control/use-mobile-source-control-loaders.ts index fbff1319cda..e712c424f95 100644 --- a/mobile/src/source-control/use-mobile-source-control-loaders.ts +++ b/mobile/src/source-control/use-mobile-source-control-loaders.ts @@ -1,4 +1,5 @@ import { useCallback, useRef, useState, type MutableRefObject } from 'react' +import { translate } from '../i18n/mobile-i18n' import type { MobileSourceControlSettings } from '../transport/settings-read-operations' import { useMobileSourceControlSettings } from './mobile-source-control-settings' import { useFocusEffect } from 'expo-router' @@ -168,7 +169,12 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr setScreenState({ kind: 'error', message: - connState === 'connected' ? 'Connecting to desktop...' : 'Waiting for desktop...' + connState === 'connected' + ? translate( + 'sourceControl.loaders.connectingToDesktop', + 'Connecting to desktop...' + ) + : translate('sourceControl.loaders.waitingForDesktop', 'Waiting for desktop...') }) } return false @@ -204,7 +210,10 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr if (isMobileGitUnavailableReply(reply)) { setScreenState({ kind: 'unavailable', - message: 'Update Orca desktop to use Source Control on mobile.' + message: translate( + 'sourceControl.loaders.updateDesktop', + 'Update Orca desktop to use Source Control on mobile.' + ) }) return false } @@ -218,13 +227,19 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr } continue } - throw new Error(refusal.message || 'Unable to load source control') + throw new Error( + refusal.message || + translate('sourceControl.loaders.loadFailed', 'Unable to load source control') + ) } } catch (err) { if (!isCurrentLoad()) { return false } - const message = err instanceof Error ? err.message : 'Unable to load source control' + const message = + err instanceof Error + ? err.message + : translate('sourceControl.loaders.loadFailed', 'Unable to load source control') setScreenState((prev) => { // Mutations can succeed while refresh races an abort; retain the last good screen through transient read failure. if (options?.preserveReadyOnFailure && prev.kind === 'ready') { diff --git a/mobile/src/source-control/use-mobile-source-control-openers.ts b/mobile/src/source-control/use-mobile-source-control-openers.ts index 5e41e8e666d..df780c63f47 100644 --- a/mobile/src/source-control/use-mobile-source-control-openers.ts +++ b/mobile/src/source-control/use-mobile-source-control-openers.ts @@ -1,4 +1,5 @@ import { useCallback, useRef, useState, type MutableRefObject } from 'react' +import { translate } from '../i18n/mobile-i18n' import { useWorkspaceRouteHandoff } from '../navigation/workspace-route-handoff' import type { RpcClient } from '../transport/rpc-client' import { isRendererUnavailableReply } from '../transport/renderer-unavailable-reply' @@ -87,7 +88,9 @@ export function useMobileSourceControlOpeners(params: Params) { if (!mountedRef.current) { return } - setActionError('Waiting for desktop...') + setActionError( + translate('sourceControl.openers.waitingForDesktop', 'Waiting for desktop...') + ) return } openingPathRef.current = entry.path @@ -127,7 +130,12 @@ export function useMobileSourceControlOpeners(params: Params) { sourceFileDiffOpenRun.interpret(diffReply) } } catch (error) { - throw new Error(refusedRpcMessageOrFallback(error, 'Unable to open diff')) + throw new Error( + refusedRpcMessageOrFallback( + error, + translate('sourceControl.openers.openDiffFailed', 'Unable to open diff') + ) + ) } if (!mountedRef.current) { return @@ -145,7 +153,12 @@ export function useMobileSourceControlOpeners(params: Params) { return } if (revealResult === 'timeout') { - throw new Error("The file opened, but its tab isn't ready yet. Try again.") + throw new Error( + translate( + 'sourceControl.openers.tabNotReady', + "The file opened, but its tab isn't ready yet. Try again." + ) + ) } triggerSelection() // Embedded panels dismiss their dock; route panels pop back to the activated diff, with Back as the unwired-dock fallback. @@ -159,7 +172,11 @@ export function useMobileSourceControlOpeners(params: Params) { return } triggerError() - setActionError(err instanceof Error ? err.message : 'Unable to open diff') + setActionError( + err instanceof Error + ? err.message + : translate('sourceControl.openers.openDiffFailed', 'Unable to open diff') + ) } finally { if (openingPathRef.current === entry.path) { openingPathRef.current = null diff --git a/mobile/src/source-control/use-mobile-source-control-runners.ts b/mobile/src/source-control/use-mobile-source-control-runners.ts index 8c70714521f..468a85f6164 100644 --- a/mobile/src/source-control/use-mobile-source-control-runners.ts +++ b/mobile/src/source-control/use-mobile-source-control-runners.ts @@ -1,4 +1,5 @@ import { useCallback, type Dispatch, type MutableRefObject, type SetStateAction } from 'react' +import { translate } from '../i18n/mobile-i18n' import type { RouteHandoff } from '../navigation/route-handoff' import type { RpcClient } from '../transport/rpc-client' import { triggerError, triggerSuccess } from '../platform/haptics' @@ -110,7 +111,8 @@ export function useMobileSourceControlRunners(params: Params) { return false } triggerError() - setActionError(err instanceof Error ? err.message : 'Source control action failed') + const text = translate('sourceControl.runners.actionFailed', 'Source control action failed') + setActionError(err instanceof Error ? err.message : text) return false } finally { if (busyActionRef.current === actionId) { diff --git a/mobile/src/source-control/use-mobile-source-control-state.ts b/mobile/src/source-control/use-mobile-source-control-state.ts index 032d2e5df0f..ad0c832fff3 100644 --- a/mobile/src/source-control/use-mobile-source-control-state.ts +++ b/mobile/src/source-control/use-mobile-source-control-state.ts @@ -1,4 +1,5 @@ import { useCallback, useMemo, useRef, useState } from 'react' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useForceReconnect } from '../transport/host-client-hooks' import { useWorkspaceClient } from '../transport/use-workspace-client' @@ -46,6 +47,7 @@ export type MobileSourceControlStateParams = { } export function useMobileSourceControlState(params: MobileSourceControlStateParams) { + const t = useMobileTranslation() const { hostId, worktreeId, @@ -123,7 +125,7 @@ export function useMobileSourceControlState(params: MobileSourceControlStatePara const branchCompareResult = branchCompareState.kind === 'ready' ? branchCompareState.result : null const branchCompareSection = useMemo( () => buildMobileBranchCompareSection(branchCompareResult?.entries ?? []), - [branchCompareResult] + [branchCompareResult, t] ) const branchCompareSummaryText = branchCompareResult ? formatMobileBranchCompareSummary(branchCompareResult.summary) @@ -162,9 +164,9 @@ export function useMobileSourceControlState(params: MobileSourceControlStatePara const upstreamKnown = upstream !== undefined const syncLabel = upstream && upstream.hasUpstream - ? `${upstream.ahead} ahead, ${upstream.behind} behind` + ? t('sourceControl.state.syncStatus', '{{ahead}} ahead, {{behind}} behind', upstream) : upstream && !upstream.hasUpstream - ? 'No upstream' + ? t('sourceControl.state.noUpstream', 'No upstream') : null const { sendGitRequest, sendCommitRequest, runGitSyncSteps } = useMobileGitRequests({ diff --git a/mobile/src/tasks/MobileTasksLegacySurface.tsx b/mobile/src/tasks/MobileTasksLegacySurface.tsx index fc6553ee0d8..2e1a9828368 100644 --- a/mobile/src/tasks/MobileTasksLegacySurface.tsx +++ b/mobile/src/tasks/MobileTasksLegacySurface.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { SafeAreaView, View, @@ -82,6 +83,7 @@ import { renderMobileTasksItemDetailDrawer } from './mobile-tasks-item-detail-dr export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentationModel }) { const colorScheme = useMobileColorScheme() + const t = useMobileTranslation() const { error, githubMode, @@ -126,8 +128,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat style={styles.sourceNoticeBanner} > - Preferred issue source upstream is unavailable for {fallback.repoLabel}. Using - origin. + {t( + 'tasks.legacySurface.sourceFallback', + 'Preferred issue source upstream is unavailable for {{repo}}. Using origin.', + { repo: fallback.repoLabel } + )} )) @@ -136,6 +141,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat {!error && provider === 'github' && githubMode === 'items' ? githubSourceErrors.map((sourceError) => { const isRetrying = retryingGithubSourceRepoPaths.has(sourceError.repoPath) + const sourceErrorParts = t( + 'tasks.legacySurface.loadIssuesFailed', + "Couldn't load issues from {{source}}.", + { source: '\uFFFC' } + ).split('\uFFFC') return ( - Couldn't load issues from{' '} + {sourceErrorParts[0]} {sourceError.source.owner}/{sourceError.source.repo} - . + {sourceErrorParts.slice(1).join('')} {sourceError.message} @@ -155,13 +165,19 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat void retryGitHubIssueSourceFetch(sourceError.repoPath)} > - {isRetrying ? 'Retrying...' : 'Retry'} + {isRetrying + ? t('tasks.legacySurface.retrying', 'Retrying...') + : t('common.retry', 'Retry')} @@ -176,7 +192,10 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat - Sub-issue data is unavailable for your token. + {t( + 'tasks.legacySurface.subIssueDataUnavailable', + 'Sub-issue data is unavailable for your token.' + )} ) : null} @@ -261,8 +280,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat ({ @@ -278,11 +300,17 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat /> ({ label: mergeMethodTaskItem.provider === 'gitlab' && method === 'merge' - ? 'Merge' + ? t('tasks.legacySurface.mergeAction', 'Merge') : getHostedReviewMergeMethodLabel(method), icon: GitBranch, onPress: () => { @@ -307,7 +335,9 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat { if (!taskUiReady || !pendingHostedMerge) { @@ -327,7 +357,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat /> { if (!taskUiReady || !pendingProjectGitHubMerge) { @@ -354,7 +384,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat title={ pendingHostedStateChange ? getHostedStateConfirmTitle(pendingHostedStateChange) - : 'Update Item' + : t('tasks.legacySurface.updateItemTitle', 'Update Item') } message={ pendingHostedStateChange @@ -364,7 +394,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat confirmLabel={ pendingHostedStateChange ? getHostedStateConfirmLabel(pendingHostedStateChange) - : 'Confirm' + : t('common.confirm', 'Confirm') } destructive={pendingHostedStateChange?.nextState === 'closed'} onConfirm={() => { diff --git a/mobile/src/tasks/MobileTasksPrFileDiff.tsx b/mobile/src/tasks/MobileTasksPrFileDiff.tsx index b8e263ab7ee..8269219757c 100644 --- a/mobile/src/tasks/MobileTasksPrFileDiff.tsx +++ b/mobile/src/tasks/MobileTasksPrFileDiff.tsx @@ -16,6 +16,7 @@ import { import { MAX_RENDERED_PR_DIFF_LINES } from './mobile-tasks-options' import type { GitHubPRFileContents } from './mobile-tasks-provider-detail-types' import { styles } from './mobile-tasks-legacy-styles' +import { useMobileTranslation } from '../i18n/use-mobile-translation' export function formatDiffLineNumber(value: number | undefined): string { return value === undefined ? ' ' : value.toString().padStart(4, ' ') @@ -47,6 +48,7 @@ export function GitHubPrFileDiff({ onSubmitComment: (line: number) => void }): ReactNode { useMobileColorScheme() + const t = useMobileTranslation() const diffPreview = useMemo( () => buildGitHubPrFileDiffPreview( @@ -64,14 +66,25 @@ export function GitHubPrFileDiff({ const hiddenDiffLineCount = Math.max(0, diffPreview.totalLineCount - visibleDiffLines.length) if (diffPreview.totalLineCount === 0) { - return No text changes found. + return ( + + {t('tasks.prFileDiff.noTextChanges', 'No text changes found.')} + + ) } return ( {hiddenDiffLineCount > 0 ? ( - Showing first {MAX_RENDERED_PR_DIFF_LINES} of {diffPreview.totalLineCount} diff lines. + {t( + 'tasks.prFileDiff.showingDiffLines', + 'Showing first {{limit}} of {{total}} diff lines.', + { + limit: MAX_RENDERED_PR_DIFF_LINES, + total: diffPreview.totalLineCount + } + )} ) : null} {visibleDiffLines.map((line) => { @@ -115,7 +128,7 @@ export function GitHubPrFileDiff({ style={[styles.input, styles.replyInput]} value={commentDrafts[draftKey] ?? ''} onChangeText={(next) => onCommentDraftChange(draftKey, next)} - placeholder="Add review comment" + placeholder={t('tasks.prFileDiff.commentPlaceholder', 'Add review comment')} placeholderTextColor={colors.textMuted} multiline textAlignVertical="top" @@ -125,7 +138,11 @@ export function GitHubPrFileDiff({ disabled={disabled || !(commentDrafts[draftKey] ?? '').trim()} onPress={() => onSubmitComment(commentLine)} > - Comment on line {commentLine} + + {t('tasks.prFileDiff.commentOnLine', 'Comment on line {{line}}', { + line: commentLine + })} + ) : null} diff --git a/mobile/src/tasks/composer-source-copy.ts b/mobile/src/tasks/composer-source-copy.ts new file mode 100644 index 00000000000..e27419569be --- /dev/null +++ b/mobile/src/tasks/composer-source-copy.ts @@ -0,0 +1,27 @@ +import { useCallback, useState } from 'react' +import { translate } from '../i18n/mobile-i18n' +import { useMobileTranslation } from '../i18n/use-mobile-translation' + +export function getBaseResolveError(error: unknown): string { + return error instanceof Error + ? error.message + : translate('tasks.composerSource.baseFailed', 'Failed to resolve base branch.') +} + +export function useForkPushWarning() { + const t = useMobileTranslation() + const [hasWarning, setHasWarning] = useState(false) + const setForkPushWarning = useCallback((warning: string | null) => { + setHasWarning(warning !== null) + }, []) + + return [ + hasWarning + ? t( + 'tasks.composerSource.forkPushWarning', + 'This PR has "Allow edits from maintainers" off; pushing to the fork may be rejected by GitHub.' + ) + : null, + setForkPushWarning + ] as const +} diff --git a/mobile/src/tasks/mobile-smart-source-modes.ts b/mobile/src/tasks/mobile-smart-source-modes.ts index bd5f80e4a76..ed1d059f240 100644 --- a/mobile/src/tasks/mobile-smart-source-modes.ts +++ b/mobile/src/tasks/mobile-smart-source-modes.ts @@ -1,4 +1,5 @@ import type { MrStateFilter, SmartNameMode } from './mobile-composer-source-types' +import { translate } from '../i18n/mobile-i18n' // Lucide has no brand icons; provider modes use TaskProviderLogo SVGs. export type SmartModeIcon = @@ -12,13 +13,31 @@ export type SmartModeOption = { } export const SMART_MODE_OPTIONS: readonly SmartModeOption[] = [ - { id: 'smart', label: 'Smart', icon: { type: 'lucide', name: 'sparkles' } }, + { + id: 'smart', + get label() { + return translate('tasks.smartSourceModes.smart', 'Smart') + }, + icon: { type: 'lucide', name: 'sparkles' } + }, { id: 'github', label: 'GitHub', icon: { type: 'provider', provider: 'github' } }, { id: 'linear', label: 'Linear', icon: { type: 'provider', provider: 'linear' } }, { id: 'jira', label: 'Jira', icon: { type: 'provider', provider: 'jira' } }, { id: 'gitlab', label: 'GitLab', icon: { type: 'provider', provider: 'gitlab' } }, - { id: 'branches', label: 'Branch', icon: { type: 'lucide', name: 'git-branch' } }, - { id: 'text', label: 'Name', icon: { type: 'lucide', name: 'case-sensitive' } } + { + id: 'branches', + get label() { + return translate('tasks.smartSourceModes.branch', 'Branch') + }, + icon: { type: 'lucide', name: 'git-branch' } + }, + { + id: 'text', + get label() { + return translate('tasks.smartSourceModes.name', 'Name') + }, + icon: { type: 'lucide', name: 'case-sensitive' } + } ] export type SmartModeAvailabilityInput = { @@ -75,10 +94,30 @@ export function normalizeSmartMode( export type MrStateFilterOption = { id: MrStateFilter; label: string } export const MR_STATE_FILTER_OPTIONS: readonly MrStateFilterOption[] = [ - { id: 'opened', label: 'Open' }, - { id: 'merged', label: 'Merged' }, - { id: 'closed', label: 'Closed' }, - { id: 'all', label: 'All' } + { + id: 'opened', + get label() { + return translate('tasks.smartSourceModes.openState', 'Open') + } + }, + { + id: 'merged', + get label() { + return translate('tasks.smartSourceModes.mergedState', 'Merged') + } + }, + { + id: 'closed', + get label() { + return translate('tasks.smartSourceModes.closedState', 'Closed') + } + }, + { + id: 'all', + get label() { + return translate('tasks.smartSourceModes.allStates', 'All') + } + } ] export const DEFAULT_MR_STATE_FILTER: MrStateFilter = 'opened' diff --git a/mobile/src/tasks/mobile-task-view-options.tsx b/mobile/src/tasks/mobile-task-view-options.tsx index 1c5db40541e..b193bd2c3fe 100644 --- a/mobile/src/tasks/mobile-task-view-options.tsx +++ b/mobile/src/tasks/mobile-task-view-options.tsx @@ -1,6 +1,7 @@ import type { JiraIssueFilter } from '../../../src/shared/jira/jira-types' import type { TaskProvider } from '../../../src/shared/task-providers' import type { PickerOption } from '../components/PickerModal' +import { translate } from '../i18n/mobile-i18n' import { JIRA_FILTER_LABELS } from './mobile-jira-issue-filters' export const PROVIDER_LABELS: Record = { @@ -11,27 +12,61 @@ export const PROVIDER_LABELS: Record = { } export const PROVIDER_EMPTY_LABELS: Record = { - github: 'No GitHub tasks', - gitlab: 'No GitLab tasks', - linear: 'No Linear tasks', - jira: 'No Jira tasks' + get github() { + return translate('tasks.taskViewOptions.noGitHubTasks', 'No GitHub tasks') + }, + get gitlab() { + return translate('tasks.taskViewOptions.noGitLabTasks', 'No GitLab tasks') + }, + get linear() { + return translate('tasks.taskViewOptions.noLinearTasks', 'No Linear tasks') + }, + get jira() { + return translate('tasks.taskViewOptions.noJiraTasks', 'No Jira tasks') + } } export const JIRA_FILTER_OPTIONS: PickerOption[] = [ { value: 'assigned', - label: JIRA_FILTER_LABELS.assigned, - subtitle: 'Unresolved issues assigned to you' + get label() { + return JIRA_FILTER_LABELS.assigned + }, + get subtitle() { + return translate( + 'tasks.taskViewOptions.assignedSubtitle', + 'Unresolved issues assigned to you' + ) + } }, { value: 'reported', - label: JIRA_FILTER_LABELS.reported, - subtitle: 'Unresolved issues you reported' + get label() { + return JIRA_FILTER_LABELS.reported + }, + get subtitle() { + return translate('tasks.taskViewOptions.reportedSubtitle', 'Unresolved issues you reported') + } }, { value: 'all', - label: JIRA_FILTER_LABELS.all, - subtitle: 'Unresolved issues across the selected sites' + get label() { + return JIRA_FILTER_LABELS.all + }, + get subtitle() { + return translate( + 'tasks.taskViewOptions.allSubtitle', + 'Unresolved issues across the selected sites' + ) + } }, - { value: 'done', label: JIRA_FILTER_LABELS.done, subtitle: 'Your recently resolved issues' } + { + value: 'done', + get label() { + return JIRA_FILTER_LABELS.done + }, + get subtitle() { + return translate('tasks.taskViewOptions.doneSubtitle', 'Your recently resolved issues') + } + } ] diff --git a/mobile/src/tasks/mobile-tasks-create-drawers.tsx b/mobile/src/tasks/mobile-tasks-create-drawers.tsx index c345e4c6820..eedda3d5deb 100644 --- a/mobile/src/tasks/mobile-tasks-create-drawers.tsx +++ b/mobile/src/tasks/mobile-tasks-create-drawers.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -56,18 +57,30 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel - New {providerLabel} Issue + + {translate('tasks.tasksCreateDrawers.newIssueTitle', 'New {{providerLabel}} Issue', { + providerLabel + })} + {provider === 'github' || provider === 'gitlab' - ? 'Create an issue in the selected repository.' - : 'Create an issue in the selected Linear team.'} + ? translate( + 'tasks.tasksCreateDrawers.repositorySubtitle', + 'Create an issue in the selected repository.' + ) + : translate( + 'tasks.tasksCreateDrawers.linearTeamSubtitle', + 'Create an issue in the selected Linear team.' + )} - {provider === 'github' || provider === 'gitlab' ? 'Repository' : 'Team'} + {provider === 'github' || provider === 'gitlab' + ? translate('tasks.tasksCreateDrawers.repository', 'Repository') + : translate('tasks.tasksCreateDrawers.team', 'Team')} - Issue source + + {translate('tasks.tasksCreateDrawers.issueSource', 'Issue source')} + - File in{' '} - {selectedCreateIssuePreference === 'origin' - ? issueSourceSlug(selectedCreateGitHubSources?.prs) - : issueSourceSlug(selectedCreateGitHubSources?.upstreamCandidate)} + {translate('tasks.tasksCreateDrawers.fileIn', 'File in {{slug}}', { + slug: + selectedCreateIssuePreference === 'origin' + ? issueSourceSlug(selectedCreateGitHubSources?.prs) + : issueSourceSlug(selectedCreateGitHubSources?.upstreamCandidate) + })} {(['upstream', 'origin'] as const).map((preference) => { @@ -135,7 +152,9 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel selected && styles.issueSourceSegmentTextActive ]} > - {preference === 'upstream' ? 'Upstream' : 'Origin'} + {preference === 'upstream' + ? translate('tasks.tasksCreateDrawers.upstream', 'Upstream') + : translate('tasks.tasksCreateDrawers.origin', 'Origin')} {slug} @@ -147,23 +166,27 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel ) : null} - Title + + {translate('tasks.tasksCreateDrawers.title', 'Title')} + - Description + + {translate('tasks.tasksCreateDrawers.description', 'Description')} + ) : ( - Create Issue + + {translate('tasks.tasksCreateDrawers.createIssue', 'Create Issue')} + )} @@ -203,7 +228,11 @@ export function renderMobileTasksCreateTargetPicker(model: ConnectionPresentatio return ( - Connect Linear workspace + + {translate( + 'tasks.tasksCreateDrawers.connectLinearWorkspace', + 'Connect Linear workspace' + )} + - Paste a Personal API key to browse issues from that workspace. + {translate( + 'tasks.tasksCreateDrawers.linearConnectSubtitle', + 'Paste a Personal API key to browse issues from that workspace.' + )} - Personal API key + + {translate('tasks.tasksCreateDrawers.personalApiKey', 'Personal API key')} + void Linking.openURL('https://linear.app/settings/account/security')} > - Linear Settings / Security / New API key + + {translate( + 'tasks.tasksCreateDrawers.linearSettingsLink', + 'Linear Settings / Security / New API key' + )} + - Your key is encrypted via the host OS keychain and stored locally. + {translate( + 'tasks.tasksCreateDrawers.keySecurityHint', + 'Your key is encrypted via the host OS keychain and stored locally.' + )} ) : ( - Connect + + {translate('tasks.tasksCreateDrawers.connect', 'Connect')} + )} @@ -321,7 +370,7 @@ export function renderMobileTasksWorkspaceCreateTargetPicker(model: ConnectionPr return ( { diff --git a/mobile/src/tasks/mobile-tasks-filter-pickers.tsx b/mobile/src/tasks/mobile-tasks-filter-pickers.tsx index 5732648e7a7..b2c7c3e2456 100644 --- a/mobile/src/tasks/mobile-tasks-filter-pickers.tsx +++ b/mobile/src/tasks/mobile-tasks-filter-pickers.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -34,12 +35,21 @@ export function renderMobileTasksGitHubProjectFieldsPicker(model: ConnectionPres onClose={() => setShowGitHubProjectFieldsPicker(false)} > - Project Fields - Choose which Project fields appear on item cards. + + {translate('tasks.filterPickers.fieldsTitle', 'Project Fields')} + + + {translate( + 'tasks.filterPickers.fieldsSubtitle', + 'Choose which Project fields appear on item cards.' + )} + {githubProjectAvailableSummaryFields.length === 0 ? ( - This view has no extra fields to show. + + {translate('tasks.filterPickers.noFields', 'This view has no extra fields to show.')} + ) : ( githubProjectAvailableSummaryFields.map((field, index) => { const visible = !githubProjectHiddenFieldIds.has(field.id) @@ -55,7 +65,9 @@ export function renderMobileTasksGitHubProjectFieldsPicker(model: ConnectionPres {field.name} - {visible ? 'Shown on cards' : 'Hidden from cards'} + {visible + ? translate('tasks.filterPickers.fieldShown', 'Shown on cards') + : translate('tasks.filterPickers.fieldHidden', 'Hidden from cards')} {visible ? : null} @@ -82,7 +94,7 @@ export function renderMobileTasksGitLabViewPicker(model: ConnectionPresentationM return ( { @@ -99,21 +111,14 @@ export function renderMobileTasksGitLabViewPicker(model: ConnectionPresentationM } export function renderMobileTasksGitLabFilterPicker(model: ConnectionPresentationModel) { - const { - gitlabFilter, - setGitlabFilter, - setShowGitLabFilterPicker, - showGitLabFilterPicker, - taskUiReady - } = model return ( setShowGitLabFilterPicker(false)} + selected={model.gitlabFilter} + onSelect={model.setGitlabFilter} + onClose={() => model.setShowGitLabFilterPicker(false)} /> ) } @@ -132,7 +137,7 @@ export function renderMobileTasksLinearFilterPicker(model: ConnectionPresentatio return ( { @@ -162,7 +167,7 @@ export function renderMobileTasksLinearWorkspacePicker(model: ConnectionPresenta return ( { @@ -173,7 +178,14 @@ export function renderMobileTasksLinearWorkspacePicker(model: ConnectionPresenta .request(client, { workspaceId }) .then(() => loadLinearContext()) .catch((err) => { - setError(err instanceof Error ? err.message : 'Failed to switch workspace') + setError( + err instanceof Error + ? err.message + : translate( + 'tasks.filterPickers.switchWorkspaceFailed', + 'Failed to switch workspace' + ) + ) }) } }} @@ -192,14 +204,19 @@ export function renderMobileTasksLinearTeamPicker(model: ConnectionPresentationM showLinearTeamPicker, taskUiReady } = model + const count = linearTeams.length return ( setShowLinearTeamPicker(false)} > - Linear Teams - Choose which teams appear in Tasks. + + {translate('tasks.filterPickers.teamsTitle', 'Linear Teams')} + + + {translate('tasks.filterPickers.teamsSubtitle', 'Choose which teams appear in Tasks.')} + - All teams - {linearTeams.length} teams + + {translate('tasks.filterPickers.allTeams', 'All teams')} + + + {count === 1 + ? translate('tasks.filterPickers.teams_one', '{{count}} team', { count }) + : translate('tasks.filterPickers.teams_other', '{{count}} teams', { count })} + {selectedLinearTeamIds.size === linearTeams.length ? ( @@ -275,19 +298,26 @@ export function renderMobileTasksLinearStatusPicker(model: ConnectionPresentatio zIndex={TASK_SECONDARY_DRAWER_Z_INDEX} > - Change Status + + {translate('tasks.filterPickers.changeStatus', 'Change Status')} + - {linearStatusPickerItem?.source.identifier ?? 'Linear issue'} + {linearStatusPickerItem?.source.identifier ?? + translate('tasks.filterPickers.linearIssue', 'Linear issue')} {linearStatesLoading ? ( - Loading states... + + {translate('tasks.filterPickers.loadingStates', 'Loading states...')} + ) : linearStates.length === 0 ? ( - No states available + + {translate('tasks.filterPickers.noStates', 'No states available')} + ) : ( linearStates.map((state, index) => { const selected = @@ -347,7 +377,7 @@ export function renderMobileTasksJiraFilterPicker(model: ConnectionPresentationM return ( { @@ -362,26 +392,17 @@ export function renderMobileTasksJiraFilterPicker(model: ConnectionPresentationM } export function renderMobileTasksJiraSitePicker(model: ConnectionPresentationModel) { - const { - jiraConnection, - jiraSiteOptions, - setItems, - setJiraConnection, - setShowJiraSitePicker, - showJiraSitePicker, - taskUiReady - } = model return ( { - setJiraConnection((current) => ({ ...current, selection: siteId })) - setItems([]) + model.setJiraConnection((current) => ({ ...current, selection: siteId })) + model.setItems([]) }} - onClose={() => setShowJiraSitePicker(false)} + onClose={() => model.setShowJiraSitePicker(false)} /> ) } diff --git a/mobile/src/tasks/mobile-tasks-github-project-list.tsx b/mobile/src/tasks/mobile-tasks-github-project-list.tsx index a5197a63abd..8599f3ef486 100644 --- a/mobile/src/tasks/mobile-tasks-github-project-list.tsx +++ b/mobile/src/tasks/mobile-tasks-github-project-list.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { View, ActivityIndicator, @@ -20,6 +21,41 @@ import { projectFieldDisplayLabel, projectRowStatusLabel } from './mobile-tasks-legacy-foundation' +import type { GitHubProjectField, GitHubProjectRow } from './mobile-tasks-view-state-types' + +function isProjectFieldEmpty(row: GitHubProjectRow, field: GitHubProjectField): boolean { + switch (field.dataType) { + case 'ASSIGNEES': + return row.content.assignees.map((user) => user.login).join(', ') === '' + case 'LABELS': + return row.content.labels.map((label) => label.name).join(', ') === '' + case 'REPOSITORY': + return row.content.repository == null + case 'PARENT_ISSUE': + return !row.content.parentIssue + case 'ISSUE_TYPE': + return row.content.issueType?.name == null + case 'TITLE': + return false + } + const value = row.fieldValuesByFieldId?.[field.id] + if (!value) { + return true + } + switch (value.kind) { + case 'text': + return !value.text + case 'labels': + return value.labels.map((label) => label.name).join(', ') === '' + case 'users': + return value.users.map((user) => user.login).join(', ') === '' + case 'date': + case 'iteration': + case 'number': + case 'single-select': + return false + } +} export function renderMobileTasksGitHubProjectList( model: ConnectionPresentationModel, @@ -42,13 +78,16 @@ export function renderMobileTasksGitHubProjectList( taskUiReady, visibleGitHubProjectRows } = model + const count = githubProjectSummaryFields.length - 4 return githubProjectLoading ? ( ) : !activeGitHubProject ? ( - Choose a GitHub project + + {translate('tasks.githubProjectList.chooseProject', 'Choose a GitHub project')} + - Browse projects + + {translate('tasks.githubProjectList.browseProjects', 'Browse projects')} + ) : githubProjectError ? ( @@ -72,7 +113,9 @@ export function renderMobileTasksGitHubProjectList( ) : !githubProjectTable || visibleGitHubProjectRows.length === 0 ? ( - No project items + + {translate('tasks.githubProjectList.noItems', 'No project items')} + ) : ( - {entry.group.label || 'Items'} + {entry.group.label || translate('tasks.githubProjectList.items', 'Items')} {projectGroupMeta(entry.group)} @@ -143,19 +186,40 @@ export function renderMobileTasksGitHubProjectList( /> {row.itemType === 'PULL_REQUEST' - ? 'Pull request' + ? translate( + 'tasks.githubProjectList.pullRequestSubtitle', + 'Pull request · {{repository}}{{number}}', + { + repository: row.content.repository ?? githubProjectTable.project.title, + number: row.content.number ? ` #${row.content.number}` : '' + } + ) : row.itemType === 'ISSUE' - ? 'Issue' - : 'Project item'}{' '} - · {row.content.repository ?? githubProjectTable.project.title} - {row.content.number ? ` #${row.content.number}` : ''} + ? translate( + 'tasks.githubProjectList.issueSubtitle', + 'Issue · {{repository}}{{number}}', + { + repository: row.content.repository ?? githubProjectTable.project.title, + number: row.content.number ? ` #${row.content.number}` : '' + } + ) + : translate( + 'tasks.githubProjectList.itemSubtitle', + 'Project item · {{repository}}{{number}}', + { + repository: row.content.repository ?? githubProjectTable.project.title, + number: row.content.number ? ` #${row.content.number}` : '' + } + )} {githubProjectSummaryFields.length > 0 ? ( {githubProjectSummaryFields.slice(0, 4).map((field) => { - const value = projectFieldDisplayLabel(row, field) - const isEmpty = value === 'Empty' + const isEmpty = isProjectFieldEmpty(row, field) + const value = isEmpty + ? translate('tasks.githubProjectList.emptyField', 'Empty') + : projectFieldDisplayLabel(row, field) return ( @@ -170,7 +234,17 @@ export function renderMobileTasksGitHubProjectList( {githubProjectSummaryFields.length > 4 ? ( - +{githubProjectSummaryFields.length - 4} fields + {count === 1 + ? translate( + 'tasks.githubProjectList.moreFields_one', + '+{{count}} field', + { count } + ) + : translate( + 'tasks.githubProjectList.moreFields_other', + '+{{count}} fields', + { count } + )} ) : null} diff --git a/mobile/src/tasks/mobile-tasks-github-project-pickers.tsx b/mobile/src/tasks/mobile-tasks-github-project-pickers.tsx index 90affafa536..9b574adc042 100644 --- a/mobile/src/tasks/mobile-tasks-github-project-pickers.tsx +++ b/mobile/src/tasks/mobile-tasks-github-project-pickers.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -42,14 +43,22 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati showGitHubProjectPicker, taskUiReady } = model + const count = githubProjectPartialFailures.length return ( setShowGitHubProjectPicker(false)} > - GitHub Projects - Choose a project view for the Tasks page. + + {translate('tasks.githubProjectPickers.title', 'GitHub Projects')} + + + {translate( + 'tasks.githubProjectPickers.subtitle', + 'Choose a project view for the Tasks page.' + )} + @@ -57,7 +66,7 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati style={styles.input} value={githubProjectPickerSearch} onChangeText={setGithubProjectPickerSearch} - placeholder="Search projects" + placeholder={translate('tasks.githubProjectPickers.searchProjects', 'Search projects')} placeholderTextColor={colors.textMuted} autoCapitalize="none" autoCorrect={false} @@ -71,7 +80,10 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati setGithubProjectPasteError('') }} onSubmitEditing={() => void resolveGitHubProjectFromInput()} - placeholder="Add by URL or owner/number" + placeholder={translate( + 'tasks.githubProjectPickers.addPlaceholder', + 'Add by URL or owner/number' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" autoCorrect={false} @@ -82,7 +94,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati onPress={() => void resolveGitHubProjectFromInput()} > - {githubProjectPasteBusy ? 'Adding...' : 'Add'} + {githubProjectPasteBusy + ? translate('tasks.githubProjectPickers.adding', 'Adding...') + : translate('tasks.githubProjectPickers.add', 'Add')} @@ -100,15 +114,35 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati {githubProjectPartialFailures.length === 1 && githubProjectPartialFailures[0]!.owner !== '*' - ? `Couldn't load projects from ${githubProjectPartialFailures[0]!.owner}.` - : `Some organizations didn't load (${githubProjectPartialFailures.length}).`} + ? translate( + 'tasks.githubProjectPickers.ownerLoadFailed', + "Couldn't load projects from {{owner}}.", + { + owner: githubProjectPartialFailures[0]!.owner + } + ) + : translate( + 'tasks.githubProjectPickers.organizationsLoadFailed', + "Some organizations didn't load ({{count}}).", + { count } + )} + + + {translate( + 'tasks.githubProjectPickers.addByUrlHint', + 'Use Add by URL to reach missing projects.' + )} - Use Add by URL to reach missing projects. {githubProjectPartialFailures - .map( - (failure) => - `${failure.owner === '*' ? 'orgs' : failure.owner}: ${failure.message}` + .map(({ owner, message }) => + owner === '*' + ? translate( + 'tasks.githubProjectPickers.organizationsError', + 'orgs: {{message}}', + { message } + ) + : `${owner}: ${message}` ) .join(' · ')} @@ -129,21 +163,29 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati onPress={() => void loadGitHubProjects().catch((err) => { setGithubProjectError( - err instanceof Error ? err.message : 'Failed to load projects' + err instanceof Error + ? err.message + : translate('tasks.githubProjectPickers.loadFailed', 'Failed to load projects') ) }) } > - No projects loaded - Tap to retry. + + {translate('tasks.githubProjectPickers.noProjects', 'No projects loaded')} + + + {translate('tasks.githubProjectPickers.retryHint', 'Tap to retry.')} + ) : ( <> {pinnedGitHubProjects.length > 0 ? ( <> - Pinned + + {translate('tasks.githubProjectPickers.pinned', 'Pinned')} + {pinnedGitHubProjects.map((project, index) => { const key = githubProjectKey(project) const selected = @@ -178,7 +220,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati }) }} > - Remove + + {translate('common.remove', 'Remove')} + {selected ? : null} @@ -190,7 +234,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati {recentGitHubProjects.length > 0 ? ( <> - Recent + + {translate('tasks.githubProjectPickers.recent', 'Recent')} + {recentGitHubProjects.map((project, index) => { const key = githubProjectKey(project) const selected = @@ -231,7 +277,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati }) }} > - Pin + + {translate('tasks.githubProjectPickers.pin', 'Pin')} + ) : null} {selected ? : null} @@ -243,11 +291,15 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati ) : null} - {githubProjectLoading ? 'Browse all (loading...)' : 'Browse all'} + {githubProjectLoading + ? translate('tasks.githubProjectPickers.browseLoading', 'Browse all (loading...)') + : translate('tasks.githubProjectPickers.browseAll', 'Browse all')} {browseGitHubProjects.length === 0 ? ( - {githubProjectPickerSearch.trim() ? 'No matching projects.' : 'No more projects.'} + {githubProjectPickerSearch.trim() + ? translate('tasks.githubProjectPickers.noMatches', 'No matching projects.') + : translate('tasks.githubProjectPickers.noMoreProjects', 'No more projects.')} ) : ( browseGitHubProjects.map((project, index) => { @@ -286,46 +338,43 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati } export function renderMobileTasksGitHubProjectViewPicker(model: ConnectionPresentationModel) { - const { - activeGitHubProject, - activeGitHubProjectKey, - activeGitHubProjectViewId, - commitGitHubProjectView, - githubProjectViewOptions, - githubProjectViews, - pendingGitHubProjectViewSelection, - setGithubProjectError, - setPendingGitHubProjectViewSelection, - setShowGitHubProjectViewPicker, - showGitHubProjectViewPicker, - taskUiReady - } = model return ( { - const view = githubProjectViews.find((candidate) => candidate.id === viewId) + const view = model.githubProjectViews.find((candidate) => candidate.id === viewId) if (view && view.layout !== 'TABLE_LAYOUT') { - setGithubProjectError("Orca doesn't support this GitHub Project layout yet.") + model.setGithubProjectError( + translate( + 'tasks.githubProjectPickers.unsupportedLayout', + "Orca doesn't support this GitHub Project layout yet." + ) + ) return } - if (pendingGitHubProjectViewSelection) { - commitGitHubProjectView(pendingGitHubProjectViewSelection, viewId) - setPendingGitHubProjectViewSelection(null) + if (model.pendingGitHubProjectViewSelection) { + model.commitGitHubProjectView(model.pendingGitHubProjectViewSelection, viewId) + model.setPendingGitHubProjectViewSelection(null) return } - if (!activeGitHubProject || !activeGitHubProjectKey) { + if (!model.activeGitHubProject || !model.activeGitHubProjectKey) { return } - commitGitHubProjectView(activeGitHubProject, viewId) + model.commitGitHubProjectView(model.activeGitHubProject, viewId) }} onClose={() => { - setShowGitHubProjectViewPicker(false) - if (pendingGitHubProjectViewSelection) { - setPendingGitHubProjectViewSelection(null) + model.setShowGitHubProjectViewPicker(false) + if (model.pendingGitHubProjectViewSelection) { + model.setPendingGitHubProjectViewSelection(null) } }} /> @@ -333,26 +382,18 @@ export function renderMobileTasksGitHubProjectViewPicker(model: ConnectionPresen } export function renderMobileTasksGitHubProjectSortPicker(model: ConnectionPresentationModel) { - const { - githubProjectSortOptions, - githubProjectSortOverride, - setGithubProjectSortOverride, - setShowGitHubProjectSortPicker, - showGitHubProjectSortPicker, - taskUiReady - } = model return ( { if (fieldId === PROJECT_VIEW_DEFAULT_SORT) { - setGithubProjectSortOverride(null) + model.setGithubProjectSortOverride(null) return } - setGithubProjectSortOverride((current) => { + model.setGithubProjectSortOverride((current) => { if (!current || current.fieldId !== fieldId) { return { fieldId, direction: 'ASC' } } @@ -362,7 +403,7 @@ export function renderMobileTasksGitHubProjectSortPicker(model: ConnectionPresen return null }) }} - onClose={() => setShowGitHubProjectSortPicker(false)} + onClose={() => model.setShowGitHubProjectSortPicker(false)} /> ) } diff --git a/mobile/src/tasks/mobile-tasks-github-view-controls.tsx b/mobile/src/tasks/mobile-tasks-github-view-controls.tsx index 820c2642962..53fffa90001 100644 --- a/mobile/src/tasks/mobile-tasks-github-view-controls.tsx +++ b/mobile/src/tasks/mobile-tasks-github-view-controls.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { Pressable, Text, View, Linking, ExternalLink, colors } from './mobile-tasks-dependencies' import { styles } from './mobile-tasks-legacy-styles' @@ -67,7 +68,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio setShowGitHubIssueSourcePicker(true) }} > - Source: {githubIssueSourceLabel} + + {translate('tasks.githubViewControls.source', 'Source: {{source}}', { + source: githubIssueSourceLabel + })} + ) : null} @@ -110,7 +115,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio setShowGitHubProjectSortPicker(true) }} > - Sort: {githubProjectSortLabel} + + {translate('tasks.githubViewControls.sort', 'Sort: {{sort}}', { + sort: githubProjectSortLabel + })} + ) : null} {githubProjectAvailableSummaryFields.length > 0 ? ( @@ -124,7 +133,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio setShowGitHubProjectFieldsPicker(true) }} > - Fields: {githubProjectFieldsLabel} + + {translate('tasks.githubViewControls.fields', 'Fields: {{fields}}', { + fields: githubProjectFieldsLabel + })} + ) : null} {githubProjectTable ? ( @@ -135,7 +148,10 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio {selectedGitHubProjectViewUrl ? ( { diff --git a/mobile/src/tasks/mobile-tasks-item-actions.tsx b/mobile/src/tasks/mobile-tasks-item-actions.tsx index d6fc046e771..cb7ef55ff2d 100644 --- a/mobile/src/tasks/mobile-tasks-item-actions.tsx +++ b/mobile/src/tasks/mobile-tasks-item-actions.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { View, Pressable, @@ -59,7 +60,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) > - {creatingKey === actionItem.key ? 'Creating...' : 'Create Workspace'} + {creatingKey === actionItem.key + ? translate('tasks.itemActions.creating', 'Creating...') + : translate('tasks.itemActions.createWorkspace', 'Create Workspace')} @@ -83,7 +86,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) > - {copiedLinkKey === `linear-url:${actionItem.key}` ? 'Copied' : 'Copy Linear link'} + {copiedLinkKey === `linear-url:${actionItem.key}` + ? translate('common.copied', 'Copied') + : translate('tasks.itemActions.copyLinearLink', 'Copy Linear link')} @@ -98,7 +103,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) > - {copiedLinkKey === `task:${actionItem.key}` ? 'Copied' : 'Copy GitHub link'} + {copiedLinkKey === `task:${actionItem.key}` + ? translate('common.copied', 'Copied') + : translate('tasks.itemActions.copyGitHubLink', 'Copy GitHub link')} @@ -142,10 +149,14 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) } > - Merge pull request + + {translate('tasks.itemActions.mergePullRequest', 'Merge pull request')} + {isGitHubPrMergeBlocked(actionItem) ? ( - GitHub reports merge conflicts. + + {translate('tasks.itemActions.mergeConflicts', 'GitHub reports merge conflicts.')} + ) : null} ) : null} @@ -190,7 +201,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) } > - Merge merge request + + {translate('tasks.itemActions.mergeMergeRequest', 'Merge merge request')} + ) : null} @@ -206,7 +219,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel) }} > - Change status + + {translate('tasks.itemActions.changeStatus', 'Change status')} + ) : null} diff --git a/mobile/src/tasks/mobile-tasks-item-detail-content.tsx b/mobile/src/tasks/mobile-tasks-item-detail-content.tsx index dc6e4cb7c48..4417dca09f3 100644 --- a/mobile/src/tasks/mobile-tasks-item-detail-content.tsx +++ b/mobile/src/tasks/mobile-tasks-item-detail-content.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { isBrokenCheck } from '../../../src/shared/pr-checks-fix-prompt' import { View, @@ -27,6 +28,12 @@ import { import { renderMobileTasksItemFieldEditors } from './mobile-tasks-item-field-editors' import { JiraDetailMeta } from '../components/JiraDetailMeta' +function pipelineJobsSummary(count: number): string { + return count === 1 + ? translate('tasks.itemDetailContent.pipelineJobs_one', '{{count}} jobs', { count }) + : translate('tasks.itemDetailContent.pipelineJobs_other', '{{count}} jobs', { count }) +} + export function renderMobileTasksItemDetailContent(model: ConnectionPresentationModel) { const { actionItem, @@ -63,22 +70,30 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation <> - Type + + {translate('tasks.itemDetailContent.type', 'Type')} + {taskKindLabel(actionItem)} - Status + + {translate('tasks.itemDetailContent.status', 'Status')} + {actionItem.status} {detailPayload.provider === 'linear' && detailPayload.assignee ? ( - Assignee + + {translate('tasks.itemDetailContent.assignee', 'Assignee')} + {detailPayload.assignee} ) : null} {detailPayload.provider === 'linear' && detailPayload.project ? ( - Project + + {translate('tasks.itemDetailContent.project', 'Project')} + {detailPayload.project.name} ) : null} @@ -92,7 +107,9 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation {(detailPayload.provider === 'github' || detailPayload.provider === 'gitlab') && detailPayload.assignees.length > 0 ? ( - Assignees + + {translate('tasks.itemDetailContent.assignees', 'Assignees')} + {detailPayload.assignees.join(', ')} ) : null} @@ -109,7 +126,9 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation ) : null} - Description + + {translate('tasks.itemDetailContent.description', 'Description')} + {renderMobileTasksItemBodyEditor(model)} @@ -123,33 +142,41 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation actionItem.source.type === 'pr' ? ( - Checks + + {translate('tasks.itemDetailContent.checks', 'Checks')} + void refreshGitHubChecks(actionItem)} > - Refresh + {translate('common.refresh', 'Refresh')} void rerunGitHubChecks(actionItem, true)} > - Rerun failed + + {translate('tasks.itemDetailContent.rerunFailed', 'Rerun failed')} + void rerunGitHubChecks(actionItem, false)} > - Rerun all + + {translate('tasks.itemDetailContent.rerunAll', 'Rerun all')} + {detailPayload.checks.length === 0 ? ( - No checks found. + + {translate('tasks.itemDetailContent.noChecks', 'No checks found.')} + ) : ( detailPayload.checks.map((check) => ( - Pipeline + + {translate('tasks.itemDetailContent.pipeline', 'Pipeline')} + {detailPayload.pipelineJobs.length - ? `${detailPayload.pipelineJobs.length} jobs` - : 'None'} + ? pipelineJobsSummary(detailPayload.pipelineJobs.length) + : translate('tasks.itemDetailContent.none', 'None')} {detailPayload.pipelineJobs.length === 0 ? ( - No pipeline runs for this MR. + + {translate('tasks.itemDetailContent.noPipelineRuns', 'No pipeline runs for this MR.')} + ) : ( detailPayload.pipelineJobs.map((job) => { const duration = formatDurationSeconds(job.duration) @@ -228,11 +259,17 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation actionItem.provider === 'linear' ? ( - Sub-issues - {detailPayload.children.length || 'None'} + + {translate('tasks.itemDetailContent.subIssues', 'Sub-issues')} + + + {detailPayload.children.length || translate('tasks.itemDetailContent.none', 'None')} + {detailPayload.children.length === 0 ? ( - No sub-issues. + + {translate('tasks.itemDetailContent.noSubIssues', 'No sub-issues.')} + ) : ( detailPayload.children.map((child) => ( {child.identifier} · {child.title} - Open + {translate('common.open', 'Open')} )) )} @@ -252,7 +289,7 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation style={[styles.input, styles.stackedInput]} value={linearSubIssueTitle} onChangeText={setLinearSubIssueTitle} - placeholder="Sub-issue title" + placeholder={translate('tasks.itemDetailContent.subIssueTitle', 'Sub-issue title')} placeholderTextColor={colors.textMuted} /> void createLinearSubIssue(actionItem)} > - Add sub-issue + + {translate('tasks.itemDetailContent.addSubIssue', 'Add sub-issue')} + ) : null} - Discussion + + {translate('tasks.itemDetailContent.discussion', 'Discussion')} + {discussionSummary(detailPayload.comments.length)} {detailPayload.comments.length === 0 ? ( - No comments. + + {translate('tasks.itemDetailContent.noComments', 'No comments.')} + ) : ( detailCommentGroups.map(renderDetailCommentGroup) )} diff --git a/mobile/src/tasks/mobile-tasks-item-detail-drawer.tsx b/mobile/src/tasks/mobile-tasks-item-detail-drawer.tsx index 7096b0f088f..56c8532c257 100644 --- a/mobile/src/tasks/mobile-tasks-item-detail-drawer.tsx +++ b/mobile/src/tasks/mobile-tasks-item-detail-drawer.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -32,7 +33,10 @@ export function renderMobileTasksItemDetailDrawer(model: ConnectionPresentationM setDetailRefreshSeq((current) => current + 1)} > - Title + + {translate('tasks.itemFieldEditors.title', 'Title')} + - Save title + + {translate('tasks.itemFieldEditors.saveTitle', 'Save title')} + - Labels - {detailPayload.labels.length || 'None'} + + {translate('tasks.itemFieldEditors.labels', 'Labels')} + + + {detailPayload.labels.length || translate('tasks.itemFieldEditors.none', 'None')} + {actionItem.provider === 'github' ? ( itemLabelsLoading ? ( - Loading labels... + + {translate('tasks.itemFieldEditors.loadingLabels', 'Loading labels...')} + ) : itemLabelsError ? ( {itemLabelsError} ) : itemAvailableLabels.length === 0 ? ( - No labels in this repository. + + {translate('tasks.itemFieldEditors.noLabels', 'No labels in this repository.')} + ) : ( {[...new Set([...itemAvailableLabels, ...detailPayload.labels])].map((label) => { @@ -136,7 +149,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM style={styles.input} value={itemAddLabelsDraft} onChangeText={setItemAddLabelsDraft} - placeholder="Add labels, comma separated" + placeholder={translate( + 'tasks.itemFieldEditors.addLabels', + 'Add labels, comma separated' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -144,7 +160,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM style={[styles.input, styles.stackedInput]} value={itemRemoveLabelsDraft} onChangeText={setItemRemoveLabelsDraft} - placeholder="Remove labels, comma separated" + placeholder={translate( + 'tasks.itemFieldEditors.removeLabels', + 'Remove labels, comma separated' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -162,7 +181,9 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM }) } > - Update labels + + {translate('tasks.itemFieldEditors.updateLabels', 'Update labels')} + )} @@ -170,19 +191,30 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM - Assignees - {detailPayload.assignees.length || 'None'} + + {translate('tasks.itemFieldEditors.assignees', 'Assignees')} + + + {detailPayload.assignees.length || translate('tasks.itemFieldEditors.none', 'None')} + {actionItem.provider === 'github' ? ( itemAssignableUsersLoading ? ( - Loading assignees... + + {translate('tasks.itemFieldEditors.loadingAssignees', 'Loading assignees...')} + ) : itemAssignableUsersError ? ( {itemAssignableUsersError} ) : itemAssignableUsers.length === 0 ? ( - No assignable users found for this repository. + + {translate( + 'tasks.itemFieldEditors.noAssignableUsers', + 'No assignable users found for this repository.' + )} + ) : ( {[ @@ -227,7 +259,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM style={styles.input} value={itemAddAssigneesDraft} onChangeText={setItemAddAssigneesDraft} - placeholder="Add usernames, comma separated" + placeholder={translate( + 'tasks.itemFieldEditors.addUsernames', + 'Add usernames, comma separated' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -235,7 +270,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM style={[styles.input, styles.stackedInput]} value={itemRemoveAssigneesDraft} onChangeText={setItemRemoveAssigneesDraft} - placeholder="Remove usernames, comma separated" + placeholder={translate( + 'tasks.itemFieldEditors.removeUsernames', + 'Remove usernames, comma separated' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -253,7 +291,9 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM }) } > - Update assignees + + {translate('tasks.itemFieldEditors.updateAssignees', 'Update assignees')} + ) : null} diff --git a/mobile/src/tasks/mobile-tasks-item-review-sections.tsx b/mobile/src/tasks/mobile-tasks-item-review-sections.tsx index 04c58eea62e..1014342c0d6 100644 --- a/mobile/src/tasks/mobile-tasks-item-review-sections.tsx +++ b/mobile/src/tasks/mobile-tasks-item-review-sections.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { SHOW_MOBILE_DETAIL_METADATA_EDITORS, SHOW_MOBILE_DETAIL_REVIEW_PANELS, @@ -46,7 +47,7 @@ export function renderMobileTasksItemBodyEditor(model: ConnectionPresentationMod style={[styles.input, styles.bodyInput]} value={itemBodyDraft} onChangeText={setItemBodyDraft} - placeholder="Description" + placeholder={translate('tasks.itemReviewSections.descriptionPlaceholder', 'Description')} placeholderTextColor={colors.textMuted} multiline textAlignVertical="top" @@ -77,12 +78,20 @@ export function renderMobileTasksItemBodyEditor(model: ConnectionPresentationMod } }} > - Save description + + {translate('tasks.itemReviewSections.saveDescription', 'Save description')} + - + ) : ( - + ) } @@ -107,14 +116,18 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo actionItem.source.type === 'pr' ? ( - Reviewers + + {translate('tasks.itemReviewSections.reviewersTitle', 'Reviewers')} + {detailPayload.provider === 'github' ? ( {getGitHubReviewSummary(detailPayload)} ) : null} {detailPayload.provider === 'github' ? ( getGitHubReviewerRows(detailPayload).length === 0 ? ( - No reviewers requested. + + {translate('tasks.itemReviewSections.noReviewersRequested', 'No reviewers requested.')} + ) : ( getGitHubReviewerRows(detailPayload).map((reviewer) => ( @@ -141,12 +154,19 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo {itemAssignableUsersLoading ? ( - Loading reviewers... + + {translate('tasks.itemReviewSections.loadingReviewers', 'Loading reviewers...')} + ) : itemAssignableUsersError ? ( {itemAssignableUsersError} ) : itemReviewerCandidates.length === 0 ? ( - No reviewer suggestions found. + + {translate( + 'tasks.itemReviewSections.noReviewerSuggestions', + 'No reviewer suggestions found.' + )} + ) : ( {itemReviewerCandidates.map((user) => { @@ -171,7 +191,10 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo style={styles.input} value={itemReviewersDraft} onChangeText={setItemReviewersDraft} - placeholder="Request reviewers" + placeholder={translate( + 'tasks.itemReviewSections.reviewersPlaceholder', + 'Request reviewers' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -180,7 +203,9 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo disabled={mutatingStatus || splitReviewerList(itemReviewersDraft).length === 0} onPress={() => void requestGitHubReviewers(actionItem)} > - Request review + + {translate('tasks.itemReviewSections.requestReview', 'Request review')} + ) : null @@ -207,7 +232,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) { detailPayload.provider === 'github' && detailPayload.files.length > 0 ? ( - Changed files + + {translate('tasks.itemReviewSections.changedFilesTitle', 'Changed files')} + {detailPayload.files.map((file) => actionItem.provider === 'github' && actionItem.source.type === 'pr' ? ( @@ -223,7 +250,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) { : ''} - {expandedPrFilePath === file.path ? 'Hide' : 'View'} + {expandedPrFilePath === file.path + ? translate('tasks.itemReviewSections.hideFile', 'Hide') + : translate('tasks.itemReviewSections.viewFile', 'View')} void toggleGitHubFileViewed(actionItem, file)} > - {file.viewerViewedState === 'VIEWED' ? 'Mark unviewed' : 'Mark viewed'} + {file.viewerViewedState === 'VIEWED' + ? translate('tasks.itemReviewSections.markUnviewed', 'Mark unviewed') + : translate('tasks.itemReviewSections.markViewed', 'Mark viewed')} {expandedPrFilePath === file.path ? ( @@ -241,7 +272,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) { ) : prFileContents[file.path]?.originalIsBinary || prFileContents[file.path]?.modifiedIsBinary ? ( - Binary file. + + {translate('tasks.itemReviewSections.binaryFile', 'Binary file.')} + ) : prFileContents[file.path] ? ( ) : ( - File contents unavailable. + + {translate( + 'tasks.itemReviewSections.fileContentsUnavailable', + 'File contents unavailable.' + )} + )} ) : null} diff --git a/mobile/src/tasks/mobile-tasks-linear-list.tsx b/mobile/src/tasks/mobile-tasks-linear-list.tsx index a43313c8d32..b494a21be16 100644 --- a/mobile/src/tasks/mobile-tasks-linear-list.tsx +++ b/mobile/src/tasks/mobile-tasks-linear-list.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { View, ActivityIndicator, @@ -86,7 +87,13 @@ export function renderMobileTasksLinearList( style={[styles.statusPillSelf, styles.linearStatePill]} disabled={mutatingStatus} accessibilityRole="button" - accessibilityLabel={`Change status from ${issue.state.name}`} + accessibilityLabel={translate( + 'tasks.linearList.changeStatusFrom', + 'Change status from {{status}}', + { + status: issue.state.name + } + )} onPress={(event) => { event.stopPropagation() triggerMediumImpact() @@ -175,7 +182,13 @@ export function renderMobileTasksLinearList( style={[styles.statusPill, styles.linearStatePill]} disabled={mutatingStatus} accessibilityRole="button" - accessibilityLabel={`Change status from ${issue.state.name}`} + accessibilityLabel={translate( + 'tasks.linearList.changeStatusFrom', + 'Change status from {{status}}', + { + status: issue.state.name + } + )} onPress={(event) => { event.stopPropagation() triggerMediumImpact() diff --git a/mobile/src/tasks/mobile-tasks-linear-view-controls.tsx b/mobile/src/tasks/mobile-tasks-linear-view-controls.tsx index e680049c12b..a14eea4d8e1 100644 --- a/mobile/src/tasks/mobile-tasks-linear-view-controls.tsx +++ b/mobile/src/tasks/mobile-tasks-linear-view-controls.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { Pressable, Text } from './mobile-tasks-dependencies' import { styles } from './mobile-tasks-legacy-styles' @@ -86,7 +87,11 @@ export function renderMobileTasksLinearViewControls(model: ConnectionPresentatio setShowLinearGroupPicker(true) }} > - Group: {linearGroupLabel} + + {translate('tasks.linearViewControls.groupLabel', 'Group: {{group}}', { + group: linearGroupLabel + })} + - Order: {linearOrderLabel} + + {translate('tasks.linearViewControls.orderLabel', 'Order: {{order}}', { + order: linearOrderLabel + })} + - Display + + {translate('tasks.linearViewControls.displayButton', 'Display')} + ) diff --git a/mobile/src/tasks/mobile-tasks-list-display-pickers.tsx b/mobile/src/tasks/mobile-tasks-list-display-pickers.tsx index 0efb5ea993c..f70e97405b4 100644 --- a/mobile/src/tasks/mobile-tasks-list-display-pickers.tsx +++ b/mobile/src/tasks/mobile-tasks-list-display-pickers.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -28,7 +29,7 @@ export function renderMobileTasksLinearViewPicker(model: ConnectionPresentationM return ( setShowLinearDisplayPicker(false)} > - Display Properties + + {translate('tasks.listDisplayPickers.displayPropertiesTitle', 'Display Properties')} + {LINEAR_DISPLAY_OPTIONS.map((property, index) => { @@ -135,7 +138,7 @@ export function renderMobileTasksSortPicker(model: ConnectionPresentationModel) return ( - Update Orca desktop + + {translate('tasks.listSurface.updateDesktopTitle', 'Update Orca desktop')} + - This mobile Tasks view needs a newer desktop runtime. + {translate( + 'tasks.listSurface.updateDesktopMessage', + 'This mobile Tasks view needs a newer desktop runtime.' + )} ) : ( @@ -53,16 +59,25 @@ export function renderMobileTasksListSurface( disabled={!taskUiReady} onCheckAgain={() => { void refreshJiraConnection().catch((err: unknown) => { - setError(err instanceof Error ? err.message : 'Failed to read Jira status') + setError( + err instanceof Error + ? err.message + : translate('tasks.listSurface.jiraStatusFailed', 'Failed to read Jira status') + ) }) }} /> ) : provider === 'linear' && !linearConnected ? ( - Connect your Linear account + + {translate('tasks.listSurface.connectLinearTitle', 'Connect your Linear account')} + - Browse and start work on your assigned Linear issues directly from Tasks. + {translate( + 'tasks.listSurface.connectLinearMessage', + 'Browse and start work on your assigned Linear issues directly from Tasks.' + )} - Connect Linear + + {translate('tasks.listSurface.connectLinearButton', 'Connect Linear')} + ) : provider === 'github' && githubMode === 'project' ? ( diff --git a/mobile/src/tasks/mobile-tasks-options.tsx b/mobile/src/tasks/mobile-tasks-options.tsx index 12b1dee3b01..137fbf6aef7 100644 --- a/mobile/src/tasks/mobile-tasks-options.tsx +++ b/mobile/src/tasks/mobile-tasks-options.tsx @@ -23,12 +23,30 @@ import type { } from './mobile-tasks-view-state-types' import type { ActionableTaskItem } from './mobile-tasks-project-workspace-types' import type { LinearIssue } from './mobile-tasks-provider-detail-types' +import { translate } from '../i18n/mobile-i18n' -export const PROVIDER_OPTIONS: PickerOption[] = [ +type TaskOptionCopy = Omit, 'label' | 'subtitle'> & { + label: string | (() => string) + subtitle?: () => string +} + +function localizedTaskOptions(options: TaskOptionCopy[]): PickerOption[] { + return options.map(({ label, subtitle, ...option }) => ({ + ...option, + get label() { + return typeof label === 'string' ? label : label() + }, + get subtitle() { + return subtitle?.() + } + })) +} + +export const PROVIDER_OPTIONS = localizedTaskOptions([ { value: 'github', label: 'GitHub', - subtitle: 'Issues and pull requests', + subtitle: () => translate('tasks.options.githubDescription', 'Issues and pull requests'), renderIcon: (selected) => ( [] = [ { value: 'gitlab', label: 'GitLab', - subtitle: 'Issues and merge requests', + subtitle: () => translate('tasks.options.gitlabDescription', 'Issues and merge requests'), renderIcon: (selected) => ( [] = [ { value: 'linear', label: 'Linear', - subtitle: 'Assigned and team issues', + subtitle: () => translate('tasks.options.linearDescription', 'Assigned and team issues'), renderIcon: (selected) => ( [] = [ { value: 'jira', label: 'Jira', - subtitle: 'Assigned and reported issues', + subtitle: () => translate('tasks.options.jiraDescription', 'Assigned and reported issues'), renderIcon: (selected) => ( [] = [ /> ) } -] +]) -export const GITLAB_FILTER_OPTIONS: PickerOption[] = [ - { value: 'opened', label: 'Open', subtitle: 'Open issues and merge requests' }, - { value: 'merged', label: 'Merged', subtitle: 'Merged merge requests' }, - { value: 'closed', label: 'Closed', subtitle: 'Closed issues and merge requests' }, - { value: 'all', label: 'All', subtitle: 'Any GitLab state' } -] +export const GITLAB_FILTER_OPTIONS = localizedTaskOptions([ + { + value: 'opened', + label: () => translate('tasks.options.openState', 'Open'), + subtitle: () => + translate('tasks.options.gitlabOpenDescription', 'Open issues and merge requests') + }, + { + value: 'merged', + label: () => translate('tasks.options.mergedState', 'Merged'), + subtitle: () => translate('tasks.options.gitlabMergedDescription', 'Merged merge requests') + }, + { + value: 'closed', + label: () => translate('tasks.options.closedState', 'Closed'), + subtitle: () => + translate('tasks.options.gitlabClosedDescription', 'Closed issues and merge requests') + }, + { + value: 'all', + label: () => translate('tasks.options.all', 'All'), + subtitle: () => translate('tasks.options.gitlabAllDescription', 'Any GitLab state') + } +]) -export const LINEAR_FILTER_OPTIONS: PickerOption[] = [ - { value: 'all', label: 'All', subtitle: 'Open issues across connected workspaces' }, - { value: 'assigned', label: 'My Issues', subtitle: 'Issues assigned to you' }, - { value: 'created', label: 'Created', subtitle: 'Issues created by you' }, - { value: 'completed', label: 'Completed', subtitle: 'Recently completed issues' } -] +export const LINEAR_FILTER_OPTIONS = localizedTaskOptions([ + { + value: 'all', + label: () => translate('tasks.options.all', 'All'), + subtitle: () => + translate('tasks.options.linearAllDescription', 'Open issues across connected workspaces') + }, + { + value: 'assigned', + label: () => translate('tasks.options.myIssues', 'My Issues'), + subtitle: () => translate('tasks.options.linearAssignedDescription', 'Issues assigned to you') + }, + { + value: 'created', + label: () => translate('tasks.options.createdState', 'Created'), + subtitle: () => translate('tasks.options.linearCreatedDescription', 'Issues created by you') + }, + { + value: 'completed', + label: () => translate('tasks.options.completedState', 'Completed'), + subtitle: () => + translate('tasks.options.linearCompletedDescription', 'Recently completed issues') + } +]) -export const LINEAR_VIEW_OPTIONS: PickerOption[] = [ - { value: 'list', label: 'List', subtitle: 'Compact issue rows' }, - { value: 'board', label: 'Board', subtitle: 'Grouped columns' } -] +export const LINEAR_VIEW_OPTIONS = localizedTaskOptions([ + { + value: 'list', + label: () => translate('tasks.options.list', 'List'), + subtitle: () => translate('tasks.options.listDescription', 'Compact issue rows') + }, + { + value: 'board', + label: () => translate('tasks.options.board', 'Board'), + subtitle: () => translate('tasks.options.boardDescription', 'Grouped columns') + } +]) export function taskWorkspaceFallback(item: ActionableTaskItem): string { if (item.provider === 'github' || item.provider === 'gitlab') { @@ -120,28 +182,28 @@ export const COMMENT_REACTION_EMOJI: Record = { eyes: 'eyes' } -export const LINEAR_GROUP_OPTIONS: PickerOption[] = [ - { value: 'none', label: 'No grouping' }, - { value: 'status', label: 'Status' }, - { value: 'assignee', label: 'Assignee' }, - { value: 'priority', label: 'Priority' }, - { value: 'team', label: 'Team' } -] +export const LINEAR_GROUP_OPTIONS = localizedTaskOptions([ + { value: 'none', label: () => translate('tasks.options.noGrouping', 'No grouping') }, + { value: 'status', label: () => translate('tasks.options.status', 'Status') }, + { value: 'assignee', label: () => translate('tasks.options.assignee', 'Assignee') }, + { value: 'priority', label: () => translate('tasks.options.priority', 'Priority') }, + { value: 'team', label: () => translate('tasks.options.team', 'Team') } +]) -export const LINEAR_ORDER_OPTIONS: PickerOption[] = [ - { value: 'priority', label: 'Priority' }, - { value: 'updated', label: 'Updated' }, - { value: 'identifier', label: 'Identifier' } -] +export const LINEAR_ORDER_OPTIONS = localizedTaskOptions([ + { value: 'priority', label: () => translate('tasks.options.priority', 'Priority') }, + { value: 'updated', label: () => translate('tasks.options.updated', 'Updated') }, + { value: 'identifier', label: () => translate('tasks.options.identifier', 'Identifier') } +]) -export const LINEAR_DISPLAY_OPTIONS: PickerOption[] = [ - { value: 'state', label: 'Status' }, - { value: 'priority', label: 'Priority' }, - { value: 'assignee', label: 'Assignee' }, - { value: 'team', label: 'Team' }, - { value: 'labels', label: 'Labels' }, - { value: 'updated', label: 'Updated' } -] +export const LINEAR_DISPLAY_OPTIONS = localizedTaskOptions([ + { value: 'state', label: () => translate('tasks.options.status', 'Status') }, + { value: 'priority', label: () => translate('tasks.options.priority', 'Priority') }, + { value: 'assignee', label: () => translate('tasks.options.assignee', 'Assignee') }, + { value: 'team', label: () => translate('tasks.options.team', 'Team') }, + { value: 'labels', label: () => translate('tasks.options.labels', 'Labels') }, + { value: 'updated', label: () => translate('tasks.options.updated', 'Updated') } +]) export const DEFAULT_LINEAR_DISPLAY_PROPERTIES: LinearDisplayProperty[] = [ 'state', @@ -152,36 +214,91 @@ export const DEFAULT_LINEAR_DISPLAY_PROPERTIES: LinearDisplayProperty[] = [ 'updated' ] -export const GITHUB_KIND_OPTIONS: PickerOption[] = [ - { value: 'issues', label: 'Issues', subtitle: 'GitHub issues' }, - { value: 'prs', label: 'PRs', subtitle: 'GitHub pull requests' }, - { value: 'project', label: 'Projects', subtitle: 'GitHub Projects views' } -] +export const GITHUB_KIND_OPTIONS = localizedTaskOptions([ + { + value: 'issues', + label: () => translate('tasks.options.issues', 'Issues'), + subtitle: () => translate('tasks.options.githubIssuesDescription', 'GitHub issues') + }, + { + value: 'prs', + label: () => translate('tasks.options.pullRequests', 'PRs'), + subtitle: () => translate('tasks.options.githubPullRequestsDescription', 'GitHub pull requests') + }, + { + value: 'project', + label: () => translate('tasks.options.projects', 'Projects'), + subtitle: () => translate('tasks.options.githubProjectsDescription', 'GitHub Projects views') + } +]) -export const ISSUE_PRESETS: PickerOption[] = [ - { value: 'issues', label: 'Open', subtitle: 'Open GitHub issues' }, - { value: 'my-issues', label: 'Assigned to me', subtitle: 'Open issues assigned to you' } -] +export const ISSUE_PRESETS = localizedTaskOptions([ + { + value: 'issues', + label: () => translate('tasks.options.openState', 'Open'), + subtitle: () => translate('tasks.options.githubOpenIssuesDescription', 'Open GitHub issues') + }, + { + value: 'my-issues', + label: () => translate('tasks.options.assignedToMe', 'Assigned to me'), + subtitle: () => + translate('tasks.options.githubAssignedIssuesDescription', 'Open issues assigned to you') + } +]) -export const PR_PRESETS: PickerOption[] = [ - { value: 'prs', label: 'Open', subtitle: 'Open pull requests' }, - { value: 'my-prs', label: 'Mine', subtitle: 'Pull requests authored by you' }, - { value: 'review', label: 'Needs review', subtitle: 'Review requests assigned to you' } -] +export const PR_PRESETS = localizedTaskOptions([ + { + value: 'prs', + label: () => translate('tasks.options.openState', 'Open'), + subtitle: () => translate('tasks.options.openPullRequestsDescription', 'Open pull requests') + }, + { + value: 'my-prs', + label: () => translate('tasks.options.mine', 'Mine'), + subtitle: () => + translate('tasks.options.myPullRequestsDescription', 'Pull requests authored by you') + }, + { + value: 'review', + label: () => translate('tasks.options.needsReview', 'Needs review'), + subtitle: () => + translate('tasks.options.reviewRequestsDescription', 'Review requests assigned to you') + } +]) -export const GITLAB_VIEW_OPTIONS: PickerOption[] = [ - { value: 'project', label: 'Project MRs', subtitle: 'Merge requests and issues by repository' }, - { value: 'todos', label: 'My Todos', subtitle: 'Pending GitLab todos' } -] +export const GITLAB_VIEW_OPTIONS = localizedTaskOptions([ + { + value: 'project', + label: () => translate('tasks.options.projectMergeRequests', 'Project MRs'), + subtitle: () => + translate( + 'tasks.options.projectMergeRequestsDescription', + 'Merge requests and issues by repository' + ) + }, + { + value: 'todos', + label: () => translate('tasks.options.myTodos', 'My Todos'), + subtitle: () => translate('tasks.options.myTodosDescription', 'Pending GitLab todos') + } +]) -export const SORT_OPTIONS: PickerOption[] = [ - { value: 'updated', label: 'Updated', subtitle: 'Newest activity first' }, +export const SORT_OPTIONS = localizedTaskOptions([ + { + value: 'updated', + label: () => translate('tasks.options.updated', 'Updated'), + subtitle: () => translate('tasks.options.updatedSortDescription', 'Newest activity first') + }, { value: 'repository', - label: 'Repository', - subtitle: 'Group by repository, then newest activity' + label: () => translate('tasks.options.repository', 'Repository'), + subtitle: () => + translate( + 'tasks.options.repositorySortDescription', + 'Group by repository, then newest activity' + ) } -] +]) export type ProjectSortOverride = { fieldId: string; direction: GitHubProjectSortDirection } diff --git a/mobile/src/tasks/mobile-tasks-project-comments.tsx b/mobile/src/tasks/mobile-tasks-project-comments.tsx index c3a8037f827..a5779028f23 100644 --- a/mobile/src/tasks/mobile-tasks-project-comments.tsx +++ b/mobile/src/tasks/mobile-tasks-project-comments.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { View, Text, @@ -24,6 +25,12 @@ import { projectRowType } from './mobile-tasks-legacy-foundation' +function resolvedCommentCountLabel(count: number): string { + return count === 1 + ? translate('tasks.projectComments.comments_one', '{{count}} comment', { count }) + : translate('tasks.projectComments.comments_other', '{{count}} comments', { count }) +} + export function renderMobileTasksProjectComments(model: ConnectionPresentationModel) { const { addProjectRowComment, @@ -53,13 +60,17 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo return projectRowDetail?.provider === 'github' ? ( - Discussion + + {translate('tasks.projectComments.discussion', 'Discussion')} + {discussionSummary(projectRowDetail.comments.length)} {projectRowDetail.comments.length === 0 ? ( - No comments. + + {translate('tasks.projectComments.noComments', 'No comments.')} + ) : ( projectDetailCommentGroups.map((group) => { const groupId = detailCommentGroupId(group) @@ -81,11 +92,26 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo } > - Resolved {group.kind === 'thread' ? 'thread' : 'comment'} by{' ' as string} - {commentAuthor(root)} + {group.kind === 'thread' + ? translate( + 'tasks.projectComments.resolvedThreadBy', + 'Resolved thread by {{author}}', + { + author: commentAuthor(root) + } + ) + : translate( + 'tasks.projectComments.resolvedCommentBy', + 'Resolved comment by {{author}}', + { + author: commentAuthor(root) + } + )} - {count > 1 ? `${count} comments` : 'Show'} + {count > 1 + ? resolvedCommentCountLabel(count) + : translate('tasks.projectComments.show', 'Show')} ) @@ -120,7 +146,7 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo style={[styles.input, styles.commentInput]} value={projectEditingCommentDraft} onChangeText={setProjectEditingCommentDraft} - placeholder="Edit comment" + placeholder={translate('tasks.projectComments.editComment', 'Edit comment')} placeholderTextColor={colors.textMuted} multiline textAlignVertical="top" @@ -131,7 +157,9 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo disabled={projectMutating || projectEditingCommentDraft.trim().length === 0} onPress={() => void updateProjectRowComment(projectRowItem, comment)} > - Save + + {translate('common.save', 'Save')} + - Cancel + + {translate('common.cancel', 'Cancel')} + @@ -160,7 +190,12 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo } > - {comment.isResolved ? 'Reopen thread' : 'Resolve thread'} + {comment.isResolved + ? translate('tasks.projectComments.reopenThread', 'Reopen thread') + : translate( + 'tasks.projectComments.resolveThread', + 'Resolve thread' + )} ) : null} @@ -173,7 +208,7 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo [commentId]: next })) } - placeholder="Reply" + placeholder={translate('tasks.projectComments.reply', 'Reply')} placeholderTextColor={colors.textMuted} multiline textAlignVertical="top" @@ -183,7 +218,9 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo disabled={projectMutating || !(itemReplyDrafts[commentId] ?? '').trim()} onPress={() => void replyToProjectGitHubComment(projectRowItem, comment)} > - Reply + + {translate('tasks.projectComments.reply', 'Reply')} + - Edit + + {translate('common.edit', 'Edit')} + void deleteProjectRowComment(projectRowItem, comment)} > - Delete + + {translate('common.delete', 'Delete')} + ) : null} diff --git a/mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx b/mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx index 00effc9d9f3..12ab801b422 100644 --- a/mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx +++ b/mobile/src/tasks/mobile-tasks-project-detail-drawer.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { BottomDrawer, View, @@ -52,10 +53,15 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese {projectRepoNotInOrca ? ( - Repository not in Orca + + {translate('tasks.projectDetailDrawer.repositoryNotInOrca', 'Repository not in Orca')} + - {projectRepoNotInOrca.owner}/{projectRepoNotInOrca.repo} is not added to Orca. Add - this repository from the desktop app, then refresh mobile Tasks. + {translate( + 'tasks.projectDetailDrawer.addRepositoryFromDesktop', + '{{repository}} is not added to Orca. Add this repository from the desktop app, then refresh mobile Tasks.', + { repository: `${projectRepoNotInOrca.owner}/${projectRepoNotInOrca.repo}` } + )} @@ -70,7 +76,9 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese }} > - Open in GitHub + + {translate('tasks.projectDetailDrawer.openInGitHub', 'Open in GitHub')} + ) : null} {projectRepoNotInOrca.url ? : null} @@ -87,8 +95,8 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese {copiedLinkKey === `project-repo:${projectRepoNotInOrca.owner}/${projectRepoNotInOrca.repo}` - ? 'Copied' - : 'Copy repository'} + ? translate('common.copied', 'Copied') + : translate('tasks.projectDetailDrawer.copyRepository', 'Copy repository')} @@ -118,6 +126,7 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati projectRowHandoff, taskUiReady } = model + const projectNumber = projectRowItem?.content.number return ( - GitHub Project · {projectRowItem.content.repository ?? activeProjectLabel} - {projectRowItem.content.number ? ` #${projectRowItem.content.number}` : ''} + {translate( + 'tasks.projectDetailDrawer.projectSubtitle', + 'GitHub Project · {{repository}}{{itemNumber}}', + { + repository: projectRowItem.content.repository ?? activeProjectLabel, + itemNumber: projectNumber ? ` #${projectNumber}` : '' + } + )} - Type + + {translate('tasks.projectDetailDrawer.type', 'Type')} + {projectRowItem.itemType === 'PULL_REQUEST' - ? 'Pull request' + ? translate('tasks.projectDetailDrawer.pullRequest', 'Pull request') : projectRowItem.itemType === 'ISSUE' - ? 'Issue' + ? translate('tasks.projectDetailDrawer.issue', 'Issue') : projectRowItem.itemType === 'DRAFT_ISSUE' - ? 'Draft issue' - : 'Project item'} + ? translate('tasks.projectDetailDrawer.draftIssue', 'Draft issue') + : translate('tasks.projectDetailDrawer.projectItem', 'Project item')} - Status + + {translate('tasks.projectDetailDrawer.status', 'Status')} + {projectRowStatusLabel(projectRowItem)} @@ -178,21 +197,32 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati {SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowItem.itemType === 'ISSUE' ? ( - Issue type + + {translate('tasks.projectDetailDrawer.issueType', 'Issue type')} + - {projectRowItem.content.issueType?.name ?? 'No type'} + {projectRowItem.content.issueType?.name ?? + translate('tasks.projectDetailDrawer.noType', 'No type')} {projectIssueTypesLoading ? ( - Loading issue types... + + {translate( + 'tasks.projectDetailDrawer.loadingIssueTypes', + 'Loading issue types...' + )} + ) : projectIssueTypesError ? ( {projectIssueTypesError} ) : projectIssueTypes.length === 0 ? ( - No issue types configured for this repository. + {translate( + 'tasks.projectDetailDrawer.noIssueTypes', + 'No issue types configured for this repository.' + )} ) : ( @@ -226,7 +256,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati disabled={projectMutating} onPress={() => void mutateProjectRowIssueType(projectRowItem, null)} > - Clear type + + {translate('tasks.projectDetailDrawer.clearType', 'Clear type')} + ) : null} @@ -251,11 +283,16 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati } > - Create Workspace + + {translate('tasks.projectDetailDrawer.createWorkspace', 'Create Workspace')} + ) : ( - Workspaces can only be created from GitHub issues and pull requests. + {translate( + 'tasks.projectDetailDrawer.workspaceCreationRequirement', + 'Workspaces can only be created from GitHub issues and pull requests.' + )} )} @@ -273,7 +310,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati }} > - Open in GitHub + + {translate('tasks.projectDetailDrawer.openInGitHub', 'Open in GitHub')} + {copiedLinkKey === `github-project:${projectRowItem.id}` - ? 'Copied' - : 'Copy GitHub link'} + ? translate('common.copied', 'Copied') + : translate('tasks.projectDetailDrawer.copyGitHubLink', 'Copy GitHub link')} @@ -327,7 +366,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati )} - {projectRowItem.content.state === 'CLOSED' ? 'Reopen item' : 'Close item'} + {projectRowItem.content.state === 'CLOSED' + ? translate('tasks.projectDetailDrawer.reopenItem', 'Reopen item') + : translate('tasks.projectDetailDrawer.closeItem', 'Close item')} @@ -343,11 +384,16 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati onPress={() => setMergeMethodProjectRow(projectRowItem)} > - Merge pull request + + {translate('tasks.projectDetailDrawer.mergePullRequest', 'Merge pull request')} + {!projectRowHostedRepo ? ( - Merge requires this repository in Orca. + {translate( + 'tasks.projectDetailDrawer.mergeRepositoryRequirement', + 'Merge requires this repository in Orca.' + )} ) : null} diff --git a/mobile/src/tasks/mobile-tasks-project-field-editors.tsx b/mobile/src/tasks/mobile-tasks-project-field-editors.tsx index fc12961c2a5..a653e8c52ed 100644 --- a/mobile/src/tasks/mobile-tasks-project-field-editors.tsx +++ b/mobile/src/tasks/mobile-tasks-project-field-editors.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { SHOW_MOBILE_PROJECT_METADATA_EDITORS, editableProjectFields, @@ -23,15 +24,25 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati return SHOW_MOBILE_PROJECT_METADATA_EDITORS && editableProjectFields(githubProjectTable).length > 0 ? ( - Project fields + + {translate('tasks.projectFieldEditors.projectFields', 'Project fields')} + {editableProjectFields(githubProjectTable).map((field) => { const currentLabel = projectFieldValueLabel(projectRowItem, field) + const currentValue = projectRowItem.fieldValuesByFieldId?.[field.id] + const isEmpty = + !currentValue || + (currentValue.kind === 'text' && !currentValue.text) || + (currentValue.kind === 'labels' && currentValue.labels.length === 0) || + (currentValue.kind === 'users' && currentValue.users.length === 0) const draftValue = projectFieldDrafts[field.id] ?? '' const saveTextField = (): void => { if (field.dataType === 'NUMBER') { const number = Number(draftValue) if (!Number.isFinite(number)) { - setProjectRowDetailError('Enter a valid number.') + setProjectRowDetailError( + translate('tasks.projectFieldEditors.invalidNumber', 'Enter a valid number.') + ) return } void mutateProjectRowField(projectRowItem, field, { @@ -43,7 +54,9 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati if (field.dataType === 'DATE') { const date = draftValue.trim() if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) { - setProjectRowDetailError('Enter a date as YYYY-MM-DD.') + setProjectRowDetailError( + translate('tasks.projectFieldEditors.invalidDate', 'Enter a date as YYYY-MM-DD.') + ) return } void mutateProjectRowField(projectRowItem, field, { kind: 'date', date }) @@ -92,7 +105,12 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati ) : field.dataType === 'ITERATION' && field.kind === 'iteration' ? ( {field.iterations.length === 0 ? ( - No iterations available. + + {translate( + 'tasks.projectFieldEditors.noIterations', + 'No iterations available.' + )} + ) : ( field.iterations.map((iteration) => { const fieldValue = projectRowItem.fieldValuesByFieldId?.[field.id] @@ -114,8 +132,23 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati {iteration.title} - {iteration.completed ? 'Completed' : 'Current & upcoming'} ·{' '} - {iteration.startDate} · {iteration.duration}d + {iteration.completed + ? translate( + 'tasks.projectFieldEditors.completedIteration', + 'Completed · {{startDate}} · {{duration}}d', + { + startDate: iteration.startDate, + duration: iteration.duration + } + ) + : translate( + 'tasks.projectFieldEditors.upcomingIteration', + 'Current & upcoming · {{startDate}} · {{duration}}d', + { + startDate: iteration.startDate, + duration: iteration.duration + } + )} {selected ? : null} @@ -137,10 +170,10 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati } placeholder={ field.dataType === 'DATE' - ? 'YYYY-MM-DD' + ? translate('tasks.projectFieldEditors.datePlaceholder', 'YYYY-MM-DD') : field.dataType === 'NUMBER' - ? 'Number' - : 'Text' + ? translate('tasks.projectFieldEditors.numberPlaceholder', 'Number') + : translate('tasks.projectFieldEditors.textPlaceholder', 'Text') } placeholderTextColor={colors.textMuted} keyboardType={field.dataType === 'NUMBER' ? 'numeric' : 'default'} @@ -151,16 +184,20 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati disabled={projectMutating} onPress={saveTextField} > - Save field + + {translate('tasks.projectFieldEditors.saveField', 'Save field')} + )} void mutateProjectRowField(projectRowItem, field, null)} > - Clear field + + {translate('tasks.projectFieldEditors.clearField', 'Clear field')} + ) diff --git a/mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx b/mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx index d0965284bc1..82e1d92f5a7 100644 --- a/mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx +++ b/mobile/src/tasks/mobile-tasks-project-metadata-editors.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { SHOW_MOBILE_PROJECT_METADATA_EDITORS, projectRowType @@ -31,23 +32,29 @@ export function renderMobileTasksProjectLabelsEditor(model: ConnectionPresentati return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? ( - Labels + + {translate('tasks.projectMetadataEditors.labels', 'Labels')} + {(projectRowDetail?.provider === 'github' ? projectRowDetail.labels : projectRowItem.content.labels.map((label) => label.name) - ).length || 'None'} + ).length || translate('tasks.projectMetadataEditors.none', 'None')} {projectLabelsLoading ? ( - Loading labels... + + {translate('tasks.projectMetadataEditors.loadingLabels', 'Loading labels...')} + ) : projectLabelsError ? ( {projectLabelsError} ) : projectAvailableLabels.length === 0 ? ( - No labels in this repository. + + {translate('tasks.projectMetadataEditors.noLabels', 'No labels in this repository.')} + ) : ( {[ @@ -104,23 +111,32 @@ export function renderMobileTasksProjectAssigneesEditor(model: ConnectionPresent return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? ( - Assignees + + {translate('tasks.projectMetadataEditors.assignees', 'Assignees')} + {(projectRowDetail?.provider === 'github' ? projectRowDetail.assignees : projectRowItem.content.assignees.map((assignee) => assignee.login) - ).length || 'None'} + ).length || translate('tasks.projectMetadataEditors.none', 'None')} {projectAssignableUsersLoading ? ( - Loading assignees... + + {translate('tasks.projectMetadataEditors.loadingAssignees', 'Loading assignees...')} + ) : projectAssignableUsersError ? ( {projectAssignableUsersError} ) : projectAssignableUsers.length === 0 ? ( - No assignable users found for this repository. + + {translate( + 'tasks.projectMetadataEditors.noAssignableUsers', + 'No assignable users found for this repository.' + )} + ) : ( {[ @@ -185,12 +201,14 @@ export function renderMobileTasksProjectIssueMetadata(model: ConnectionPresentat return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? ( <> - Title + + {translate('tasks.projectMetadataEditors.title', 'Title')} + - Save title + + {translate('tasks.projectMetadataEditors.saveTitle', 'Save title')} + - Description + + {translate('tasks.projectMetadataEditors.description', 'Description')} + - Save description + + {translate('tasks.projectMetadataEditors.saveDescription', 'Save description')} + - + ) : ( <> - Title + + {translate('tasks.projectMetadataEditors.title', 'Title')} + {projectRowItem.content.title} - Description - + + {translate('tasks.projectMetadataEditors.description', 'Description')} + + ) diff --git a/mobile/src/tasks/mobile-tasks-project-review-panels.tsx b/mobile/src/tasks/mobile-tasks-project-review-panels.tsx index 8e1f61d323d..dc0b8ba2b73 100644 --- a/mobile/src/tasks/mobile-tasks-project-review-panels.tsx +++ b/mobile/src/tasks/mobile-tasks-project-review-panels.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { isBrokenCheck } from '../../../src/shared/pr-checks-fix-prompt' import { SHOW_MOBILE_PROJECT_REVIEW_PANELS, @@ -55,11 +56,15 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati <> - Reviewers + + {translate('tasks.projectReviewPanels.reviewers', 'Reviewers')} + {getGitHubReviewSummary(projectRowDetail)} {getGitHubReviewerRows(projectRowDetail).length === 0 ? ( - No reviewers requested. + + {translate('tasks.projectReviewPanels.noReviewers', 'No reviewers requested.')} + ) : ( getGitHubReviewerRows(projectRowDetail).map((reviewer) => ( @@ -85,12 +90,16 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati {projectAssignableUsersLoading ? ( - Loading reviewers... + + {translate('tasks.projectReviewPanels.loadingReviewers', 'Loading reviewers...')} + ) : projectAssignableUsersError ? ( {projectAssignableUsersError} ) : projectReviewerCandidates.length === 0 ? ( - No reviewer suggestions found. + + {translate('tasks.projectReviewPanels.noSuggestions', 'No reviewer suggestions found.')} + ) : ( {projectReviewerCandidates.map((user) => { @@ -115,7 +124,7 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati style={styles.input} value={projectReviewersDraft} onChangeText={setProjectReviewersDraft} - placeholder="Request reviewers" + placeholder={translate('tasks.projectReviewPanels.requestReviewers', 'Request reviewers')} placeholderTextColor={colors.textMuted} autoCapitalize="none" /> @@ -124,40 +133,50 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati disabled={projectMutating || splitReviewerList(projectReviewersDraft).length === 0} onPress={() => void requestProjectGitHubReviewers(projectRowItem)} > - Request review + + {translate('tasks.projectReviewPanels.requestReview', 'Request review')} + {projectRowType(projectRowItem) === 'pr' ? ( - Checks + + {translate('tasks.projectReviewPanels.checks', 'Checks')} + void refreshProjectGitHubChecks(projectRowItem)} > - Refresh + {translate('common.refresh', 'Refresh')} void rerunProjectGitHubChecks(projectRowItem, true)} > - Rerun failed + + {translate('tasks.projectReviewPanels.rerunFailed', 'Rerun failed')} + void rerunProjectGitHubChecks(projectRowItem, false)} > - Rerun all + + {translate('tasks.projectReviewPanels.rerunAll', 'Rerun all')} + {projectRowDetail.checks.length === 0 ? ( - No checks found. + + {translate('tasks.projectReviewPanels.noChecks', 'No checks found.')} + ) : ( projectRowDetail.checks.map((check) => ( 0 ? ( - Changed files + + {translate('tasks.projectReviewPanels.changedFiles', 'Changed files')} + {projectRowDetail.files.map((file) => ( - {expandedPrFilePath === file.path ? 'Hide' : 'View'} + {expandedPrFilePath === file.path + ? translate('tasks.projectReviewPanels.hideFile', 'Hide') + : translate('tasks.projectReviewPanels.viewFile', 'View')} void toggleProjectGitHubFileViewed(projectRowItem, file)} > - {file.viewerViewedState === 'VIEWED' ? 'Mark unviewed' : 'Mark viewed'} + {file.viewerViewedState === 'VIEWED' + ? translate('tasks.projectReviewPanels.markUnviewed', 'Mark unviewed') + : translate('tasks.projectReviewPanels.markViewed', 'Mark viewed')} {expandedPrFilePath === file.path ? ( @@ -215,7 +240,9 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati ) : prFileContents[file.path]?.originalIsBinary || prFileContents[file.path]?.modifiedIsBinary ? ( - Binary file. + + {translate('tasks.projectReviewPanels.binaryFile', 'Binary file.')} + ) : prFileContents[file.path] ? ( ) : ( - File contents unavailable. + + {translate( + 'tasks.projectReviewPanels.fileUnavailable', + 'File contents unavailable.' + )} + )} ) : null} diff --git a/mobile/src/tasks/mobile-tasks-provider-controls.tsx b/mobile/src/tasks/mobile-tasks-provider-controls.tsx index a5a8f0e0d8a..b0e4fdf7fce 100644 --- a/mobile/src/tasks/mobile-tasks-provider-controls.tsx +++ b/mobile/src/tasks/mobile-tasks-provider-controls.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { ScrollView, Pressable, @@ -92,7 +93,9 @@ export function renderMobileTasksProviderControls(model: ConnectionPresentationM }} > - {gitlabView === 'project' ? 'Project MRs' : 'My Todos'} + {gitlabView === 'project' + ? translate('tasks.providerControls.projectMergeRequests', 'Project MRs') + : translate('tasks.providerControls.myTodos', 'My Todos')} {gitlabView === 'project' && ( @@ -128,7 +131,9 @@ export function renderMobileTasksProviderControls(model: ConnectionPresentationM }} > - Sort: {sortLabel} + + {translate('tasks.providerControls.sort', 'Sort: {{sortLabel}}', { sortLabel })} + ) : null} diff --git a/mobile/src/tasks/mobile-tasks-provider-item-list.tsx b/mobile/src/tasks/mobile-tasks-provider-item-list.tsx index a1c4727a72c..7be7ccff4ef 100644 --- a/mobile/src/tasks/mobile-tasks-provider-item-list.tsx +++ b/mobile/src/tasks/mobile-tasks-provider-item-list.tsx @@ -1,4 +1,5 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation' +import { translate } from '../i18n/mobile-i18n' import { View, ActivityIndicator, @@ -83,7 +84,7 @@ export function renderMobileTasksProviderItemList( {githubCountedTotalPages === null - ? `Page ${githubCurrentPage + 1}` - : `Page ${githubCurrentPage + 1} of ${githubTotalPages}`} + ? translate('tasks.providerItemList.page', 'Page {{page}}', { + page: githubCurrentPage + 1 + }) + : translate('tasks.providerItemList.pageOfTotal', 'Page {{page}} of {{total}}', { + page: githubCurrentPage + 1, + total: githubTotalPages + })} = githubTotalPages - 1) || @@ -205,7 +217,9 @@ export function renderMobileTasksProviderItemList( {branchSummary.head} - into {branchSummary.base} + {translate('tasks.providerItemList.intoBranch', 'into {{base}}', { + base: branchSummary.base + })} ) : null} diff --git a/mobile/src/tasks/mobile-tasks-provider-pickers.tsx b/mobile/src/tasks/mobile-tasks-provider-pickers.tsx index e1f95b9d957..bc5aaa2ed5b 100644 --- a/mobile/src/tasks/mobile-tasks-provider-pickers.tsx +++ b/mobile/src/tasks/mobile-tasks-provider-pickers.tsx @@ -23,6 +23,7 @@ import { } from './mobile-tasks-legacy-foundation' import { styles } from './mobile-tasks-legacy-styles' import { normalizeJiraFilter } from './mobile-jira-issue-filters' +import { translate as t } from '../i18n/mobile-i18n' export function renderMobileTasksProviderPicker(model: ConnectionPresentationModel) { const { @@ -47,7 +48,7 @@ export function renderMobileTasksProviderPicker(model: ConnectionPresentationMod return ( { @@ -111,8 +112,10 @@ export function renderMobileTasksRepoPicker(model: ConnectionPresentationModel) return ( setShowRepoPicker(false)}> - Repositories - Choose which repositories to query. + {t('tasks.providerPickers.repos', 'Repositories')} + + {t('tasks.providerPickers.repoDescription', 'Choose which repositories to query.')} + @@ -125,7 +128,9 @@ export function renderMobileTasksRepoPicker(model: ConnectionPresentationModel) }} > - All repositories + + {t('tasks.providerPickers.allRepositories', 'All repositories')} + {repositoryCount(hostedRepos.length)} {effectiveRepoIds.size === 0 ? : null} @@ -172,16 +177,23 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen onClose={() => setShowGitHubIssueSourcePicker(false)} > - GitHub Issue Sources + + {t('tasks.providerPickers.issueSources', 'GitHub Issue Sources')} + - Choose whether each repository queries and creates work from upstream or origin. + {t( + 'tasks.providerPickers.issueSourcesDescription', + 'Choose whether each repository queries and creates work from upstream or origin.' + )} {githubIssueSourceRows.length === 0 ? ( - No alternate issue sources available. + + {t('tasks.providerPickers.noIssueSources', 'No alternate issue sources available.')} + ) : ( githubIssueSourceRows.map(({ repo, sources }, index) => { @@ -198,10 +210,11 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen {repo.displayName} - Querying{' '} - {issueSourceSlug( - selectedPreference === 'origin' ? sources.prs : sources.upstreamCandidate - )} + {t('tasks.providerPickers.queryingSource', 'Querying {{source}}', { + source: issueSourceSlug( + selectedPreference === 'origin' ? sources.prs : sources.upstreamCandidate + ) + })} @@ -227,7 +240,9 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen selected && styles.issueSourceSegmentTextActive ]} > - {preference === 'upstream' ? 'Upstream' : 'Origin'} + {preference === 'upstream' + ? t('tasks.providerPickers.upstream', 'Upstream') + : t('tasks.providerPickers.origin', 'Origin')} {slug} @@ -264,7 +279,7 @@ export function renderMobileTasksGitHubViewPicker(model: ConnectionPresentationM return ( { @@ -311,7 +326,11 @@ export function renderMobileTasksGitHubPresetPicker(model: ConnectionPresentatio return ( { @@ -349,8 +368,10 @@ export function renderMobileTasksPagePicker(model: ConnectionPresentationModel) onClose={() => setShowGitHubPagePicker(false)} > - GitHub Pages - Jump to a loaded or available result page. + {t('tasks.providerPickers.pages', 'GitHub Pages')} + + {t('tasks.providerPickers.pageHint', 'Jump to a loaded or available result page.')} + {githubPagePickerPages.map((index) => { @@ -367,9 +388,15 @@ export function renderMobileTasksPagePicker(model: ConnectionPresentationModel) }} > - Page {index + 1} + + {t('tasks.providerPickers.pageNumber', 'Page {{page}}', { + page: index + 1 + })} + - {loaded ? 'Loaded' : 'Loads older results'} + {loaded + ? t('tasks.providerPickers.pageLoaded', 'Loaded') + : t('tasks.providerPickers.pageNotLoaded', 'Loads older results')} {selected ? : null} diff --git a/mobile/src/tasks/mobile-tasks-reviewer-linear.ts b/mobile/src/tasks/mobile-tasks-reviewer-linear.ts index 9ee16fcf693..a897d530996 100644 --- a/mobile/src/tasks/mobile-tasks-reviewer-linear.ts +++ b/mobile/src/tasks/mobile-tasks-reviewer-linear.ts @@ -1,6 +1,7 @@ import { type GitHubOwnerRepo, colors } from './mobile-tasks-dependencies' import { getLinearPriorityLabel, getLinearPriorityRank } from './mobile-tasks-hosted-review' import { formatUpdatedAt, taskTime } from './mobile-tasks-item-mapping' +import { translate } from '../i18n/mobile-i18n' import type { LinearIssueSection } from './mobile-tasks-options' import type { LinearDisplayProperty, @@ -80,7 +81,7 @@ export function hasGitHubIssueSourceChoice(sources: GitHubRepoSources | undefine } export function issueSourceSlug(source: GitHubOwnerRepo | null | undefined): string { - return source ? `${source.owner}/${source.repo}` : 'Unknown' + return source ? `${source.owner}/${source.repo}` : translate('common.unknown', 'Unknown') } export function sortLinearIssues( @@ -117,21 +118,33 @@ export function getLinearIssueGroup( if (groupBy === 'assignee') { return { key: `assignee:${issue.assignee?.id ?? issue.assignee?.displayName ?? 'unassigned'}`, - label: issue.assignee?.displayName ?? 'Unassigned', + get label() { + return ( + issue.assignee?.displayName ?? translate('tasks.reviewerLinear.unassigned', 'Unassigned') + ) + }, color: colors.accentBlue } } if (groupBy === 'priority') { return { key: `priority:${issue.priority}`, - label: getLinearPriorityLabel(issue.priority), + get label() { + return getLinearPriorityLabel(issue.priority) + }, color: issue.priority === 1 ? colors.statusRed : colors.accentBlue } } if (groupBy === 'team') { return { key: `team:${issue.team.id}`, label: issue.team.name, color: issue.state.color } } - return { key: 'all', label: 'Issues', color: colors.accentBlue } + return { + key: 'all', + get label() { + return translate('tasks.reviewerLinear.issues', 'Issues') + }, + color: colors.accentBlue + } } export function groupLinearIssues( @@ -154,7 +167,16 @@ function groupOrderedLinearIssues( groupBy: LinearGroupBy ): LinearIssueSection[] { if (groupBy === 'none') { - return [{ key: 'all', label: 'Issues', color: colors.accentBlue, issues: sorted }] + return [ + { + key: 'all', + get label() { + return translate('tasks.reviewerLinear.issues', 'Issues') + }, + color: colors.accentBlue, + issues: sorted + } + ] } const sections = new Map< string, @@ -166,7 +188,13 @@ function groupOrderedLinearIssues( if (section) { section.issues.push(issue) } else { - sections.set(group.key, { ...group, issues: [issue] }) + sections.set(group.key, { + ...group, + get label() { + return group.label + }, + issues: [issue] + }) } } return [...sections.values()] diff --git a/mobile/src/tasks/mobile-tasks-screen-chrome.tsx b/mobile/src/tasks/mobile-tasks-screen-chrome.tsx index 00b3f30caba..a952cc86c1c 100644 --- a/mobile/src/tasks/mobile-tasks-screen-chrome.tsx +++ b/mobile/src/tasks/mobile-tasks-screen-chrome.tsx @@ -13,13 +13,16 @@ import { MobileTasksHostSubtitle } from './mobile-tasks-host-subtitle' import { styles } from './mobile-tasks-legacy-styles' import { renderMobileTasksProviderControls } from './mobile-tasks-provider-controls' import { renderMobileTasksSearchControl } from './mobile-tasks-search-control' +import { translate } from '../i18n/mobile-i18n' -const REFRESH_LABELS = { - github: 'Refresh GitHub work', - gitlab: 'Refresh GitLab work items', - linear: 'Refresh Linear', - jira: 'Refresh Jira issues' -} as const +function refreshLabels() { + return { + github: translate('tasks.screenChrome.refreshGitHub', 'Refresh GitHub work'), + gitlab: translate('tasks.screenChrome.refreshGitLab', 'Refresh GitLab work items'), + linear: translate('tasks.screenChrome.refreshLinear', 'Refresh Linear'), + jira: translate('tasks.screenChrome.refreshJira', 'Refresh Jira issues') + } +} export function renderMobileTasksChrome(model: ConnectionPresentationModel) { const { setTaskCopyFeedbackRootRef } = model @@ -65,14 +68,14 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) { onPress={() => router.back()} hitSlop={8} accessibilityRole="button" - accessibilityLabel="Back" + accessibilityLabel={translate('common.back', 'Back')} > - Tasks + {translate('tasks.screenChrome.title', 'Tasks')} @@ -81,7 +84,7 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) { disabled={!taskUiReady || loading || refreshing || githubProjectLoading} hitSlop={8} accessibilityRole="button" - accessibilityLabel={REFRESH_LABELS[provider]} + accessibilityLabel={refreshLabels()[provider]} onPress={() => { if (!taskUiReady) { return @@ -103,10 +106,10 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) { accessibilityRole="button" accessibilityLabel={ provider === 'github' - ? 'New GitHub issue' + ? translate('tasks.screenChrome.newGitHubIssue', 'New GitHub issue') : linearConnected - ? 'New Linear issue' - : 'Connect Linear' + ? translate('tasks.screenChrome.newLinearIssue', 'New Linear issue') + : translate('tasks.screenChrome.connectLinear', 'Connect Linear') } onPress={() => { if (!taskUiReady) { diff --git a/mobile/src/tasks/mobile-tasks-search-control.tsx b/mobile/src/tasks/mobile-tasks-search-control.tsx index 1bd0d57638c..a88f1d8d595 100644 --- a/mobile/src/tasks/mobile-tasks-search-control.tsx +++ b/mobile/src/tasks/mobile-tasks-search-control.tsx @@ -2,6 +2,7 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection- import { View, MobileSearchField } from './mobile-tasks-dependencies' import { styles } from './mobile-tasks-legacy-styles' import { getTaskPresetQuery, scopeGitHubTaskSearch } from './mobile-tasks-legacy-foundation' +import { translate } from '../i18n/mobile-i18n' export function renderMobileTasksSearchControl(model: ConnectionPresentationModel) { const { @@ -33,11 +34,20 @@ export function renderMobileTasksSearchControl(model: ConnectionPresentationMode onChangeText={isGithubProjectSearch ? setGithubProjectSearch : setQuery} placeholder={ isGithubProjectSearch - ? 'Search project view...' + ? translate('tasks.searchControl.projectPlaceholder', 'Search project view...') : provider === 'jira' ? // Jira accepts raw JQL, matching desktop. - 'Jira JQL, e.g. project = ABC AND statusCategory != Done' - : `Search ${providerLabel} tasks...` + translate( + 'tasks.searchControl.jiraPlaceholder', + 'Jira JQL, e.g. project = ABC AND statusCategory != Done' + ) + : translate( + 'tasks.searchControl.providerPlaceholder', + 'Search {{provider}} tasks...', + { + provider: providerLabel + } + ) } // Preset text is not an override; Project’s explicit empty filter must not leave Clear visible forever. showClear={ diff --git a/mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx b/mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx index 522110f2609..94b66de7295 100644 --- a/mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx +++ b/mobile/src/tasks/mobile-tasks-workspace-create-drawer.tsx @@ -21,6 +21,7 @@ import { workspaceAgentIconId } from './mobile-tasks-legacy-foundation' import { styles } from './mobile-tasks-legacy-styles' +import { translate } from '../i18n/mobile-i18n' export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresentationModel) { const { @@ -60,7 +61,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta {workspaceCreateDraft ? ( - Create Workspace + + {translate('tasks.workspaceCreateDrawer.title', 'Create Workspace')} + {workspaceCreateDraft.item.title} @@ -68,7 +71,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta - Repository + + {translate('tasks.workspaceCreateDrawer.repository', 'Repository')} + - {workspaceCreateTargetRepo?.displayName ?? 'Select a repository'} + {workspaceCreateTargetRepo?.displayName ?? + translate( + 'tasks.workspaceCreateDrawer.selectRepository', + 'Select a repository' + )} {workspaceCreateCanPickRepo ? ( @@ -101,7 +110,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta {workspaceCreateTargetConnectionId ? ( - SSH Connection + + {translate('tasks.workspaceCreateDrawer.sshConnection', 'SSH Connection')} + - {workspaceCreateTargetRepo?.displayName ?? 'Remote repository'} + {workspaceCreateTargetRepo?.displayName ?? + translate( + 'tasks.workspaceCreateDrawer.remoteRepository', + 'Remote repository' + )} {workspaceSshStatusLabel(workspaceCreateSshStatus)} @@ -134,7 +149,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta onPress={() => void connectWorkspaceSshRepo()} > - {workspaceCreateSshConnectInProgress ? 'Connecting...' : 'Connect'} + {workspaceCreateSshConnectInProgress + ? translate('tasks.workspaceCreateDrawer.connecting', 'Connecting...') + : translate('tasks.workspaceCreateDrawer.connect', 'Connect')} )} @@ -148,7 +165,10 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta - Workspace Name [Optional] + {translate('tasks.workspaceCreateDrawer.workspaceName', 'Workspace Name')}{' '} + + {translate('tasks.workspaceCreateDrawer.optional', '[Optional]')} + - Agent + + {translate('tasks.workspaceCreateDrawer.agent', 'Agent')} + {workspaceCreateRequiresSshConnection - ? 'Connect repository first' + ? translate( + 'tasks.workspaceCreateDrawer.connectFirst', + 'Connect repository first' + ) : workspaceAgentDetectionPending - ? 'Detecting agents...' + ? translate( + 'tasks.workspaceCreateDrawer.detectingAgents', + 'Detecting agents...' + ) : workspaceAgentLabel(resolvedWorkspaceAgent)} @@ -185,7 +213,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta style={styles.workspaceAdvancedToggle} onPress={() => setShowWorkspaceAdvanced((current) => !current)} > - Advanced + + {translate('tasks.workspaceCreateDrawer.advanced', 'Advanced')} + {showWorkspaceAdvanced ? ( ) : ( @@ -195,7 +225,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta {showWorkspaceAdvanced ? ( - Start from + + {translate('tasks.workspaceCreateDrawer.startFrom', 'Start from')} + { @@ -205,13 +237,16 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta > - {workspaceBaseBranch?.refName ?? 'Default branch'} + {workspaceBaseBranch?.refName ?? + translate('tasks.workspaceCreateDrawer.defaultBranch', 'Default branch')} {workspaceBaseBranch ? ( - Create from {workspaceBaseBranch.refName} + {translate('tasks.workspaceCreateDrawer.createFrom', 'Create from {{branch}}', { + branch: workspaceBaseBranch.refName + })} ) : null} @@ -221,8 +256,14 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta {workspaceCreateTargetRepo ? null : ( {workspaceCreateDraft.item.provider === 'linear' - ? 'Add a Git repository before creating a Linear workspace.' - : 'Repository not found.'} + ? translate( + 'tasks.workspaceCreateDrawer.addRepository', + 'Add a Git repository before creating a Linear workspace.' + ) + : translate( + 'tasks.workspaceCreateDrawer.repositoryNotFound', + 'Repository not found.' + )} )} @@ -265,10 +306,16 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta ) : ( {workspaceAgentDetectionPending - ? 'Detecting agents...' + ? translate( + 'tasks.workspaceCreateDrawer.detectingAgents', + 'Detecting agents...' + ) : workspaceCreateRequiresSshConnection - ? 'Connect Repository' - : 'Create Workspace'} + ? translate( + 'tasks.workspaceCreateDrawer.connectRepository', + 'Connect Repository' + ) + : translate('tasks.workspaceCreateDrawer.title', 'Create Workspace')} )} @@ -292,7 +339,7 @@ export function renderMobileTasksWorkspaceCreateRepoPicker(model: ConnectionPres return ( { @@ -321,7 +368,7 @@ export function renderMobileTasksWorkspaceAgentPicker(model: ConnectionPresentat return ( { diff --git a/mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx b/mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx index 073f9fb5bed..5f989fd1b27 100644 --- a/mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx +++ b/mobile/src/tasks/mobile-tasks-workspace-option-pickers.tsx @@ -12,6 +12,7 @@ import { } from './mobile-tasks-dependencies' import { TASK_SECONDARY_DRAWER_Z_INDEX } from './mobile-tasks-legacy-foundation' import { styles } from './mobile-tasks-legacy-styles' +import { translate } from '../i18n/mobile-i18n' export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPresentationModel) { const { @@ -36,15 +37,25 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres > - Start From - Pick an existing branch or ref. + + {translate('tasks.workspaceOptionPickers.baseBranchTitle', 'Start From')} + + + {translate( + 'tasks.workspaceOptionPickers.baseBranchSubtitle', + 'Pick an existing branch or ref.' + )} + : null} - Default branch - Use this repository's configured base + + {translate('tasks.workspaceOptionPickers.defaultBranch', 'Default branch')} + + + {translate( + 'tasks.workspaceOptionPickers.defaultBranchSubtitle', + "Use this repository's configured base" + )} + {workspaceBaseBranchLoading ? ( @@ -70,7 +88,9 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres ) : workspaceBaseBranchError ? ( {workspaceBaseBranchError} ) : workspaceBaseBranchQuery.trim() && workspaceBaseBranchResults.length === 0 ? ( - No branches match. + + {translate('tasks.workspaceOptionPickers.noBranches', 'No branches match.')} + ) : null} {workspaceBaseBranchResults.map((branch) => ( @@ -92,7 +112,13 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres {branch.localBranchName !== branch.refName ? ( - Branch name: {branch.localBranchName} + {translate( + 'tasks.workspaceOptionPickers.branchName', + 'Branch name: {{name}}', + { + name: branch.localBranchName + } + )} ) : null} @@ -127,7 +153,9 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta > - Sparse Checkout + + {translate('tasks.workspaceOptionPickers.sparseCheckoutTitle', 'Sparse Checkout')} + - Full checkout - Use the whole repository + + {translate('tasks.workspaceOptionPickers.fullCheckout', 'Full checkout')} + + + {translate( + 'tasks.workspaceOptionPickers.fullCheckoutSubtitle', + 'Use the whole repository' + )} + {workspaceSparsePresets.map((preset) => ( @@ -175,7 +210,13 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta startEditWorkspaceSparsePreset(preset)} > @@ -194,7 +235,9 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta disabled={!workspaceSparsePresetsLoaded || workspaceSparsePresetsLoading} onPress={startNewWorkspaceSparsePreset} > - New preset + + {translate('tasks.workspaceOptionPickers.newPreset', 'New preset')} + diff --git a/mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx b/mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx index 96121fc198b..cb63a298730 100644 --- a/mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx +++ b/mobile/src/tasks/mobile-tasks-workspace-trust-drawers.tsx @@ -12,6 +12,7 @@ import { } from './mobile-tasks-dependencies' import { TASK_SECONDARY_DRAWER_Z_INDEX, setupSourceLabel } from './mobile-tasks-legacy-foundation' import { styles } from './mobile-tasks-legacy-styles' +import { translate } from '../i18n/mobile-i18n' export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresentationModel) { const { @@ -25,6 +26,7 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta workspaceSparseDraftParsed, workspaceSparseSaving } = model + const count = workspaceSparseDraftParsed?.directories.length ?? 0 return ( - {workspaceSparseDraft.mode === 'new' ? 'New Sparse Preset' : 'Edit Sparse Preset'} + {workspaceSparseDraft.mode === 'new' + ? translate('tasks.workspaceTrustDrawers.newSparsePreset', 'New Sparse Preset') + : translate('tasks.workspaceTrustDrawers.editSparsePreset', 'Edit Sparse Preset')} - Name + + {translate('tasks.workspaceTrustDrawers.nameLabel', 'Name')} + setWorkspaceSparseDraft({ ...workspaceSparseDraft, name })} - placeholder="Renderer UI" + placeholder={translate( + 'tasks.workspaceTrustDrawers.namePlaceholder', + 'Renderer UI' + )} placeholderTextColor={colors.textMuted} autoCapitalize="none" autoCorrect={false} @@ -57,7 +66,9 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta /> - Directories + + {translate('tasks.workspaceTrustDrawers.directoriesLabel', 'Directories')} + {workspaceSparseDraftError ?? - (workspaceSparseDraftParsed?.directories.length === 1 - ? '1 directory' - : `${workspaceSparseDraftParsed?.directories.length ?? 0} directories`)} + (count === 1 + ? translate( + 'tasks.workspaceTrustDrawers.directories_one', + '{{count}} directory', + { count } + ) + : translate( + 'tasks.workspaceTrustDrawers.directories_other', + '{{count}} directories', + { count } + ))} @@ -85,7 +104,7 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta disabled={workspaceSparseSaving} onPress={() => setWorkspaceSparseDraft(null)} > - Cancel + {translate('common.cancel', 'Cancel')} ) : null} - Save + {translate('common.save', 'Save')} @@ -118,9 +137,17 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM {setupPrompt ? ( - Run Setup Script? + + {translate('tasks.workspaceTrustDrawers.setupTitle', 'Run Setup Script?')} + - {setupPrompt.repoName} requires a setup choice before creating this workspace. + {translate( + 'tasks.workspaceTrustDrawers.setupSubtitle', + '{{name}} requires a setup choice before creating this workspace.', + { + name: setupPrompt.repoName + } + )} @@ -151,7 +178,12 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM > - {creatingKey === setupPrompt.item.key ? 'Creating...' : 'Run setup and create'} + {creatingKey === setupPrompt.item.key + ? translate('tasks.workspaceTrustDrawers.creating', 'Creating...') + : translate( + 'tasks.workspaceTrustDrawers.runSetupAndCreate', + 'Run setup and create' + )} @@ -173,7 +205,12 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM } > - Skip setup and create + + {translate( + 'tasks.workspaceTrustDrawers.skipSetupAndCreate', + 'Skip setup and create' + )} + @@ -203,19 +240,31 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati {orcaYamlTrustPrompt.previouslyApproved - ? `${orcaYamlTrustPrompt.repoName}'s setup script changed` - : `Run setup from ${orcaYamlTrustPrompt.repoName}?`} + ? translate( + 'tasks.workspaceTrustDrawers.setupChangedTitle', + "{{name}}'s setup script changed", + { name: orcaYamlTrustPrompt.repoName } + ) + : translate( + 'tasks.workspaceTrustDrawers.runSetupTitle', + 'Run setup from {{name}}?', + { name: orcaYamlTrustPrompt.repoName } + )} - This repository's orca.yaml runs on your machine before the workspace starts. Only run - it if you trust this repository. + {translate( + 'tasks.workspaceTrustDrawers.trustSubtitle', + "This repository's orca.yaml runs on your machine before the workspace starts. Only run it if you trust this repository." + )} - {orcaYamlTrustPrompt.previouslyApproved ? 'New setup script' : 'Setup script'} + {orcaYamlTrustPrompt.previouslyApproved + ? translate('tasks.workspaceTrustDrawers.newSetupScript', 'New setup script') + : translate('tasks.workspaceTrustDrawers.setupScript', 'Setup script')} {orcaYamlTrustPrompt.scriptContent} @@ -247,13 +296,22 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati orcaYamlTrustPrompt.contentHash ) } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to trust setup script.') + setError( + err instanceof Error + ? err.message + : translate( + 'tasks.workspaceTrustDrawers.trustFailed', + 'Failed to trust setup script.' + ) + ) } })() } > - Run hooks + + {translate('tasks.workspaceTrustDrawers.runHooks', 'Run hooks')} + - Always trust and run + + {translate('tasks.workspaceTrustDrawers.alwaysTrustAndRun', 'Always trust and run')} + - Don't run + + {translate('tasks.workspaceTrustDrawers.dontRun', "Don't run")} + diff --git a/mobile/src/tasks/sparse-preset-draft.ts b/mobile/src/tasks/sparse-preset-draft.ts index a70baded66b..111d39f48f1 100644 --- a/mobile/src/tasks/sparse-preset-draft.ts +++ b/mobile/src/tasks/sparse-preset-draft.ts @@ -1,3 +1,5 @@ +import { translate } from '../i18n/mobile-i18n' + const WINDOWS_DRIVE_PATH_PATTERN = /^[A-Za-z]:/ export type SparsePresetDirectoryParseResult = { @@ -40,7 +42,10 @@ export function parseSparsePresetDirectories(value: string): SparsePresetDirecto if (rawEntries.some(isAbsoluteSparseDirectoryPath)) { return { directories: [], - error: 'Use repo-relative directories, not root, absolute paths, or parent segments.' + error: translate( + 'tasks.sparsePresetDraft.repoRelativeDirectoriesRequired', + 'Use repo-relative directories, not root, absolute paths, or parent segments.' + ) } } @@ -49,14 +54,17 @@ export function parseSparsePresetDirectories(value: string): SparsePresetDirecto if (directories.length === 0) { return { directories, - error: 'Add at least one directory.' + error: translate('tasks.sparsePresetDraft.directoryRequired', 'Add at least one directory.') } } if (directories.some((entry) => entry === '.' || entry.split('/').includes('..'))) { return { directories: [], - error: 'Use repo-relative directories, not root, absolute paths, or parent segments.' + error: translate( + 'tasks.sparsePresetDraft.repoRelativeDirectoriesRequired', + 'Use repo-relative directories, not root, absolute paths, or parent segments.' + ) } } diff --git a/mobile/src/tasks/use-mobile-composer-source.ts b/mobile/src/tasks/use-mobile-composer-source.ts index eada3a05f2e..7ac5410b03c 100644 --- a/mobile/src/tasks/use-mobile-composer-source.ts +++ b/mobile/src/tasks/use-mobile-composer-source.ts @@ -31,6 +31,7 @@ import type { SmartNameSelection } from './mobile-composer-source-types' import { useMobileComposerName } from './use-mobile-composer-name' +import { getBaseResolveError, useForkPushWarning } from './composer-source-copy' export type UseMobileComposerSourceArgs = { client: RpcClient | null @@ -45,7 +46,7 @@ export function useMobileComposerSource(args: UseMobileComposerSourceArgs) { const [base, setBase] = useState({}) const [reuseEligibleBranch, setReuseEligibleBranch] = useState(null) const [reuseSelectedBranch, setReuseSelectedBranch] = useState(false) - const [forkPushWarning, setForkPushWarning] = useState(null) + const [forkPushWarning, setForkPushWarning] = useForkPushWarning() const [resolvingBase, setResolvingBase] = useState(false) const [branchCreateIntent, setBranchCreateIntent] = useState(false) @@ -78,11 +79,10 @@ export function useMobileComposerSource(args: UseMobileComposerSourceArgs) { setForkPushWarning(getForkPushWarning(result)) }) .catch((error: unknown) => { - if (resolveTokenRef.current !== token) { - return + if (resolveTokenRef.current === token) { + setBase({}) + onError?.(getBaseResolveError(error)) } - setBase({}) - onError?.(error instanceof Error ? error.message : 'Failed to resolve base branch.') }) .finally(() => { if (resolveTokenRef.current === token) { diff --git a/mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx b/mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx index c5c6bfc94ca..2b8fc1970bf 100644 --- a/mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx +++ b/mobile/src/tasks/use-mobile-tasks-detail-comment-renderers.tsx @@ -23,8 +23,10 @@ import { renderCommentReactions } from './mobile-tasks-legacy-foundation' import { styles } from './mobile-tasks-legacy-styles' +import { useMobileTranslation } from '../i18n/use-mobile-translation' export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsModel) { + const t = useMobileTranslation() const { actionItem, detailPayload, @@ -49,7 +51,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod style={[styles.input, styles.commentInput, styles.commentComposerInput]} value={args.value} onChangeText={args.onChangeText} - placeholder="Add a comment" + placeholder={t('tasks.detailCommentRenderers.commentPlaceholder', 'Add a comment')} placeholderTextColor={colors.textMuted} editable={!args.disabled} multiline @@ -59,7 +61,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod {hasText ? ( [ styles.commentComposerSend, pressed && !args.disabled && styles.commentComposerSendPressed, @@ -111,7 +113,9 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod onPress={() => void toggleGitHubReviewThread(actionItem, comment)} > - {comment.isResolved ? 'Reopen thread' : 'Resolve thread'} + {comment.isResolved + ? t('tasks.detailCommentRenderers.reopenThread', 'Reopen thread') + : t('tasks.detailCommentRenderers.resolveThread', 'Resolve thread')} ) : null} @@ -124,7 +128,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod [String(comment.id)]: next })) } - placeholder="Reply" + placeholder={t('tasks.detailCommentRenderers.reply', 'Reply')} placeholderTextColor={colors.textMuted} multiline textAlignVertical="top" @@ -134,7 +138,9 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod disabled={mutatingStatus || !(itemReplyDrafts[String(comment.id)] ?? '').trim()} onPress={() => void replyToGitHubComment(actionItem, comment)} > - Reply + + {t('tasks.detailCommentRenderers.reply', 'Reply')} + ) : null} @@ -151,6 +157,10 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod isResolvedDetailCommentGroup(group) && !expandedResolvedCommentGroups.has(id) if (isCollapsedResolved) { + const countLabel = + count === 1 + ? t('tasks.detailCommentRenderers.comments_one', '{{count}} comment', { count }) + : t('tasks.detailCommentRenderers.comments_other', '{{count}} comments', { count }) return ( - Resolved {group.kind === 'thread' ? 'thread' : 'comment'} by {commentAuthor(root)} + {group.kind === 'thread' + ? t( + 'tasks.detailCommentRenderers.resolvedThreadBy', + 'Resolved thread by {{author}}', + { + author: commentAuthor(root) + } + ) + : t( + 'tasks.detailCommentRenderers.resolvedCommentBy', + 'Resolved comment by {{author}}', + { + author: commentAuthor(root) + } + )} + + + {count > 1 ? countLabel : t('tasks.detailCommentRenderers.show', 'Show')} - {count > 1 ? `${count} comments` : 'Show'} ) } diff --git a/mobile/src/tasks/use-mobile-tasks-picker-projection.tsx b/mobile/src/tasks/use-mobile-tasks-picker-projection.tsx index d30edf3ad1a..4a1028bd0d1 100644 --- a/mobile/src/tasks/use-mobile-tasks-picker-projection.tsx +++ b/mobile/src/tasks/use-mobile-tasks-picker-projection.tsx @@ -2,7 +2,6 @@ import type { DetailCommentRenderersModel } from './use-mobile-tasks-detail-comm import { type PickerOption, View, useMemo, useMobileColorScheme } from './mobile-tasks-dependencies' import { type GitHubRepoSources, - type LinearTeam, PROJECT_VIEW_DEFAULT_SORT, PROVIDER_OPTIONS, type RepoSummary, @@ -18,8 +17,23 @@ import { import { styles } from './mobile-tasks-legacy-styles' import { PROVIDER_LABELS } from './mobile-task-view-options' import { jiraSiteLabel } from './jira-mobile-connection' +import type { Translate } from '../i18n/mobile-i18n' +import { useMobileTranslation } from '../i18n/use-mobile-translation' + +function sourceCountLabel(count: number, t: Translate): string { + return count === 1 + ? t('tasks.pickerProjection.sources_one', '{{count}} source', { count }) + : t('tasks.pickerProjection.sources_other', '{{count}} sources', { count }) +} + +function repoCountLabel(count: number, t: Translate): string { + return count === 1 + ? t('tasks.pickerProjection.repos_one', '{{count}} repo', { count }) + : t('tasks.pickerProjection.repos_other', '{{count}} repos', { count }) +} export function useMobileTasksPickerProjection(model: DetailCommentRenderersModel) { + const t = useMobileTranslation() const colorScheme = useMobileColorScheme() const { createRepoId, @@ -60,38 +74,39 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode label: team.name, subtitle: team.workspaceName })), - [hostedRepos, linearTeams, provider, repoHostLabels] + [hostedRepos, linearTeams, provider, repoHostLabels, t] ) - const selectedCreateTarget = + const selectedCreateRepo = provider === 'github' || provider === 'gitlab' ? (hostedRepos.find((repo) => repo.id === createRepoId) ?? hostedRepos[0] ?? null) - : (linearTeams.find((team) => team.id === createTeamId) ?? linearTeams[0] ?? null) - const selectedCreateTargetLabel = + : null + const selectedCreateTeam = provider === 'github' || provider === 'gitlab' - ? ((selectedCreateTarget as RepoSummary | null)?.displayName ?? 'Select target') - : ((selectedCreateTarget as LinearTeam | null)?.name ?? 'Select target') + ? null + : (linearTeams.find((team) => team.id === createTeamId) ?? linearTeams[0] ?? null) + const selectedCreateTarget = selectedCreateRepo ?? selectedCreateTeam + const selectedCreateTargetLabel = + selectedCreateRepo?.displayName ?? + selectedCreateTeam?.name ?? + t('tasks.pickerProjection.selectTarget', 'Select target') const providerLabel = PROVIDER_LABELS[provider] const showHeaderCreateTask = provider === 'linear' || (provider === 'github' && githubMode === 'items') const jiraSiteOptions = useMemo[]>( () => [ - { value: 'all', label: 'All sites' }, + { value: 'all', label: t('tasks.pickerProjection.allSites', 'All sites') }, ...jiraConnection.sites.map((site) => ({ value: site.id, label: jiraSiteLabel(site), subtitle: site.siteUrl })) ], - [jiraConnection.sites] + [jiraConnection.sites, t] ) const providerOptions = useMemo( () => PROVIDER_OPTIONS.filter((option) => visibleProviders.includes(option.value)), - [visibleProviders] + [t, visibleProviders] ) - const selectedCreateRepo = - provider === 'github' || provider === 'gitlab' - ? (selectedCreateTarget as RepoSummary | null) - : null const selectedCreateGitHubSources = provider === 'github' && selectedCreateRepo ? githubRepoSources[selectedCreateRepo.id] @@ -117,13 +132,13 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode ? githubIssueSourceRows[0]!.sources.prs : githubIssueSourceRows[0]!.sources.upstreamCandidate ) - : `${githubIssueSourceRows.length} sources` + : sourceCountLabel(githubIssueSourceRows.length, t) const repoPickerLabel = effectiveRepoIds.size === 0 || selectedHostedRepos.length === hostedRepos.length - ? 'All repos' + ? t('tasks.pickerProjection.allRepos', 'All repos') : selectedHostedRepos.length === 1 ? selectedHostedRepos[0]!.displayName - : `${selectedHostedRepos.length} repos` + : repoCountLabel(selectedHostedRepos.length, t) const repoPickerSelectedRepo = effectiveRepoIds.size > 0 && selectedHostedRepos.length === 1 ? selectedHostedRepos[0]! : null const workspaceRepoOptions = useMemo[]>( @@ -136,7 +151,7 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode ) })), - [repoHostLabels, workspaceRepos] + [repoHostLabels, t, workspaceRepos] ) const sortedItems = useMemo( () => sortMobileTaskItems(items, taskSort, reposById), @@ -162,8 +177,10 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode entries.push({ type: 'item', key: item.key, item }) } return entries - }, [colorScheme, reposById, sortedItems, taskSort]) - const sortLabel = SORT_OPTIONS.find((option) => option.value === taskSort)?.label ?? 'Updated' + }, [colorScheme, reposById, sortedItems, t, taskSort]) + const sortLabel = + SORT_OPTIONS.find((option) => option.value === taskSort)?.label ?? + t('tasks.pickerProjection.updatedSort', 'Updated') const githubProjectFields = githubProjectTable?.selectedView.fields ?? [] const githubProjectViewSort = githubProjectTable?.selectedView.sortByFields?.[0] ?? null const githubProjectSortField = githubProjectSortOverride @@ -172,35 +189,53 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode const githubProjectSortDirection = githubProjectSortOverride?.direction ?? githubProjectViewSort?.direction ?? null const githubProjectSortLabel = githubProjectSortField - ? `${githubProjectSortField.name} ${githubProjectSortDirection === 'DESC' ? 'desc' : 'asc'}` - : 'View order' + ? githubProjectSortDirection === 'DESC' + ? t('tasks.pickerProjection.fieldDescending', '{{field}} desc', { + field: githubProjectSortField.name + }) + : t('tasks.pickerProjection.fieldAscending', '{{field}} asc', { + field: githubProjectSortField.name + }) + : t('tasks.pickerProjection.viewOrder', 'View order') const githubProjectFieldsLabel = githubProjectAvailableSummaryFields.length > 0 - ? `${githubProjectSummaryFields.length}/${githubProjectAvailableSummaryFields.length} fields` - : 'Fields' + ? t('tasks.pickerProjection.selectedFields', '{{selected}}/{{total}} fields', { + selected: githubProjectSummaryFields.length, + total: githubProjectAvailableSummaryFields.length + }) + : t('tasks.pickerProjection.fields', 'Fields') const githubProjectSortOptions = useMemo[]>( () => [ { value: PROJECT_VIEW_DEFAULT_SORT, - label: 'View order', + label: t('tasks.pickerProjection.viewOrder', 'View order'), subtitle: githubProjectViewSort - ? `Uses ${githubProjectViewSort.field.name} ${githubProjectViewSort.direction.toLowerCase()}` - : 'Uses GitHub rank order' + ? githubProjectViewSort.direction === 'DESC' + ? t('tasks.pickerProjection.usesFieldDescending', 'Uses {{field}} desc', { + field: githubProjectViewSort.field.name + }) + : t('tasks.pickerProjection.usesFieldAscending', 'Uses {{field}} asc', { + field: githubProjectViewSort.field.name + }) + : t('tasks.pickerProjection.usesGitHubRankOrder', 'Uses GitHub rank order') }, ...githubProjectFields.map((field) => { const active = githubProjectSortOverride?.fieldId === field.id - const nextDirection = - !active || githubProjectSortOverride.direction === 'DESC' ? 'ascending' : 'descending' return { value: field.id, label: field.name, subtitle: active - ? `Currently ${githubProjectSortOverride.direction.toLowerCase()} · tap for ${nextDirection}` - : 'Sort ascending' + ? githubProjectSortOverride.direction === 'DESC' + ? t( + 'tasks.pickerProjection.currentlyDescending', + 'Currently desc · tap for ascending' + ) + : t('tasks.pickerProjection.currentlyAscending', 'Currently asc · tap for descending') + : t('tasks.pickerProjection.sortAscending', 'Sort ascending') } }) ], - [githubProjectFields, githubProjectSortOverride, githubProjectViewSort] + [githubProjectFields, githubProjectSortOverride, githubProjectViewSort, t] ) const githubProjectViewOptions = useMemo[]>( () => @@ -208,10 +243,12 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode value: view.id, label: view.name, subtitle: - view.layout === 'TABLE_LAYOUT' ? `View #${view.number}` : 'Unsupported layout on mobile', + view.layout === 'TABLE_LAYOUT' + ? t('tasks.pickerProjection.viewNumber', 'View #{{number}}', { number: view.number }) + : t('tasks.pickerProjection.unsupportedLayout', 'Unsupported layout on mobile'), disabled: view.layout !== 'TABLE_LAYOUT' })), - [githubProjectViews] + [githubProjectViews, t] ) return Object.assign(model, { createTargetOptions, diff --git a/mobile/src/tasks/use-mobile-tasks-provider-view-projection.tsx b/mobile/src/tasks/use-mobile-tasks-provider-view-projection.tsx index d4bec5d65b6..446b14c3888 100644 --- a/mobile/src/tasks/use-mobile-tasks-provider-view-projection.tsx +++ b/mobile/src/tasks/use-mobile-tasks-provider-view-projection.tsx @@ -1,6 +1,7 @@ import type { PickerProjectionModel } from './use-mobile-tasks-picker-projection' import { JIRA_FILTER_LABELS } from './mobile-jira-issue-filters' import { jiraSiteLabel } from './jira-mobile-connection' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { type PickerOption, githubProjectKey, @@ -23,6 +24,7 @@ import { } from './mobile-tasks-legacy-foundation' export function useMobileTasksProviderViewProjection(model: PickerProjectionModel) { + const t = useMobileTranslation() const colorScheme = useMobileColorScheme() const { activeGitHubProject, @@ -60,53 +62,70 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode () => githubPresetOptions.map((option) => option.value === defaultGitHubPreset - ? { ...option, subtitle: option.subtitle ? `${option.subtitle} · Default` : 'Default' } + ? { + ...option, + subtitle: option.subtitle + ? t('tasks.providerViewProjection.defaultSubtitle', '{{subtitle}} · Default', { + subtitle: option.subtitle + }) + : t('tasks.providerViewProjection.default', 'Default') + } : option ), - [defaultGitHubPreset, githubPresetOptions] + [defaultGitHubPreset, githubPresetOptions, t] ) const githubPresetLabel = - githubPresetOptions.find((preset) => preset.value === githubPreset)?.label ?? 'Open' + githubPresetOptions.find((preset) => preset.value === githubPreset)?.label ?? + t('tasks.providerViewProjection.openState', 'Open') const gitlabFilterLabel = - GITLAB_FILTER_OPTIONS.find((filter) => filter.value === gitlabFilter)?.label ?? 'Open' + GITLAB_FILTER_OPTIONS.find((filter) => filter.value === gitlabFilter)?.label ?? + t('tasks.providerViewProjection.openState', 'Open') const jiraFilterLabel = JIRA_FILTER_LABELS[jiraFilter] const jiraSelectedSite = jiraConnection.selection && jiraConnection.selection !== 'all' ? (jiraConnection.sites.find((site) => site.id === jiraConnection.selection) ?? null) : null - const jiraSiteChipLabel = jiraSelectedSite ? jiraSiteLabel(jiraSelectedSite) : 'All sites' + const jiraSiteChipLabel = jiraSelectedSite + ? jiraSiteLabel(jiraSelectedSite) + : t('tasks.providerViewProjection.allSites', 'All sites') const linearFilterLabel = - LINEAR_FILTER_OPTIONS.find((filter) => filter.value === linearFilter)?.label ?? 'All' + LINEAR_FILTER_OPTIONS.find((filter) => filter.value === linearFilter)?.label ?? + t('tasks.providerViewProjection.all', 'All') const linearViewLabel = - LINEAR_VIEW_OPTIONS.find((option) => option.value === linearViewMode)?.label ?? 'List' + LINEAR_VIEW_OPTIONS.find((option) => option.value === linearViewMode)?.label ?? + t('tasks.providerViewProjection.list', 'List') const linearGroupLabel = - LINEAR_GROUP_OPTIONS.find((option) => option.value === linearGroupBy)?.label ?? 'No grouping' + LINEAR_GROUP_OPTIONS.find((option) => option.value === linearGroupBy)?.label ?? + t('tasks.providerViewProjection.noGrouping', 'No grouping') const linearOrderLabel = - LINEAR_ORDER_OPTIONS.find((option) => option.value === linearOrderBy)?.label ?? 'Priority' + LINEAR_ORDER_OPTIONS.find((option) => option.value === linearOrderBy)?.label ?? + t('tasks.providerViewProjection.priority', 'Priority') const linearWorkspaceLabel = selectedLinearWorkspaceId === 'all' - ? 'All workspaces' + ? t('tasks.providerViewProjection.allWorkspaces', 'All workspaces') : (linearWorkspaces.find((workspace) => workspace.id === selectedLinearWorkspaceId) ?.organizationName ?? linearWorkspaces.find((workspace) => workspace.id === selectedLinearWorkspaceId) ?.displayName ?? - 'Workspace') + t('tasks.providerViewProjection.workspace', 'Workspace')) const linearWorkspaceOptions = useMemo[]>( () => [ - { value: 'all', label: 'All workspaces' }, + { value: 'all', label: t('tasks.providerViewProjection.allWorkspaces', 'All workspaces') }, ...linearWorkspaces.map((workspace) => ({ value: workspace.id, label: workspace.organizationName ?? workspace.displayName ?? workspace.id })) ], - [linearWorkspaces] + [linearWorkspaces, t] ) + const count = selectedLinearTeamIds.size const linearTeamLabel = - selectedLinearTeamIds.size === 0 || selectedLinearTeamIds.size === linearTeams.length - ? 'All teams' - : selectedLinearTeamIds.size === 1 - ? (linearTeams.find((team) => selectedLinearTeamIds.has(team.id))?.name ?? '1 team') - : `${selectedLinearTeamIds.size} teams` + count === 0 || count === linearTeams.length + ? t('tasks.providerViewProjection.allTeams', 'All teams') + : count === 1 + ? (linearTeams.find((team) => selectedLinearTeamIds.has(team.id))?.name ?? + t('tasks.providerViewProjection.teams_one', '{{count}} team', { count })) + : t('tasks.providerViewProjection.teams_other', '{{count}} teams', { count }) const effectiveLinearDisplayProperties = useMemo(() => { const next = new Set(linearDisplayProperties) if (linearGroupBy === 'status') { @@ -147,7 +166,7 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode ) const linearIssueSections = useMemo( () => groupSortedLinearIssues(linearIssuesForView, linearGroupBy), - [colorScheme, linearGroupBy, linearIssuesForView] + [colorScheme, linearGroupBy, linearIssuesForView, t] ) // Preserve FlatList data identity across unrelated renders. const linearListEntries = useMemo( @@ -168,15 +187,19 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode linearGroupBy === 'none' ? groupSortedLinearIssues(linearIssuesForView, 'status') : linearIssueSections, - [linearGroupBy, linearIssueSections, linearIssuesForView] + [linearGroupBy, linearIssueSections, linearIssuesForView, t] ) const githubModeLabel = - githubMode === 'project' ? 'Projects' : githubKind === 'prs' ? 'PRs' : 'Issues' + githubMode === 'project' + ? t('tasks.providerViewProjection.projects', 'Projects') + : githubKind === 'prs' + ? t('tasks.providerViewProjection.pullRequests', 'PRs') + : t('tasks.providerViewProjection.issues', 'Issues') const activeProjectLabel = githubProjectTable ? githubProjectTable.project.title : activeGitHubProject ? `${activeGitHubProject.owner} #${activeGitHubProject.number}` - : 'Choose project' + : t('tasks.providerViewProjection.chooseProject', 'Choose project') const selectedGitHubProjectViewUrl = githubProjectTable ? `${githubProjectTable.project.url}/views/${githubProjectTable.selectedView.number}` : null diff --git a/mobile/src/tasks/use-mobile-tasks-workspace-create-projection.tsx b/mobile/src/tasks/use-mobile-tasks-workspace-create-projection.tsx index 2db54403934..7c565b849be 100644 --- a/mobile/src/tasks/use-mobile-tasks-workspace-create-projection.tsx +++ b/mobile/src/tasks/use-mobile-tasks-workspace-create-projection.tsx @@ -1,4 +1,5 @@ import type { ProjectMetadataLoadingModel } from './use-mobile-tasks-project-metadata-loading' +import { useMobileTranslation } from '../i18n/use-mobile-translation' import { type BaseRefSearchResult, MOBILE_TUI_AGENT_AUTO_PICK_ORDER, @@ -23,6 +24,7 @@ import { } from './mobile-tasks-legacy-foundation' export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLoadingModel) { + const t = useMobileTranslation() const { repos, runtimeTaskSettings, @@ -109,7 +111,7 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo workspaceSparseDraft ? parseSparsePresetDirectories(workspaceSparseDraft.directoriesText) : null, - [workspaceSparseDraft] + [t, workspaceSparseDraft] ) const workspaceSparseDraftName = workspaceSparseDraft?.name.trim() ?? '' const workspaceSparseDraftNameCollision = @@ -122,11 +124,13 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo : null const workspaceSparseDraftError = workspaceSparseDraft && workspaceSparseDraftName.length === 0 - ? 'Name is required.' + ? t('tasks.workspaceCreateProjection.nameRequired', 'Name is required.') : workspaceSparseDraftName.length > 80 - ? 'Name must be 80 characters or fewer.' + ? t('tasks.workspaceCreateProjection.nameTooLong', 'Name must be 80 characters or fewer.') : workspaceSparseDraftNameCollision - ? `"${workspaceSparseDraftNameCollision.name}" already exists.` + ? t('tasks.workspaceCreateProjection.nameAlreadyExists', '"{{name}}" already exists.', { + name: workspaceSparseDraftNameCollision.name + }) : (workspaceSparseDraftParsed?.error ?? null) const canSaveWorkspaceSparseDraft = workspaceSparseDraft !== null && @@ -166,11 +170,11 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo { value: 'blank' as const, label: workspaceAgentLabel('blank'), - subtitle: 'Open a shell', + subtitle: t('tasks.workspaceCreateProjection.openShell', 'Open a shell'), renderIcon: () => } ] - }, [runtimeTaskSettings.disabledTuiAgents, workspaceAgent, workspaceDetectedAgentIds]) + }, [runtimeTaskSettings.disabledTuiAgents, t, workspaceAgent, workspaceDetectedAgentIds]) const openWorkspaceCreate = useCallback((item: ActionableTaskItem, repoIdOverride?: string) => { const suggestedName = taskWorkspaceSuggestedName(item) setWorkspaceCreateDraft({ item, ...(repoIdOverride ? { repoIdOverride } : {}) }) diff --git a/mobile/src/tasks/workspace-agent-selection.ts b/mobile/src/tasks/workspace-agent-selection.ts index 24dc376a663..8b2b76f09e7 100644 --- a/mobile/src/tasks/workspace-agent-selection.ts +++ b/mobile/src/tasks/workspace-agent-selection.ts @@ -1,4 +1,5 @@ import type { TuiAgent } from '../../../src/shared/tui-agent' +import { translate } from '../i18n/mobile-i18n' import { filterEnabledMobileTuiAgents, isMobileTuiAgent, @@ -27,7 +28,9 @@ type ResolveWorkspaceAgentSelectionArgs = WorkspaceAgentSelectionState & { } export function workspaceAgentLabel(agent: WorkspaceAgentChoice): string { - return agent === 'blank' ? 'Blank Terminal' : MOBILE_TUI_AGENT_LABELS[agent] + return agent === 'blank' + ? translate('tasks.workspaceAgentSelection.blankTerminal', 'Blank Terminal') + : MOBILE_TUI_AGENT_LABELS[agent] } export function normalizeWorkspaceAgent(value: unknown): WorkspaceAgentChoice | null { diff --git a/mobile/src/tasks/workspace-ssh-gate.ts b/mobile/src/tasks/workspace-ssh-gate.ts index e173968014d..4fcb22c90a3 100644 --- a/mobile/src/tasks/workspace-ssh-gate.ts +++ b/mobile/src/tasks/workspace-ssh-gate.ts @@ -1,5 +1,6 @@ import type { SshConnectionState, SshConnectionStatus } from '../../../src/shared/ssh-types' import { ORCAD_RECLAIM_STALE_LOCK_FLAG } from '../../../src/shared/orcad-stale-lock-reclaim' +import { translate } from '../i18n/mobile-i18n' // Keep unread SSH fields optional so an omitted member cannot drop auth-failed state into connected fallback. export type WorkspaceSshRecord = Omit< @@ -25,27 +26,27 @@ function isWorkspaceSshConnectInProgress(status: SshConnectionStatus | null): bo export function workspaceSshStatusLabel(status: SshConnectionStatus | null): string { if (status === 'connected') { - return 'Connected' + return translate('tasks.workspaceSshGate.connected', 'Connected') } if (status === 'connecting') { - return 'Connecting' + return translate('tasks.workspaceSshGate.connecting', 'Connecting') } if (status === 'deploying-relay') { - return 'Deploying relay' + return translate('tasks.workspaceSshGate.deployingRelay', 'Deploying relay') } if (status === 'reconnecting') { - return 'Reconnecting' + return translate('tasks.workspaceSshGate.reconnecting', 'Reconnecting') } if (status === 'auth-failed') { - return 'Authentication failed' + return translate('tasks.workspaceSshGate.authenticationFailed', 'Authentication failed') } if (status === 'reconnection-failed') { - return 'Reconnect failed' + return translate('tasks.workspaceSshGate.reconnectFailed', 'Reconnect failed') } if (status === 'error') { - return 'Connection failed' + return translate('tasks.workspaceSshGate.connectionFailed', 'Connection failed') } - return 'Disconnected' + return translate('tasks.workspaceSshGate.disconnected', 'Disconnected') } export function deriveWorkspaceSshGate(args: { diff --git a/mobile/src/tasks/worktree-create-retry.ts b/mobile/src/tasks/worktree-create-retry.ts index e2c2d5050ac..2a738026dec 100644 --- a/mobile/src/tasks/worktree-create-retry.ts +++ b/mobile/src/tasks/worktree-create-retry.ts @@ -114,7 +114,7 @@ export async function createWorktreeWithNameRetry( ...(created.warning ? { warning: created.warning } : {}) } } - lastError = 'Failed to create workspace' + lastError = translate('tasks.worktreeCreateRetry.createFailed', 'Failed to create workspace') break } lastError = response.error.message @@ -126,7 +126,10 @@ export async function createWorktreeWithNameRetry( break } } - return { error: lastError ?? 'Failed to create workspace' } + return { + error: + lastError ?? translate('tasks.worktreeCreateRetry.createFailed', 'Failed to create workspace') + } } async function resolveAgentLaunchRoute(