diff --git a/config/render-path-translate-baseline.txt b/config/render-path-translate-baseline.txt index 427f2dbba79..75b9990b5d6 100644 --- a/config/render-path-translate-baseline.txt +++ b/config/render-path-translate-baseline.txt @@ -849,37 +849,6 @@ 1 src/renderer/src/components/settings/appearance/use-appearance-picker-labels.ts 23 src/renderer/src/components/settings/artifacts/ArtifactsSettingsPane.tsx 12 src/renderer/src/components/settings/automations/AutomationsSettingsPane.tsx -4 src/renderer/src/components/settings/browser/BrowserDefaultZoomSetting.tsx -7 src/renderer/src/components/settings/browser/BrowserHomePageSetting.tsx -4 src/renderer/src/components/settings/browser/BrowserPane.tsx -4 src/renderer/src/components/settings/browser/BrowserSearchEngineSetting.tsx -5 src/renderer/src/components/settings/browser/BrowserSitePermissionsSetting.tsx -12 src/renderer/src/components/settings/browser/BrowserUserAgentSetting.tsx -9 src/renderer/src/components/settings/browser/KagiSessionLinkForm.tsx -2 src/renderer/src/components/settings/browser/extensions/BrowserExtensionsExperimentalSetting.tsx -16 src/renderer/src/components/settings/browser/extensions/BrowserExtensionsSection.tsx -7 src/renderer/src/components/settings/browser/extensions/BrowserExtensionsWebStoreInstall.tsx -15 src/renderer/src/components/settings/browser/passwords/BrowserPasswordEntryDialog.tsx -2 src/renderer/src/components/settings/browser/passwords/BrowserPasswordImportMenu.tsx -10 src/renderer/src/components/settings/browser/passwords/BrowserPasswordList.tsx -2 src/renderer/src/components/settings/browser/passwords/BrowserPasswordNeverList.tsx -6 src/renderer/src/components/settings/browser/passwords/BrowserPasswordPreferences.tsx -21 src/renderer/src/components/settings/browser/passwords/BrowserPasswordsSection.tsx -7 src/renderer/src/components/settings/browser/profiles/BrowserNewProfileDialog.tsx -11 src/renderer/src/components/settings/browser/profiles/BrowserProfileRow.tsx -6 src/renderer/src/components/settings/browser/profiles/BrowserProfileScopeSetting.tsx -13 src/renderer/src/components/settings/browser/profiles/BrowserSessionCookiesSection.tsx -4 src/renderer/src/components/settings/browser/routing/BrowserClientHostedRemoteSetting.tsx -3 src/renderer/src/components/settings/browser/routing/BrowserLinkRoutingSetting.tsx -2 src/renderer/src/components/settings/browser/routing/BrowserLocalhostWorktreeLabelsSetting.tsx -6 src/renderer/src/components/settings/browser/routing/BrowserSshWorkspaceRoutingSetting.tsx -11 src/renderer/src/components/settings/browser/routing/BrowserTerminalLinkActionsSetting.tsx -3 src/renderer/src/components/settings/browser/use/BrowserUseComputerUseNotice.tsx -13 src/renderer/src/components/settings/browser/use/BrowserUseCookieImportStep.tsx -1 src/renderer/src/components/settings/browser/use/BrowserUseEnableSwitch.tsx -6 src/renderer/src/components/settings/browser/use/BrowserUseExamples.tsx -6 src/renderer/src/components/settings/browser/use/BrowserUsePane.tsx -2 src/renderer/src/components/settings/browser/use/BrowserUseSkillStep.tsx 3 src/renderer/src/components/settings/chat/ChatBehaviorSetting.tsx 10 src/renderer/src/components/settings/chat/ChatNamingSetting.tsx 2 src/renderer/src/components/settings/chat/ChatPermissionSetting.tsx @@ -944,64 +913,6 @@ 9 src/renderer/src/components/settings/quick-commands/QuickCommandsPane.tsx 4 src/renderer/src/components/settings/quick-commands/QuickCommandsScopeFilter.tsx 4 src/renderer/src/components/settings/quick-commands/QuickCommandsToolbar.tsx -8 src/renderer/src/components/settings/repository/RepositoryFormatterSection.tsx -18 src/renderer/src/components/settings/repository/RepositoryGitHubAccountSection.tsx -6 src/renderer/src/components/settings/repository/RepositoryJiraProjectSection.tsx -19 src/renderer/src/components/settings/repository/RepositoryPane.tsx -1 src/renderer/src/components/settings/repository/RepositoryRemoveProjectButton.tsx -9 src/renderer/src/components/settings/repository/execution/ProjectWindowsRuntimeSetting.tsx -12 src/renderer/src/components/settings/repository/execution/RepositoryForkSyncSection.tsx -17 src/renderer/src/components/settings/repository/execution/RepositoryHookPolicySettings.tsx -16 src/renderer/src/components/settings/repository/execution/RepositoryHookScriptSetting.tsx -12 src/renderer/src/components/settings/repository/execution/RepositoryHooksSection.tsx -6 src/renderer/src/components/settings/repository/execution/RepositoryHooksYamlStatus.tsx -7 src/renderer/src/components/settings/repository/execution/RepositoryHostSetupActions.tsx -16 src/renderer/src/components/settings/repository/execution/RepositoryHostSetupsSection.tsx -7 src/renderer/src/components/settings/repository/execution/RepositoryIssueCommandSetting.tsx -2 src/renderer/src/components/settings/repository/execution/RepositoryWindowsRuntimeSection.tsx -20 src/renderer/src/components/settings/repository/execution/RepositoryWorktreeDefaultsSection.tsx -7 src/renderer/src/components/settings/repository/execution/SparsePresetSettingsSection.tsx -14 src/renderer/src/components/settings/repository/execution/WorktreeSymlinksSection.tsx -22 src/renderer/src/components/settings/repository/execution/repository-host-add-project-steps.tsx -1 src/renderer/src/components/settings/repository/execution/sparse-preset-directory-preview.tsx -9 src/renderer/src/components/settings/repository/execution/sparse-preset-settings-row.tsx -4 src/renderer/src/components/settings/repository/identity/RepositoryIconColorSection.tsx -3 src/renderer/src/components/settings/repository/identity/RepositoryIconEmojiPicker.tsx -4 src/renderer/src/components/settings/repository/identity/RepositoryIconPicker.tsx -13 src/renderer/src/components/settings/repository/identity/RepositoryIconTabs.tsx -4 src/renderer/src/components/settings/repository/mcp/McpConfigFileRow.tsx -9 src/renderer/src/components/settings/repository/mcp/McpConfigSection.tsx -1 src/renderer/src/components/settings/repository/mcp/McpMissingConfigList.tsx -6 src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiActionRows.tsx -5 src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiCustomCommand.tsx -5 src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiEnablement.tsx -5 src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiHostedReviewDefaults.tsx -1 src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiSection.tsx -3 src/renderer/src/components/settings/runtime-environments/catalog/RuntimeEnvironmentsPane.tsx -4 src/renderer/src/components/settings/runtime-environments/catalog/runtime-default-host-row.tsx -11 src/renderer/src/components/settings/runtime-environments/catalog/runtime-environment-dialogs.tsx -3 src/renderer/src/components/settings/runtime-environments/catalog/use-runtime-environment-connection-actions.ts -6 src/renderer/src/components/settings/runtime-environments/catalog/use-runtime-environment-mutation-actions.ts -22 src/renderer/src/components/settings/runtime-environments/managed-servers/managed-server-row-parts.tsx -18 src/renderer/src/components/settings/runtime-environments/managed-servers/runtime-install-server-dialog.tsx -11 src/renderer/src/components/settings/runtime-environments/pairing/RuntimeAccessGrantList.tsx -1 src/renderer/src/components/settings/runtime-environments/pairing/RuntimePairingGeneratedUrlRows.tsx -37 src/renderer/src/components/settings/runtime-environments/pairing/RuntimePairingGeneratorForm.tsx -9 src/renderer/src/components/settings/runtime-environments/pairing/RuntimePairingUrlGenerator.tsx -2 src/renderer/src/components/settings/runtime-environments/pairing/runtime-add-server-dialog.tsx -9 src/renderer/src/components/settings/runtime-environments/pairing/runtime-share-computer-button.tsx -3 src/renderer/src/components/settings/runtime-environments/pairing/use-runtime-pairing-url-copy.ts -10 src/renderer/src/components/settings/runtime-environments/runtime-servers-header-actions.tsx -4 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-list-row.tsx -4 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-list.tsx -15 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-row-details.tsx -10 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-row-menu.tsx -1 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-row-state.ts -8 src/renderer/src/components/settings/runtime-environments/server-rows/runtime-server-row.tsx -11 src/renderer/src/components/settings/runtime-environments/ssh-access/RuntimeSshAccessControl.tsx -3 src/renderer/src/components/settings/runtime-environments/ssh-access/runtime-ssh-access-dialog.tsx -12 src/renderer/src/components/settings/runtime-environments/updates/GeneralRemoteServerUpdates.tsx -15 src/renderer/src/components/settings/runtime-environments/updates/RemoteServerUpdateDialog.tsx 2 src/renderer/src/components/settings/session-history/SessionHistoryComputerRow.tsx 4 src/renderer/src/components/settings/session-history/SessionHistoryServerRow.tsx 7 src/renderer/src/components/settings/session-history/SessionHistorySettingsPane.tsx @@ -1034,58 +945,14 @@ 6 src/renderer/src/components/settings/source-control/SourceControlActionRepoOverrideNote.tsx 2 src/renderer/src/components/settings/source-control/SourceControlAiActionRecipeDefaults.tsx 4 src/renderer/src/components/settings/source-control/text-actions/SourceControlTextActionAgentPicker.tsx -8 src/renderer/src/components/settings/ssh/SshPane.tsx -18 src/renderer/src/components/settings/ssh/SshPaneToolbar.tsx -7 src/renderer/src/components/settings/ssh/server-actions/SshHostDeltaMoveDialog.tsx -4 src/renderer/src/components/settings/ssh/server-actions/SshHostKeepServerVersionDialog.tsx -5 src/renderer/src/components/settings/ssh/server-actions/SshHostMoveAnywayAction.tsx -19 src/renderer/src/components/settings/ssh/server-actions/SshHostRecoverServerAction.tsx -4 src/renderer/src/components/settings/ssh/server-actions/SshHostRestartServerAction.tsx -9 src/renderer/src/components/settings/ssh/server-actions/SshTargetServerStatus.tsx -2 src/renderer/src/components/settings/ssh/targets/SshDestructiveActionDialog.tsx -19 src/renderer/src/components/settings/ssh/targets/SshHostAdvancedFields.tsx -4 src/renderer/src/components/settings/ssh/targets/SshManagedHostRemoveDialog.tsx -5 src/renderer/src/components/settings/ssh/targets/SshRestoreRemovedHostsDialog.tsx -11 src/renderer/src/components/settings/ssh/targets/SshTargetCard.tsx -9 src/renderer/src/components/settings/ssh/targets/SshTargetDestructiveActions.tsx -18 src/renderer/src/components/settings/ssh/targets/SshTargetForm.tsx -3 src/renderer/src/components/settings/ssh/targets/SshTargetList.tsx -1 src/renderer/src/components/settings/ssh/targets/SshTargetsEmptyState.tsx -1 src/renderer/src/components/settings/ssh/targets/use-ssh-bulk-remove.ts -3 src/renderer/src/components/settings/ssh/targets/use-ssh-config-sync.ts -6 src/renderer/src/components/settings/ssh/targets/use-ssh-target-tests.ts 2 src/renderer/src/components/settings/tasks/JiraIssueKeyCasingSetting.tsx 13 src/renderer/src/components/settings/tasks/TaskSourceLinearSetup.tsx 2 src/renderer/src/components/settings/tasks/TaskSourceProviderCard.tsx 2 src/renderer/src/components/settings/tasks/TaskSourceShowInTasksStep.tsx 11 src/renderer/src/components/settings/tasks/TaskSourceSimpleSetup.tsx 10 src/renderer/src/components/settings/tasks/TasksPane.tsx -26 src/renderer/src/components/settings/terminal/TerminalAdvancedSection.tsx -37 src/renderer/src/components/settings/terminal/TerminalInteractionSection.tsx 22 src/renderer/src/components/settings/terminal/TerminalPane.tsx -25 src/renderer/src/components/settings/terminal/TerminalWindowSection.tsx -20 src/renderer/src/components/settings/terminal/appearance/TerminalAdvancedTypographyControls.tsx -5 src/renderer/src/components/settings/terminal/appearance/TerminalAppearanceSection.tsx -12 src/renderer/src/components/settings/terminal/appearance/TerminalContrastSetting.tsx -14 src/renderer/src/components/settings/terminal/appearance/TerminalCursorAppearanceSection.tsx -4 src/renderer/src/components/settings/terminal/appearance/TerminalFontSizeSetting.tsx -8 src/renderer/src/components/settings/terminal/appearance/TerminalPaneAppearanceSection.tsx -16 src/renderer/src/components/settings/terminal/appearance/TerminalRenderingSection.tsx 5 src/renderer/src/components/settings/terminal/appearance/TerminalSettingsPreview.tsx -11 src/renderer/src/components/settings/terminal/configuration/TerminalConfigImportModal.tsx -21 src/renderer/src/components/settings/terminal/platform/TerminalMacKeyboardSection.tsx -25 src/renderer/src/components/settings/terminal/platform/TerminalWindowsAdministratorSection.tsx -15 src/renderer/src/components/settings/terminal/platform/TerminalWindowsShellSection.tsx -6 src/renderer/src/components/settings/terminal/session-management/ManageSessionKillDialog.tsx -2 src/renderer/src/components/settings/terminal/session-management/ManageSessionsSection.tsx -10 src/renderer/src/components/settings/terminal/session-management/ManageSessionsTable.tsx -16 src/renderer/src/components/settings/terminal/session-management/TerminalLimitSetting.tsx -15 src/renderer/src/components/settings/terminal/themes/TerminalThemePicker.tsx -23 src/renderer/src/components/settings/terminal/themes/TerminalThemeSections.tsx -1 src/renderer/src/components/settings/terminal/themes/WarpThemeImportButton.tsx -22 src/renderer/src/components/settings/terminal/themes/WarpThemeImportModal.tsx -1 src/renderer/src/components/settings/terminal/themes/YamlThemeImportButton.tsx -4 src/renderer/src/components/settings/terminal/themes/useWarpThemeImport.ts 25 src/renderer/src/components/settings/updates/GeneralUpdateSettingsSection.tsx 4 src/renderer/src/components/settings/updates/ReleaseBuildPicker.tsx 17 src/renderer/src/components/settings/updates/ReleaseChannelSection.tsx diff --git a/src/renderer/src/components/browser-extension-permission-messages.ts b/src/renderer/src/components/browser-extension-permission-messages.ts index 64c1b7aa9f8..f94396ff876 100644 --- a/src/renderer/src/components/browser-extension-permission-messages.ts +++ b/src/renderer/src/components/browser-extension-permission-messages.ts @@ -1,4 +1,5 @@ import { translate } from '@/i18n/i18n' +import type { Translate } from '@/i18n/use-translate' import { browserExtensionHostWarning, browserExtensionPermissionWarning, @@ -132,14 +133,15 @@ function featureLabel(feature: UnsupportedBrowserExtensionFeature): string { } /** One calm line naming what the extension asks for that Orca cannot do yet, or null. */ -export function describeUnsupportedBrowserExtensionFeatures(permissions: string[]): string | null { +export function describeUnsupportedBrowserExtensionFeatures( + permissions: string[], + t: Translate = translate +): string | null { const features = unsupportedBrowserExtensionFeatures(permissions) if (features.length === 0) { return null } - return translate( - 'browserExtensions.unsupported.line', - 'Not available in Orca yet: {{features}}.', - { features: features.map(featureLabel).join(', ') } - ) + return t('browserExtensions.unsupported.line', 'Not available in Orca yet: {{features}}.', { + features: features.map(featureLabel).join(', ') + }) } diff --git a/src/renderer/src/components/browser-pane/browser-site-permission-copy.ts b/src/renderer/src/components/browser-pane/browser-site-permission-copy.ts index 4aead057f9c..2b1a8e70984 100644 --- a/src/renderer/src/components/browser-pane/browser-site-permission-copy.ts +++ b/src/renderer/src/components/browser-pane/browser-site-permission-copy.ts @@ -4,40 +4,35 @@ import { type BrowserSitePermission } from '../../../../shared/browser-site-permission' import { translate } from '@/i18n/i18n' +import type { Translate } from '@/i18n/use-translate' /** The setting's name, e.g. in Settings → Browser → Site permissions. */ -export function browserSitePermissionLabel(permission: BrowserSitePermission): string { +export function browserSitePermissionLabel( + permission: BrowserSitePermission, + t: Translate = translate +): string { switch (permission) { case 'camera': - return translate('auto.components.browserPane.sitePermission.label.camera', 'Camera') + return t('auto.components.browserPane.sitePermission.label.camera', 'Camera') case 'microphone': - return translate('auto.components.browserPane.sitePermission.label.microphone', 'Microphone') + return t('auto.components.browserPane.sitePermission.label.microphone', 'Microphone') case 'location': - return translate('auto.components.browserPane.sitePermission.label.location', 'Location') + return t('auto.components.browserPane.sitePermission.label.location', 'Location') case 'notifications': - return translate( - 'auto.components.browserPane.sitePermission.label.notifications', - 'Notifications' - ) + return t('auto.components.browserPane.sitePermission.label.notifications', 'Notifications') case 'clipboard': - return translate('auto.components.browserPane.sitePermission.label.clipboard', 'Clipboard') + return t('auto.components.browserPane.sitePermission.label.clipboard', 'Clipboard') case 'midi': - return translate('auto.components.browserPane.sitePermission.label.midi', 'MIDI devices') + return t('auto.components.browserPane.sitePermission.label.midi', 'MIDI devices') case 'window-management': - return translate( + return t( 'auto.components.browserPane.sitePermission.label.windowManagement', 'Window management' ) case 'idle-detection': - return translate( - 'auto.components.browserPane.sitePermission.label.idleDetection', - 'Device use' - ) + return t('auto.components.browserPane.sitePermission.label.idleDetection', 'Device use') case 'local-network': - return translate( - 'auto.components.browserPane.sitePermission.label.localNetwork', - 'Local network' - ) + return t('auto.components.browserPane.sitePermission.label.localNetwork', 'Local network') } } @@ -90,9 +85,9 @@ export function browserSitePermissionRequestLine(permission: BrowserSitePermissi } /** The origin as people read it: the host for https, the full origin otherwise. */ -export function browserSitePermissionSiteName(origin: string): string { +export function browserSitePermissionSiteName(origin: string, t: Translate = translate): string { if (origin === BROWSER_SITE_PERMISSION_LOCAL_FILES_ORIGIN) { - return translate('auto.components.browserPane.sitePermission.localFiles', 'Local files') + return t('auto.components.browserPane.sitePermission.localFiles', 'Local files') } return origin.startsWith('https://') ? origin.slice('https://'.length) : origin } diff --git a/src/renderer/src/components/plugins/presentation/plugin-name-disambiguation.ts b/src/renderer/src/components/plugins/presentation/plugin-name-disambiguation.ts index 34368b4815d..1d0165ed177 100644 --- a/src/renderer/src/components/plugins/presentation/plugin-name-disambiguation.ts +++ b/src/renderer/src/components/plugins/presentation/plugin-name-disambiguation.ts @@ -1,4 +1,5 @@ import { translate } from '@/i18n/i18n' +import type { Translate } from '@/i18n/use-translate' import { hasOfficialPluginPublisher, splitQualifiedPluginKey @@ -8,8 +9,12 @@ import { type PluginNameCandidate } from '../../../../../shared/plugins/plugin-name-clashes' -export function pluginNameWithPublisher(name: string, publisher: string): string { - return translate( +export function pluginNameWithPublisher( + name: string, + publisher: string, + t: Translate = translate +): string { + return t( 'auto.components.plugins.pluginNameDisambiguation.nameWithPublisher', '{{value0}} ({{value1}})', { value0: name, value1: publisher } @@ -18,14 +23,15 @@ export function pluginNameWithPublisher(name: string, publisher: string): string /** Each item's name as a list shows it: a clashing non-official one gains " (publisher)". */ export function disambiguatedPluginNames( - items: readonly PluginNameCandidate[] + items: readonly PluginNameCandidate[], + t?: Translate ): Map { const clashing = pluginNameClashKeys(items) return new Map( items.map((item) => [ item.key, clashing.has(item.key) && item.publisher - ? pluginNameWithPublisher(item.name, item.publisher) + ? pluginNameWithPublisher(item.name, item.publisher, t) : item.name ]) ) @@ -48,26 +54,31 @@ export type PluginContentLabelItem = { id: string; pluginKey: string; label: str */ export function disambiguatedPluginContentLabels( items: readonly PluginContentLabelItem[], - plainLabels: readonly string[] = [] + plainLabels: readonly string[] = [], + t?: Translate ): Map { - return disambiguatedPluginNames([ - ...plainLabels.map((label, index) => ({ - key: `\0built-in:${index}`, - name: label, - publisher: null, - official: true - })), - ...items.map((item) => ({ - key: item.id, - name: item.label, - ...contentPublisher(item.pluginKey) - })) - ]) + return disambiguatedPluginNames( + [ + ...plainLabels.map((label, index) => ({ + key: `\0built-in:${index}`, + name: label, + publisher: null, + official: true + })), + ...items.map((item) => ({ + key: item.id, + name: item.label, + ...contentPublisher(item.pluginKey) + })) + ], + t + ) } /** Plugin names for the plugins behind some content, keyed by plugin key. */ export function disambiguatedContentPluginNames( - items: readonly { pluginKey: string; pluginName: string }[] + items: readonly { pluginKey: string; pluginName: string }[], + t?: Translate ): Map { const byPlugin = new Map(items.map((item) => [item.pluginKey, item.pluginName])) return disambiguatedPluginNames( @@ -75,7 +86,8 @@ export function disambiguatedContentPluginNames( key: pluginKey, name, ...contentPublisher(pluginKey) - })) + })), + t ) } diff --git a/src/renderer/src/components/settings/advanced/experimental-search.ts b/src/renderer/src/components/settings/advanced/experimental-search.ts index 259ecc66fff..97f63766797 100644 --- a/src/renderer/src/components/settings/advanced/experimental-search.ts +++ b/src/renderer/src/components/settings/advanced/experimental-search.ts @@ -1,6 +1,7 @@ import type { SettingsSearchEntry } from '../search/settings-search' import { createLocalizedCatalog } from '@/i18n/localized-catalog' import { translate } from '@/i18n/i18n' +import type { Translate } from '@/i18n/use-translate' import { translateSearchKeyword } from '../search/settings-search-keywords' import { getNewWorktreeCardStyleSearchEntry } from './new-worktree-card-style-search-entry' import { getEphemeralVmsSearchEntry } from '../virtual-machines/recipes/ephemeral-vms-search' @@ -198,35 +199,26 @@ function findEntry(title: string): SettingsSearchEntry { return entry } -export function getExperimentalSearchEntry() { +export function getExperimentalSearchEntry(t: Translate = translate) { return { - pet: findEntry(translate('auto.components.settings.experimental.search.87d99e634b', 'Pet')), + pet: findEntry(t('auto.components.settings.experimental.search.87d99e634b', 'Pet')), agentDashboard: findEntry( - translate( - 'auto.components.settings.experimental.search.agentDashboard.title', - 'Agent Dashboard' - ) + t('auto.components.settings.experimental.search.agentDashboard.title', 'Agent Dashboard') ), terminalAttention: findEntry( - translate('auto.components.settings.experimental.search.9e4ddf776d', 'Terminal attention') + t('auto.components.settings.experimental.search.9e4ddf776d', 'Terminal attention') ), agentHibernation: findEntry( - translate( - 'auto.components.settings.experimental.search.agentHibernation.title', - 'Agent sleep' - ) + t('auto.components.settings.experimental.search.agentHibernation.title', 'Agent sleep') ), newWorktreeCardStyle: findEntry( - translate( - 'auto.components.settings.experimental.search.newWorktreeCardStyle.title', - 'New card style' - ) + t('auto.components.settings.experimental.search.newWorktreeCardStyle.title', 'New card style') ), ephemeralVms: findEntry( - translate('auto.components.settings.ephemeralVms.search.cloudVmTitle', 'Cloud VM') + t('auto.components.settings.ephemeralVms.search.cloudVmTitle', 'Cloud VM') ), browserExtensions: findEntry( - translate( + t( 'auto.components.settings.experimental.search.browserExtensions.title', 'Browser extensions' ) diff --git a/src/renderer/src/components/settings/browser/BrowserDefaultZoomSetting.tsx b/src/renderer/src/components/settings/browser/BrowserDefaultZoomSetting.tsx index 5c264e0594c..a67badb9d75 100644 --- a/src/renderer/src/components/settings/browser/BrowserDefaultZoomSetting.tsx +++ b/src/renderer/src/components/settings/browser/BrowserDefaultZoomSetting.tsx @@ -6,7 +6,7 @@ import { import { Label } from '../../ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select' import { SearchableSetting } from '../section-layout/SearchableSetting' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' type BrowserDefaultZoomSettingProps = { value: number @@ -17,15 +17,13 @@ export function BrowserDefaultZoomSetting({ value, onChange }: BrowserDefaultZoomSettingProps): React.JSX.Element { + const t = useTranslate() const selectedZoomLevel = normalizeBrowserPageZoomLevel(value) return (

- {translate( + {t( 'auto.components.settings.BrowserDefaultZoomSetting.siteDefault', "Zoom for sites you haven't zoomed." )} diff --git a/src/renderer/src/components/settings/browser/BrowserHomePageSetting.tsx b/src/renderer/src/components/settings/browser/BrowserHomePageSetting.tsx index 6089efa0a87..1370c7d45e0 100644 --- a/src/renderer/src/components/settings/browser/BrowserHomePageSetting.tsx +++ b/src/renderer/src/components/settings/browser/BrowserHomePageSetting.tsx @@ -5,7 +5,7 @@ import { Button } from '../../ui/button' import { Input } from '../../ui/input' import { Label } from '../../ui/label' import { SearchableSetting } from '../section-layout/SearchableSetting' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' type BrowserHomePageSettingProps = { value: string @@ -18,13 +18,11 @@ export function BrowserHomePageSetting({ onChange, onSave }: BrowserHomePageSettingProps): React.JSX.Element { + const t = useTranslate() return (

- {translate( + {t( 'auto.components.settings.BrowserHomePageSetting.6a37540f4b', 'URL opened when creating a new browser tab. Leave empty to open a blank tab.' )} @@ -58,10 +53,7 @@ export function BrowserHomePageSetting({ if (normalized && normalized !== ORCA_BROWSER_BLANK_URL) { onSave(normalized) toast.success( - translate( - 'auto.components.settings.BrowserHomePageSetting.c6cbd1c105', - 'Home page saved.' - ) + t('auto.components.settings.BrowserHomePageSetting.c6cbd1c105', 'Home page saved.') ) } }} @@ -69,7 +61,7 @@ export function BrowserHomePageSetting({ onChange(event.target.value)} - placeholder={translate( + placeholder={t( 'auto.components.settings.BrowserHomePageSetting.37a30c5bfd', 'https://google.com' )} @@ -79,7 +71,7 @@ export function BrowserHomePageSetting({ className="h-7 w-52 text-xs" /> diff --git a/src/renderer/src/components/settings/browser/BrowserPane.tsx b/src/renderer/src/components/settings/browser/BrowserPane.tsx index e0418d7dc4e..5836dda95a9 100644 --- a/src/renderer/src/components/settings/browser/BrowserPane.tsx +++ b/src/renderer/src/components/settings/browser/BrowserPane.tsx @@ -38,7 +38,7 @@ import { } from '../../../../../shared/execution-host' import { isMacUserAgent } from '@/lib/user-agent-platform' import { isWebClientLocation } from '@/lib/web-client-location' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' import { useUiLanguageRevision } from '@/i18n/use-ui-language-revision' import { resolveAvailableBrowserSessionHostId } from './profiles/browser-session-host-selection' import { getDefaultBrowserProfileForHost } from '@/store/slices/browser/hosts/browser-host-state' @@ -62,6 +62,7 @@ export function BrowserPane({ updateSettings, onOpenComputerUse }: BrowserPaneProps): React.JSX.Element { + const t = useTranslate() const languageRevision = useUiLanguageRevision() const searchQuery = useAppStore((s) => s.settingsSearchQuery) const browserDefaultUrl = useAppStore((s) => s.browserDefaultUrl) @@ -126,33 +127,37 @@ export function BrowserPane({ const showSitePermissions = matchesSettingsSearch(searchQuery, [browserSearchEntries[11]]) const showProfileScope = matchesSettingsSearch(searchQuery, [browserSearchEntries[12]]) const showLinkRoutingBackground = matchesSettingsSearch(searchQuery, [browserSearchEntries[13]]) - const showPasswords = matchesSettingsSearch(searchQuery, [getBrowserPasswordsSearchEntry()]) + const showPasswords = matchesSettingsSearch(searchQuery, [getBrowserPasswordsSearchEntry(t)]) const showBrowserUse = matchesSettingsSearch(searchQuery, getBrowserUsePaneSearchEntries()) const isMac = isMacUserAgent() const linkRoutingDescription = getBrowserLinkRoutingDescription( { isMac }, - settings.openLinksInAppModifierInverts === true + settings.openLinksInAppModifierInverts === true, + t ) const hostLabelOverrides = useMemo(() => getHostDisplayLabelOverrides(settings), [settings]) const browserSessionHostOptions = useMemo( () => - buildSidebarHostOptions({ - repos, - sshTargetLabels, - sshConnectionStates, - settings, - runtimeEnvironments, - runtimeStatusByEnvironmentId, - hostLabelOverrides - }) + buildSidebarHostOptions( + { + repos, + sshTargetLabels, + sshConnectionStates, + settings, + runtimeEnvironments, + runtimeStatusByEnvironmentId, + hostLabelOverrides + }, + t + ) .filter((host) => host.kind === 'local' || host.kind === 'runtime') .map((host) => ({ id: host.id, label: host.label, detail: host.kind === 'local' - ? translate('auto.components.settings.BrowserPane.86b7c83fee', 'This computer') - : translate( + ? t('auto.components.settings.BrowserPane.86b7c83fee', 'This computer') + : t( 'auto.components.settings.BrowserPane.c0f85056d9', 'Browser profiles on this Orca server.' ) @@ -166,7 +171,8 @@ export function BrowserPane({ runtimeEnvironments, runtimeStatusByEnvironmentId, hostLabelOverrides, - languageRevision + languageRevision, + t ] ) const settingsFocusedHostId = getSettingsFocusedExecutionHostId(settings) @@ -340,8 +346,8 @@ export function BrowserPane({ {showClientHostedRemote || showSshWorkspaceRouting ? (

- {translate( + {t( 'auto.components.settings.BrowserPane.3e46903ad4', 'Used when typing non-URL text in the address bar.' )} diff --git a/src/renderer/src/components/settings/browser/BrowserSitePermissionsSetting.tsx b/src/renderer/src/components/settings/browser/BrowserSitePermissionsSetting.tsx index b00954e6069..8536e19674a 100644 --- a/src/renderer/src/components/settings/browser/BrowserSitePermissionsSetting.tsx +++ b/src/renderer/src/components/settings/browser/BrowserSitePermissionsSetting.tsx @@ -18,7 +18,7 @@ import { SettingsRow } from '../form-controls/SettingsFormControls' import { getBrowserSitePermissionsSearchEntry } from './browser-site-permissions-search' import { LOCAL_EXECUTION_HOST_ID } from '../../../../../shared/execution-host' import { useAppStore } from '../../../store/index' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' function SitePermissionRow({ entry, @@ -29,7 +29,8 @@ function SitePermissionRow({ permission: BrowserSitePermission onChange: (permission: BrowserSitePermission, value: string) => void }): React.JSX.Element { - const label = browserSitePermissionLabel(permission) + const t = useTranslate() + const label = browserSitePermissionLabel(permission, t) return ( - {translate('settings.browser.sitePermissions.allow', 'Allow')} + {t('settings.browser.sitePermissions.allow', 'Allow')} - {translate('settings.browser.sitePermissions.block', 'Block')} + {t('settings.browser.sitePermissions.block', 'Block')} - {translate('settings.browser.sitePermissions.ask', 'Ask again')} + {t('settings.browser.sitePermissions.ask', 'Ask again')} @@ -62,6 +63,7 @@ const NO_PROFILES: readonly BrowserSessionProfile[] = [] /** Remembered answers live on this computer, so only its own browser profiles are listed. */ export function BrowserSitePermissionsSetting(): React.JSX.Element { + const t = useTranslate() const profiles = useAppStore((s) => s.browserSessionProfilesByHostId[LOCAL_EXECUTION_HOST_ID]) ?? NO_PROFILES const fetchBrowserSessionProfiles = useAppStore((s) => s.fetchBrowserSessionProfiles) @@ -129,7 +131,7 @@ export function BrowserSitePermissionsSetting(): React.JSX.Element { @@ -146,7 +148,7 @@ export function BrowserSitePermissionsSetting(): React.JSX.Element { {entries?.length === 0 ? (

- {translate( + {t( 'settings.browser.sitePermissions.empty', 'No sites have been allowed or blocked yet.' )} @@ -157,7 +159,7 @@ export function BrowserSitePermissionsSetting(): React.JSX.Element { {entries.map((entry) => (

- {browserSitePermissionSiteName(entry.origin)} + {browserSitePermissionSiteName(entry.origin, t)}

{BROWSER_SITE_PERMISSIONS.filter((permission) => entry.decisions[permission]).map( (permission) => ( diff --git a/src/renderer/src/components/settings/browser/BrowserUserAgentSetting.tsx b/src/renderer/src/components/settings/browser/BrowserUserAgentSetting.tsx index 7f17d88fdea..c9f6c84bbef 100644 --- a/src/renderer/src/components/settings/browser/BrowserUserAgentSetting.tsx +++ b/src/renderer/src/components/settings/browser/BrowserUserAgentSetting.tsx @@ -5,7 +5,7 @@ import type { } from '../../../../../shared/browser-user-agent-mode' import { LOCAL_EXECUTION_HOST_ID, type ExecutionHostId } from '../../../../../shared/execution-host' import { BROWSER_USER_AGENT_SETTINGS_TARGET_ID } from '@/lib/settings-navigation-types' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' import { SearchableSetting } from '../section-layout/SearchableSetting' import { SettingsRow, SettingsSegmentedControl } from '../form-controls/SettingsFormControls' @@ -16,11 +16,12 @@ type BrowserUserAgentSettingProps = { export function BrowserUserAgentSetting({ hostId }: BrowserUserAgentSettingProps): React.JSX.Element { + const t = useTranslate() const [status, setStatus] = useState(null) const [error, setError] = useState(null) const [saving, setSaving] = useState(false) - const title = translate('settings.browser.userAgent.title', 'Browser identity') - const description = translate( + const title = t('settings.browser.userAgent.title', 'Browser identity') + const description = t( 'settings.browser.userAgent.description', 'Choose the user agent for every browser profile and page. Changes take effect after a restart.' ) @@ -57,9 +58,7 @@ export function BrowserUserAgentSetting({ .identitySet(mode) .then((result) => { if (!result) { - setError( - translate('settings.browser.userAgent.unavailable', 'Browser identity is unavailable.') - ) + setError(t('settings.browser.userAgent.unavailable', 'Browser identity is unavailable.')) } else if (!result.ok) { setError(result.error.message) } else { @@ -74,7 +73,7 @@ export function BrowserUserAgentSetting({ if (!isLocal) { control = ( - {translate( + {t( 'settings.browser.userAgent.remoteUnsupported', 'Manage browser identity on the remote host with the Orca CLI.' )} @@ -83,7 +82,7 @@ export function BrowserUserAgentSetting({ } else if (!status) { control = ( - {error ?? translate('settings.browser.userAgent.loading', 'Loading…')} + {error ?? t('settings.browser.userAgent.loading', 'Loading…')} ) } else if (status.identity.configuredMode === null) { @@ -91,13 +90,13 @@ export function BrowserUserAgentSetting({ control = (
- {translate( + {t( 'settings.browser.userAgent.resetRequired', 'Identity data must be reset explicitly before it can be changed.' )}
- {translate( + {t( 'settings.browser.userAgent.resetRequiredCommand', 'Reset it from the command line: orca browser identity set --mode --reset' )} @@ -116,8 +115,8 @@ export function BrowserUserAgentSetting({ { value: 'clean', disabled: saving, - label: translate('settings.browser.userAgent.optionClean', 'Cleaned'), - tooltip: translate( + label: t('settings.browser.userAgent.optionClean', 'Cleaned'), + tooltip: t( 'settings.browser.userAgent.optionCleanTooltip', 'Removes Orca and Electron tokens to match imported Chrome sessions.' ) @@ -125,8 +124,8 @@ export function BrowserUserAgentSetting({ { value: 'native', disabled: saving, - label: translate('settings.browser.userAgent.optionNative', 'Native'), - tooltip: translate( + label: t('settings.browser.userAgent.optionNative', 'Native'), + tooltip: t( 'settings.browser.userAgent.optionNativeTooltip', "Keeps Electron's built-in identity for sites that reject the cleaned identity." ) @@ -135,7 +134,7 @@ export function BrowserUserAgentSetting({ /> {status.identity.restartRequired ? (
- {translate('settings.browser.userAgent.restartRequired', 'Restart required')} + {t('settings.browser.userAgent.restartRequired', 'Restart required')}
) : null} {error ?
{error}
: null} diff --git a/src/renderer/src/components/settings/browser/KagiSessionLinkForm.tsx b/src/renderer/src/components/settings/browser/KagiSessionLinkForm.tsx index 35290f7049f..22c42052031 100644 --- a/src/renderer/src/components/settings/browser/KagiSessionLinkForm.tsx +++ b/src/renderer/src/components/settings/browser/KagiSessionLinkForm.tsx @@ -4,7 +4,7 @@ import { normalizeKagiSessionLink } from '../../../../../shared/browser-url' import { useAppStore } from '../../../store/index' import { Button } from '../../ui/button' import { Input } from '../../ui/input' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' export type KagiSessionLinkDraftState = { persisted: string @@ -26,6 +26,7 @@ export function resolveKagiSessionLinkDraftState( } export function KagiSessionLinkForm(): React.JSX.Element { + const t = useTranslate() const browserKagiSessionLink = useAppStore((s) => s.browserKagiSessionLink) const setBrowserKagiSessionLink = useAppStore((s) => s.setBrowserKagiSessionLink) const persistedDraft = browserKagiSessionLink ?? '' @@ -49,17 +50,14 @@ export function KagiSessionLinkForm(): React.JSX.Element { setBrowserKagiSessionLink(null) setDraftState(createKagiSessionLinkDraftState('')) toast.success( - translate( - 'auto.components.settings.KagiSessionLinkForm.9f741627a7', - 'Kagi session link cleared.' - ) + t('auto.components.settings.KagiSessionLinkForm.9f741627a7', 'Kagi session link cleared.') ) return } const normalized = normalizeKagiSessionLink(trimmed) if (!normalized) { toast.error( - translate( + t( 'auto.components.settings.KagiSessionLinkForm.0911d5fa4c', 'Enter a Kagi private session link from https://kagi.com/search?token=...' ) @@ -69,10 +67,7 @@ export function KagiSessionLinkForm(): React.JSX.Element { setBrowserKagiSessionLink(normalized) setDraftState(createKagiSessionLinkDraftState(normalized)) toast.success( - translate( - 'auto.components.settings.KagiSessionLinkForm.3e5b7c6c25', - 'Kagi session link saved.' - ) + t('auto.components.settings.KagiSessionLinkForm.3e5b7c6c25', 'Kagi session link saved.') ) } @@ -85,7 +80,7 @@ export function KagiSessionLinkForm(): React.JSX.Element { }} >

- {translate( + {t( 'auto.components.settings.KagiSessionLinkForm.81409d9362', 'Optional private session link for Kagi auth.' )} @@ -95,7 +90,7 @@ export function KagiSessionLinkForm(): React.JSX.Element { type="password" value={draft} onChange={(e) => setDraft(e.target.value)} - placeholder={translate( + placeholder={t( 'auto.components.settings.KagiSessionLinkForm.e383683485', 'https://kagi.com/search?token=...' )} @@ -103,14 +98,14 @@ export function KagiSessionLinkForm(): React.JSX.Element { autoCapitalize="none" autoCorrect="off" autoComplete="off" - aria-label={translate( + aria-label={t( 'auto.components.settings.KagiSessionLinkForm.ff450194cd', 'Kagi private session link' )} className="h-7 w-72 text-xs" /> {browserKagiSessionLink ? ( ) : null}

diff --git a/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsExperimentalSetting.tsx b/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsExperimentalSetting.tsx index e3826a9dc78..21f8d8476a9 100644 --- a/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsExperimentalSetting.tsx +++ b/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsExperimentalSetting.tsx @@ -1,5 +1,5 @@ import type { GlobalSettings } from '../../../../../../shared/global-settings-types' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' import { Label } from '../../../ui/label' import { SearchableSetting } from '../../section-layout/SearchableSetting' import { SettingsSwitch } from '../../form-controls/SettingsFormControls' @@ -14,7 +14,8 @@ export function BrowserExtensionsExperimentalSetting({ settings, updateSettings }: BrowserExtensionsExperimentalSettingProps): React.JSX.Element { - const entry = getExperimentalSearchEntry().browserExtensions + const t = useTranslate() + const entry = getExperimentalSearchEntry(t).browserExtensions const enabled = settings.experimentalBrowserExtensions === true return ( @@ -29,7 +30,7 @@ export function BrowserExtensionsExperimentalSetting({

- {translate( + {t( 'auto.components.settings.ExperimentalPane.browserExtensions.copy', 'Adds Settings › Browser › Extensions for local browser profiles.' )} @@ -37,7 +38,7 @@ export function BrowserExtensionsExperimentalSetting({

void onRemove: () => void }): React.JSX.Element { - const unsupported = describeUnsupportedBrowserExtensionFeatures(extension.permissions) + const t = useTranslate() + const unsupported = describeUnsupportedBrowserExtensionFeatures(extension.permissions, t) const sourceLabel = extension.source === 'unpacked' - ? translate('settings.browser.extensions.sourceUnpacked', 'Unpacked') - : translate('settings.browser.extensions.sourceWebStore', 'Chrome Web Store') + ? t('settings.browser.extensions.sourceUnpacked', 'Unpacked') + : t('settings.browser.extensions.sourceWebStore', 'Chrome Web Store') return (
{extension.iconDataUrl ? ( @@ -59,7 +60,7 @@ function ExtensionRow({

{extension.heldUpdateVersion ? (

- {translate( + {t( 'settings.browser.extensions.heldUpdate', 'Version {{version}} is waiting for more access.', { version: extension.heldUpdateVersion } @@ -69,7 +70,7 @@ function ExtensionRow({ {unsupported ?

{unsupported}

: null} {extension.loadError ? (

- {translate('settings.browser.extensions.loadError', 'Could not start: {{error}}', { + {t('settings.browser.extensions.loadError', 'Could not start: {{error}}', { error: extension.loadError })}

@@ -78,25 +79,21 @@ function ExtensionRow({
{extension.heldUpdateVersion ? ( ) : null} {extension.hasOptionsPage && extension.enabled ? ( ) : null} {extension.source === 'unpacked' ? ( @@ -107,13 +104,13 @@ function ExtensionRow({ size="icon-sm" onClick={onReload} disabled={busy} - aria-label={translate('settings.browser.extensions.reload', 'Reload from folder')} + aria-label={t('settings.browser.extensions.reload', 'Reload from folder')} > - {translate('settings.browser.extensions.reload', 'Reload from folder')} + {t('settings.browser.extensions.reload', 'Reload from folder')} ) : null} @@ -124,13 +121,13 @@ function ExtensionRow({ size="icon-sm" onClick={onRemove} disabled={busy} - aria-label={translate('settings.browser.extensions.remove', 'Remove')} + aria-label={t('settings.browser.extensions.remove', 'Remove')} > - {translate('settings.browser.extensions.remove', 'Remove')} + {t('settings.browser.extensions.remove', 'Remove')}
@@ -142,6 +139,7 @@ export function BrowserExtensionsSection({ profileId, profileLabel }: BrowserExtensionsSectionProps): React.JSX.Element { + const t = useTranslate() const confirm = useConfirmationDialog() const entry = getBrowserExtensionsSearchEntry() const [listing, setListing] = useState<{ @@ -199,11 +197,11 @@ export function BrowserExtensionsSection({ const remove = async (extension: BrowserExtensionListing): Promise => { const confirmed = await confirm({ - title: translate('settings.browser.extensions.removeTitle', 'Remove {{name}}?', { + title: t('settings.browser.extensions.removeTitle', 'Remove {{name}}?', { name: extension.name }), description: browserExtensionRemovalDescription(extension.source), - confirmLabel: translate('settings.browser.extensions.remove', 'Remove'), + confirmLabel: t('settings.browser.extensions.remove', 'Remove'), confirmVariant: 'destructive', surface: 'security' }) @@ -226,7 +224,7 @@ export function BrowserExtensionsSection({

- {translate( + {t( 'settings.browser.extensions.profileDescription', 'Extensions turned on here run in tabs that use the {{profile}} profile.', { profile: profileLabel } @@ -241,7 +239,7 @@ export function BrowserExtensionsSection({ onClick={() => void loadUnpacked()} > - {translate('settings.browser.extensions.loadUnpacked', 'Load unpacked…')} + {t('settings.browser.extensions.loadUnpacked', 'Load unpacked…')}

{active && result.extensions.length === 0 ? (

- {translate( + {t( 'settings.browser.extensions.empty', 'No extensions installed. Add one from the Chrome Web Store above.' )} diff --git a/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsWebStoreInstall.tsx b/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsWebStoreInstall.tsx index ea422df4c8f..5d477401f75 100644 --- a/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsWebStoreInstall.tsx +++ b/src/renderer/src/components/settings/browser/extensions/BrowserExtensionsWebStoreInstall.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { toast } from 'sonner' import { CHROME_WEB_STORE_HOME_URL } from '../../../../../../shared/browser/extensions/browser-extension-webstore' -import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' import { useAppStore } from '@/store/index' import { LoadingSpinner } from '../../../LoadingSpinner' import { Button } from '../../../ui/button' @@ -19,6 +19,7 @@ export function BrowserExtensionsWebStoreInstall({ disabled, onFinished }: BrowserExtensionsWebStoreInstallProps): React.JSX.Element { + const t = useTranslate() const [input, setInput] = useState('') const [installing, setInstalling] = useState(false) const openBrowserProfileTab = useAppStore((state) => state.openBrowserProfileTabInActiveWorkspace) @@ -34,7 +35,7 @@ export function BrowserExtensionsWebStoreInstall({ if (result.status === 'installed') { setInput('') toast.success( - translate('settings.browser.extensions.webStore.added', 'Added {{name}}', { + t('settings.browser.extensions.webStore.added', 'Added {{name}}', { name: result.name }) ) @@ -52,7 +53,7 @@ export function BrowserExtensionsWebStoreInstall({ closeSettingsPage() } else { toast.error( - translate( + t( 'settings.browser.extensions.webStore.openFailed', 'Open a workspace to browse the Chrome Web Store.' ) @@ -73,11 +74,11 @@ export function BrowserExtensionsWebStoreInstall({ value={input} onChange={(event) => setInput(event.target.value)} disabled={disabled || installing} - placeholder={translate( + placeholder={t( 'settings.browser.extensions.webStore.placeholder', 'Chrome Web Store link or extension ID' )} - aria-label={translate( + aria-label={t( 'settings.browser.extensions.webStore.inputLabel', 'Add from Chrome Web Store' )} @@ -94,8 +95,8 @@ export function BrowserExtensionsWebStoreInstall({ > {installing ? : null} {installing - ? translate('settings.browser.extensions.webStore.adding', 'Adding…') - : translate('settings.browser.extensions.webStore.add', 'Add')} + ? t('settings.browser.extensions.webStore.adding', 'Adding…') + : t('settings.browser.extensions.webStore.add', 'Add')}

) diff --git a/src/renderer/src/components/settings/browser/passwords/BrowserPasswordEntryDialog.tsx b/src/renderer/src/components/settings/browser/passwords/BrowserPasswordEntryDialog.tsx index e346aa37979..3f1b0e903d0 100644 --- a/src/renderer/src/components/settings/browser/passwords/BrowserPasswordEntryDialog.tsx +++ b/src/renderer/src/components/settings/browser/passwords/BrowserPasswordEntryDialog.tsx @@ -13,6 +13,7 @@ import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { translate } from '@/i18n/i18n' +import { useTranslate } from '@/i18n/use-translate' import type { BrowserPasswordEntryEditResult, BrowserPasswordEntryInput @@ -88,6 +89,7 @@ function BrowserPasswordEntryForm({ start: BrowserPasswordEntryFormStart onDone: (saved: boolean) => void }): React.JSX.Element { + const t = useTranslate() const [draft, setDraft] = useState( start.mode === 'edit' ? { site: start.site, username: start.username, password: start.password, note: start.note } @@ -137,11 +139,11 @@ function BrowserPasswordEntryForm({ {start.mode === 'edit' - ? translate('settings.browser.passwords.form.editTitle', 'Edit password') - : translate('settings.browser.passwords.form.addTitle', 'Add password')} + ? t('settings.browser.passwords.form.editTitle', 'Edit password') + : t('settings.browser.passwords.form.addTitle', 'Add password')} - {translate( + {t( 'settings.browser.passwords.form.description', 'Orca fills it when you pick it under a sign-in field on this site.' )} @@ -150,15 +152,12 @@ function BrowserPasswordEntryForm({
set('site')(event.target.value)} @@ -166,12 +165,12 @@ function BrowserPasswordEntryForm({
setShowPassword((shown) => !shown)} aria-label={ showPassword - ? translate('settings.browser.passwords.hide', 'Hide password') - : translate('settings.browser.passwords.show', 'Show password') + ? t('settings.browser.passwords.hide', 'Hide password') + : t('settings.browser.passwords.show', 'Show password') } > {showPassword ? : }

- {translate( + {t( 'settings.browser.passwords.form.currentHint', 'Save the password you use on this site today.' )} @@ -215,7 +214,7 @@ function BrowserPasswordEntryForm({ {showNote ? (