From dde81df1f4395d8ddcad86124cf3f2224d1f2dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sun, 19 Jul 2026 17:09:36 +0900 Subject: [PATCH 1/5] fix(i18n): localize the Link Routing description in browser settings The copy is built with a template literal (it interpolates the platform shortcut label), so the localization codemod never wrapped it in translate() and it rendered hard-coded English in every locale. Wrap it with {{value0}} interpolation and add catalog entries for all locales. --- src/renderer/src/components/settings/browser-search.ts | 6 +++++- src/renderer/src/i18n/locales/en.json | 3 ++- src/renderer/src/i18n/locales/es.json | 3 ++- src/renderer/src/i18n/locales/ja.json | 3 ++- src/renderer/src/i18n/locales/ko.json | 3 ++- src/renderer/src/i18n/locales/zh.json | 3 ++- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/renderer/src/components/settings/browser-search.ts b/src/renderer/src/components/settings/browser-search.ts index 4cd99f7fa77a..a1cb64a07ae1 100644 --- a/src/renderer/src/components/settings/browser-search.ts +++ b/src/renderer/src/components/settings/browser-search.ts @@ -17,7 +17,11 @@ export function getBrowserLinkRoutingShortcutLabel(platform: BrowserShortcutPlat } export function getBrowserLinkRoutingDescription(platform: BrowserShortcutPlatform): string { - return `Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. ${getBrowserLinkRoutingShortcutLabel(platform)} always uses your system browser.` + return translate( + 'auto.components.settings.browser.search.904ce58440', + "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{value0}} always uses your system browser.", + { value0: getBrowserLinkRoutingShortcutLabel(platform) } + ) } export function getBrowserPaneSearchEntries( diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 1575481e14b4..dcc106b17701 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -7475,7 +7475,8 @@ "a942905148": "URL opened when creating a new browser tab. Leave empty to open a blank tab.", "c3903322d2": "Default Home Page", "19ea5607cf": "Localhost Worktree Labels", - "4e0fdf0a3f": "Open workspace ports as worktree-specific Orca localhost URLs so browser tabs are easier to tell apart." + "4e0fdf0a3f": "Open workspace ports as worktree-specific Orca localhost URLs so browser tabs are easier to tell apart.", + "904ce58440": "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{value0}} always uses your system browser." }, "use": { "search": { diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 3a5311cb76ce..4a31b3b8adb1 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -7415,7 +7415,8 @@ "a942905148": "URL abierta al crear una nueva pestaña del navegador. Déjelo vacío para abrir una pestaña en blanco.", "c3903322d2": "Página de inicio predeterminada", "19ea5607cf": "Etiquetas de localhost para worktrees", - "4e0fdf0a3f": "Abre los puertos del workspace como URL localhost de Orca específicas del worktree para que las pestañas del navegador sean más fáciles de distinguir." + "4e0fdf0a3f": "Abre los puertos del workspace como URL localhost de Orca específicas del worktree para que las pestañas del navegador sean más fáciles de distinguir.", + "904ce58440": "Abre los enlaces http(s) del terminal, Markdown y el editor en el navegador integrado de Orca. {{value0}} siempre usa el navegador del sistema." }, "use": { "search": { diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 34481f1ac18b..1815f3dc2e4f 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -7437,7 +7437,8 @@ "a942905148": "新規ブラウザ タブを作成するときに開かれる URL。空白のタブを開くには、空白のままにします。", "c3903322d2": "デフォルトのホームページ", "19ea5607cf": "ローカルホストのワークツリーのラベル", - "4e0fdf0a3f": "ワークスペース ポートをワークツリー固有の Orca localhost URL として開くと、ブラウザーのタブを区別しやすくなります。" + "4e0fdf0a3f": "ワークスペース ポートをワークツリー固有の Orca localhost URL として開くと、ブラウザーのタブを区別しやすくなります。", + "904ce58440": "ターミナル、Markdown、エディターの http(s) リンクを Orca の組み込みブラウザで開きます。{{value0}} は常にシステム ブラウザを使用します。" }, "use": { "search": { diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index e8d8ba493199..d8ec6833253a 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -7400,7 +7400,8 @@ "a942905148": "새 브라우저 탭을 만들 때 열리는 URL입니다. 빈 탭을 열려면 비워 두세요.", "c3903322d2": "기본 홈 페이지", "19ea5607cf": "로컬호스트 작업 트리 레이블", - "4e0fdf0a3f": "브라우저 탭을 더 쉽게 구분할 수 있도록 작업 트리별 Orca 로컬 호스트 URL로 워크스페이스 포트를 엽니다." + "4e0fdf0a3f": "브라우저 탭을 더 쉽게 구분할 수 있도록 작업 트리별 Orca 로컬 호스트 URL로 워크스페이스 포트를 엽니다.", + "904ce58440": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다. {{value0}}은 항상 시스템 브라우저를 사용합니다." }, "use": { "search": { diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 2ec328ba2e15..7799d12379c4 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -7400,7 +7400,8 @@ "a942905148": "创建新浏览器选项卡时打开的 URL。留空以打开空白选项卡。", "c3903322d2": "默认主页", "19ea5607cf": "本地主机工作区标签", - "4e0fdf0a3f": "将工作区端口打开为特定于工作区的 Orca localhost URL,便于区分浏览器标签页。" + "4e0fdf0a3f": "将工作区端口打开为特定于工作区的 Orca localhost URL,便于区分浏览器标签页。", + "904ce58440": "在 Orca 内置浏览器中打开来自终端、Markdown 和编辑器的 http(s) 链接。{{value0}} 始终使用系统浏览器。" }, "use": { "search": { From 1093c31d51be2a3a827533875a3c54719118226f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sun, 19 Jul 2026 21:08:27 +0900 Subject: [PATCH 2/5] fix(i18n): use action-oriented Korean copy for the Link Routing shortcut hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shortcut label read as the sentence's actor and a hard-coded particle could mismatch other labels; switch to the {{value0}}을(를) 누르면 form, matching the action-oriented style of the existing Korean catalog. --- src/renderer/src/i18n/locales/ko.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index d8ec6833253a..5302f61b7943 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -7401,7 +7401,7 @@ "c3903322d2": "기본 홈 페이지", "19ea5607cf": "로컬호스트 작업 트리 레이블", "4e0fdf0a3f": "브라우저 탭을 더 쉽게 구분할 수 있도록 작업 트리별 Orca 로컬 호스트 URL로 워크스페이스 포트를 엽니다.", - "904ce58440": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다. {{value0}}은 항상 시스템 브라우저를 사용합니다." + "904ce58440": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다. {{value0}}을(를) 누르면 항상 시스템 브라우저를 사용합니다." }, "use": { "search": { From e32b9498b35a8372b8a87e7c92f226c778f1930c Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 26 Jul 2026 03:11:35 -0700 Subject: [PATCH 3/5] test(i18n): pin Link Routing description localization across locales Existing browser-search coverage only asserted the English copy, which was byte-identical before and after the fix. Add a locale-switching test that fails on main for every non-English catalog and pins the shortcut label per platform. Original patch by @m-a-king. Co-authored-by: Orca --- .../browser-link-routing-localization.test.ts | 55 +++++++++++++++++++ .../settings/browser-search.test.ts | 3 + 2 files changed, 58 insertions(+) create mode 100644 src/renderer/src/components/settings/browser-link-routing-localization.test.ts diff --git a/src/renderer/src/components/settings/browser-link-routing-localization.test.ts b/src/renderer/src/components/settings/browser-link-routing-localization.test.ts new file mode 100644 index 000000000000..f8eb6d0767fb --- /dev/null +++ b/src/renderer/src/components/settings/browser-link-routing-localization.test.ts @@ -0,0 +1,55 @@ +import { afterEach, describe, expect, it } from 'vitest' + +import { i18n } from '@/i18n/i18n' +import { getBrowserLinkRoutingDescription } from './browser-search' + +// The Link Routing description was a bare template literal, so it stayed English in every +// locale while its own title and the rest of the pane translated. It carries the platform +// shortcut label, so each locale must interpolate it rather than embed a hardcoded modifier. +const NON_ENGLISH_LOCALES = ['es', 'ja', 'ko', 'zh'] as const + +const SHORTCUT_BY_PLATFORM = { + mac: '⇧⌘-click', + other: 'Shift+Ctrl+click' +} as const + +describe('Link Routing description localization', () => { + afterEach(async () => { + await i18n.changeLanguage('en') + }) + + it('translates the description in every non-English locale on both platforms', async () => { + const english = { + mac: getBrowserLinkRoutingDescription({ isMac: true }), + other: getBrowserLinkRoutingDescription({ isMac: false }) + } + + for (const locale of NON_ENGLISH_LOCALES) { + await i18n.changeLanguage(locale) + + for (const [platform, shortcut] of Object.entries(SHORTCUT_BY_PLATFORM)) { + const description = getBrowserLinkRoutingDescription({ isMac: platform === 'mac' }) + + expect(description, `${locale}/${platform} fell back to English`).not.toBe( + english[platform as keyof typeof english] + ) + // The label is a key symbol, not prose: it stays literal in every locale. + expect(description, `${locale}/${platform} lost the shortcut label`).toContain(shortcut) + expect(description, `${locale}/${platform} leaked a placeholder`).not.toMatch(/\{\{.+?\}\}/) + } + } + }) + + it('keeps each platform label out of the other platform copy', async () => { + for (const locale of ['en', ...NON_ENGLISH_LOCALES]) { + await i18n.changeLanguage(locale) + + expect(getBrowserLinkRoutingDescription({ isMac: true })).not.toContain( + SHORTCUT_BY_PLATFORM.other + ) + expect(getBrowserLinkRoutingDescription({ isMac: false })).not.toContain( + SHORTCUT_BY_PLATFORM.mac + ) + } + }) +}) diff --git a/src/renderer/src/components/settings/browser-search.test.ts b/src/renderer/src/components/settings/browser-search.test.ts index 5d6e4255047a..a61d80b641e2 100644 --- a/src/renderer/src/components/settings/browser-search.test.ts +++ b/src/renderer/src/components/settings/browser-search.test.ts @@ -12,6 +12,8 @@ describe('browser settings search copy', () => { const description = getBrowserLinkRoutingDescription({ isMac: true }) expect(description).toContain('⇧⌘-click') expect(description).not.toContain('Cmd/Ctrl') + // The copy is translated: a leaked `{{...}}` means the interpolation name drifted from the catalog. + expect(description).not.toMatch(/\{\{.+?\}\}/) const linkRoutingEntry = getBrowserPaneSearchEntries({ isMac: true }).find( (entry) => entry.title === 'Link Routing' @@ -32,6 +34,7 @@ describe('browser settings search copy', () => { const description = getBrowserLinkRoutingDescription({ isMac: false }) expect(description).toContain('Shift+Ctrl+click') expect(description).not.toContain('Cmd/Ctrl') + expect(description).not.toMatch(/\{\{.+?\}\}/) const linkRoutingEntry = getBrowserPaneSearchEntries({ isMac: false }).find( (entry) => entry.title === 'Link Routing' From 5884960445c2871b25c0ed91c5e834fa9f947fe5 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 26 Jul 2026 04:03:54 -0700 Subject: [PATCH 4/5] test(i18n): prove Link Routing description actually localizes The existing assertion (no leaked {{...}}) cannot fail on main: the hardcoded English literal has no placeholder either. Switch to ko and assert the rendered copy matches the catalog entry. Co-authored-by: Orca --- .../settings/browser-search.test.ts | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/components/settings/browser-search.test.ts b/src/renderer/src/components/settings/browser-search.test.ts index a61d80b641e2..bd7dc3252f7d 100644 --- a/src/renderer/src/components/settings/browser-search.test.ts +++ b/src/renderer/src/components/settings/browser-search.test.ts @@ -1,4 +1,7 @@ -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it } from 'vitest' + +import ko from '@/i18n/locales/ko.json' +import { i18n } from '@/i18n/i18n' import { getBrowserLinkRoutingDescription, getBrowserLinkRoutingShortcutLabel, @@ -44,3 +47,46 @@ describe('browser settings search copy', () => { expect(linkRoutingEntry?.keywords).not.toContain('cmd') }) }) + +// The bug this file guards: the Link Routing description was a bare template +// literal, so it stayed English in every locale. Asserting only "no {{...}} leaked" +// cannot catch that — the English literal has no placeholder either. +describe('Link Routing description localization', () => { + const KEY = 'auto.components.settings.browser.search.904ce58440' + + beforeEach(async () => { + await i18n.changeLanguage('en') + }) + + it('renders the Korean copy with the shortcut interpolated', async () => { + const koCopy = ( + ko.auto.components.settings.browser.search as unknown as Record + )['904ce58440'] + expect(koCopy).toBeTruthy() + expect(koCopy).toContain('{{value0}}') + + i18n.addResourceBundle('ko', 'translation', ko, true, true) + await i18n.changeLanguage('ko') + + const description = getBrowserLinkRoutingDescription({ isMac: true }) + expect(description).toBe(koCopy.replace('{{value0}}', '⇧⌘-click')) + expect(description).not.toMatch(/\{\{.+?\}\}/) + // Fails when the copy is a hardcoded English literal. + expect(description).not.toContain("Orca's built-in browser") + + // The entry title is localized too, so match on the description instead. + const entry = getBrowserPaneSearchEntries({ isMac: true }).find( + (item) => item.description === description + ) + expect(entry).toBeDefined() + + await i18n.changeLanguage('en') + expect(getBrowserLinkRoutingDescription({ isMac: true })).toContain( + "Orca's built-in browser" + ) + }) + + it('uses the catalog key rather than an inline literal', () => { + expect(i18n.exists(KEY)).toBe(true) + }) +}) From 73760e78ad87d2c7ec662f91114f8523a26fbd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Fri, 31 Jul 2026 07:12:18 +0900 Subject: [PATCH 5/5] refactor(i18n): move Link Routing copy into the #10991 copy-module pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The interim state mixed a codemod hash key with a hand-named key inside browser-search.ts — forced by a hash collision: the invert-on base sentence is byte-identical to the template head that produced the full-copy key's hash. Align with the copy-module pattern #10991 introduced instead: rename browser-link-routing-modifier-copy.ts to browser-link-routing-copy.ts (it now carries all Link Routing copy), re-key both description variants as hand-named entries (BrowserLinkRoutingSetting.description / .descriptionBase), and use a named {{shortcut}} placeholder to match the module's convention. Catalog values move verbatim across all five locales, so the reviewed translations are unchanged. Platform detection stays in browser-search.ts — the copy module keeps its resolved-arguments-only contract, and the description's unused default-platform argument is dropped. --- .../BrowserLinkRoutingModifierSetting.tsx | 2 +- .../src/components/settings/BrowserPane.tsx | 3 +- ...r-copy.ts => browser-link-routing-copy.ts} | 25 ++++++++++++++++ .../browser-link-routing-localization.test.ts | 2 +- .../settings/browser-search.test.ts | 23 +++++++------- .../src/components/settings/browser-search.ts | 30 ++----------------- src/renderer/src/i18n/locales/en.json | 8 +++-- src/renderer/src/i18n/locales/es.json | 8 +++-- src/renderer/src/i18n/locales/ja.json | 8 +++-- src/renderer/src/i18n/locales/ko.json | 8 +++-- src/renderer/src/i18n/locales/zh.json | 8 +++-- 11 files changed, 67 insertions(+), 58 deletions(-) rename src/renderer/src/components/settings/{browser-link-routing-modifier-copy.ts => browser-link-routing-copy.ts} (58%) diff --git a/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx b/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx index aeb8f4151d8d..b0c55e87204d 100644 --- a/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx +++ b/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx @@ -4,7 +4,7 @@ import { SettingsSwitchRow } from './SettingsFormControls' import { getLinkRoutingModifierDescription, getLinkRoutingModifierTitle -} from './browser-link-routing-modifier-copy' +} from './browser-link-routing-copy' type BrowserLinkRoutingModifierSettingProps = { settings: Pick diff --git a/src/renderer/src/components/settings/BrowserPane.tsx b/src/renderer/src/components/settings/BrowserPane.tsx index d67aaf7ef70e..5c8088cc9bbf 100644 --- a/src/renderer/src/components/settings/BrowserPane.tsx +++ b/src/renderer/src/components/settings/BrowserPane.tsx @@ -2,7 +2,8 @@ import { useCallback, useEffect, useMemo, useRef, useState, type MutableRefObjec import type { GlobalSettings } from '../../../../shared/types' import { useAppStore } from '../../store' import { matchesSettingsSearch } from './settings-search' -import { getBrowserPaneSearchEntries, getBrowserLinkRoutingDescription } from './browser-search' +import { getBrowserPaneSearchEntries } from './browser-search' +import { getBrowserLinkRoutingDescription } from './browser-link-routing-copy' import { getBrowserUsePaneSearchEntries } from './browser-use-search' import { getBrowserPaneCombinedSearchEntries } from './browser-pane-search' import { BrowserHomePageSetting } from './BrowserHomePageSetting' diff --git a/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts b/src/renderer/src/components/settings/browser-link-routing-copy.ts similarity index 58% rename from src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts rename to src/renderer/src/components/settings/browser-link-routing-copy.ts index 1151d3e70e13..5a4d5bac2d65 100644 --- a/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts +++ b/src/renderer/src/components/settings/browser-link-routing-copy.ts @@ -1,5 +1,30 @@ import { translate } from '@/i18n/i18n' +export function getBrowserLinkRoutingShortcutLabel(platform: { isMac: boolean }): string { + return platform.isMac ? '⇧⌘-click' : 'Shift+Ctrl+click' +} + +// Why: "always" stops being true once inverting is on, so only then does the nested +// row take over the chord sentence — with it off this reads exactly as it always has. +// Each variant is a complete catalog entry: stitched suffixes break in locales whose +// sentence joining differs from English. +export function getBrowserLinkRoutingDescription( + platform: { isMac: boolean }, + modifierInverts = false +): string { + if (modifierInverts) { + return translate( + 'auto.components.settings.BrowserLinkRoutingSetting.descriptionBase', + "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor." + ) + } + return translate( + 'auto.components.settings.BrowserLinkRoutingSetting.description', + "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{shortcut}} always uses your system browser.", + { shortcut: getBrowserLinkRoutingShortcutLabel(platform) } + ) +} + /** * Title and description both name the destination the modifier reaches, which is * the opposite of wherever Link Routing points. Kept out of the component so the diff --git a/src/renderer/src/components/settings/browser-link-routing-localization.test.ts b/src/renderer/src/components/settings/browser-link-routing-localization.test.ts index f8eb6d0767fb..613f8e0de1cf 100644 --- a/src/renderer/src/components/settings/browser-link-routing-localization.test.ts +++ b/src/renderer/src/components/settings/browser-link-routing-localization.test.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it } from 'vitest' import { i18n } from '@/i18n/i18n' -import { getBrowserLinkRoutingDescription } from './browser-search' +import { getBrowserLinkRoutingDescription } from './browser-link-routing-copy' // The Link Routing description was a bare template literal, so it stayed English in every // locale while its own title and the rest of the pane translated. It carries the platform diff --git a/src/renderer/src/components/settings/browser-search.test.ts b/src/renderer/src/components/settings/browser-search.test.ts index 2915392e2340..0df9173b28d3 100644 --- a/src/renderer/src/components/settings/browser-search.test.ts +++ b/src/renderer/src/components/settings/browser-search.test.ts @@ -2,15 +2,13 @@ import { beforeEach, describe, expect, it } from 'vitest' import ko from '@/i18n/locales/ko.json' import { i18n } from '@/i18n/i18n' +import { getBrowserPaneSearchEntries } from './browser-search' import { getBrowserLinkRoutingDescription, getBrowserLinkRoutingShortcutLabel, - getBrowserPaneSearchEntries -} from './browser-search' -import { getLinkRoutingModifierDescription, getLinkRoutingModifierTitle -} from './browser-link-routing-modifier-copy' +} from './browser-link-routing-copy' describe('browser settings search copy', () => { it('uses macOS shortcut symbols for Link Routing copy and search metadata', () => { @@ -129,7 +127,8 @@ describe('browser link routing modifier copy', () => { // literal, so it stayed English in every locale. Asserting only "no {{...}} leaked" // cannot catch that — the English literal has no placeholder either. describe('Link Routing description localization', () => { - const KEY = 'auto.components.settings.browser.search.904ce58440' + const KEY = 'auto.components.settings.BrowserLinkRoutingSetting.description' + const BASE_KEY = 'auto.components.settings.BrowserLinkRoutingSetting.descriptionBase' beforeEach(async () => { await i18n.changeLanguage('en') @@ -137,16 +136,16 @@ describe('Link Routing description localization', () => { it('renders the Korean copy with the shortcut interpolated', async () => { const koCopy = ( - ko.auto.components.settings.browser.search as unknown as Record - )['904ce58440'] + ko.auto.components.settings.BrowserLinkRoutingSetting as unknown as Record + )['description'] expect(koCopy).toBeTruthy() - expect(koCopy).toContain('{{value0}}') + expect(koCopy).toContain('{{shortcut}}') i18n.addResourceBundle('ko', 'translation', ko, true, true) await i18n.changeLanguage('ko') const description = getBrowserLinkRoutingDescription({ isMac: true }) - expect(description).toBe(koCopy.replace('{{value0}}', '⇧⌘-click')) + expect(description).toBe(koCopy.replace('{{shortcut}}', '⇧⌘-click')) expect(description).not.toMatch(/\{\{.+?\}\}/) // Fails when the copy is a hardcoded English literal. expect(description).not.toContain("Orca's built-in browser") @@ -163,8 +162,8 @@ describe('Link Routing description localization', () => { it('renders the Korean copy for the invert-on variant', async () => { const koBase = ( - ko.auto.components.settings.browser.search as unknown as Record - )['linkRoutingBase'] + ko.auto.components.settings.BrowserLinkRoutingSetting as unknown as Record + )['descriptionBase'] expect(koBase).toBeTruthy() i18n.addResourceBundle('ko', 'translation', ko, true, true) @@ -178,6 +177,6 @@ describe('Link Routing description localization', () => { it('uses the catalog key rather than an inline literal', () => { expect(i18n.exists(KEY)).toBe(true) - expect(i18n.exists('auto.components.settings.browser.search.linkRoutingBase')).toBe(true) + expect(i18n.exists(BASE_KEY)).toBe(true) }) }) diff --git a/src/renderer/src/components/settings/browser-search.ts b/src/renderer/src/components/settings/browser-search.ts index 06f0f1a4b43a..67f5506de42c 100644 --- a/src/renderer/src/components/settings/browser-search.ts +++ b/src/renderer/src/components/settings/browser-search.ts @@ -2,9 +2,10 @@ import type { SettingsSearchEntry } from './settings-search' import { translate } from '@/i18n/i18n' import { translateSearchKeyword } from './settings-search-keywords' import { + getBrowserLinkRoutingDescription, getLinkRoutingModifierDescription, getLinkRoutingModifierTitle -} from './browser-link-routing-modifier-copy' +} from './browser-link-routing-copy' type BrowserShortcutPlatform = { isMac: boolean @@ -16,33 +17,6 @@ function getDefaultBrowserShortcutPlatform(): BrowserShortcutPlatform { } } -export function getBrowserLinkRoutingShortcutLabel(platform: BrowserShortcutPlatform): string { - return platform.isMac ? '⇧⌘-click' : 'Shift+Ctrl+click' -} - -// Why: "always" stops being true once inverting is on, so only then does the nested -// row take over the chord sentence — with it off this reads exactly as it always has. -// Each variant is a complete catalog entry — stitching a translated suffix onto a -// translated base breaks in locales whose sentence order differs from English. -export function getBrowserLinkRoutingDescription( - platform: BrowserShortcutPlatform = getDefaultBrowserShortcutPlatform(), - modifierInverts = false -): string { - if (modifierInverts) { - // Why: hand-named key — the codemod hash of this sentence collides with - // 904ce58440, whose source text was this same sentence as the template head. - return translate( - 'auto.components.settings.browser.search.linkRoutingBase', - "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor." - ) - } - return translate( - 'auto.components.settings.browser.search.904ce58440', - "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{value0}} always uses your system browser.", - { value0: getBrowserLinkRoutingShortcutLabel(platform) } - ) -} - export function getBrowserPaneSearchEntries( platform: BrowserShortcutPlatform = getDefaultBrowserShortcutPlatform() ): SettingsSearchEntry[] { diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 3136ec880669..dab15537c25c 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -7842,9 +7842,7 @@ "a942905148": "URL opened when creating a new browser tab. Leave empty to open a blank tab.", "c3903322d2": "Default Home Page", "19ea5607cf": "Localhost Worktree Labels", - "4e0fdf0a3f": "Open workspace ports as worktree-specific Orca localhost URLs so browser tabs are easier to tell apart.", - "904ce58440": "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{value0}} always uses your system browser.", - "linkRoutingBase": "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor." + "4e0fdf0a3f": "Open workspace ports as worktree-specific Orca localhost URLs so browser tabs are easier to tell apart." }, "use": { "search": { @@ -9687,6 +9685,10 @@ "unpackedHelp": "Development builds must be updated from their source checkout.", "legacyHelp": "Update this server manually once to enable remote updates." }, + "BrowserLinkRoutingSetting": { + "description": "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. {{shortcut}} always uses your system browser.", + "descriptionBase": "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor." + }, "BrowserLinkRoutingModifierSetting": { "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 22954c3402d3..5b886a20857d 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -7773,9 +7773,7 @@ "a942905148": "URL abierta al crear una nueva pestaña del navegador. Déjelo vacío para abrir una pestaña en blanco.", "c3903322d2": "Página de inicio predeterminada", "19ea5607cf": "Etiquetas de localhost para worktrees", - "4e0fdf0a3f": "Abre los puertos del workspace como URL localhost de Orca específicas del worktree para que las pestañas del navegador sean más fáciles de distinguir.", - "linkRoutingBase": "Abre los enlaces http(s) del terminal, Markdown y el editor en el navegador integrado de Orca.", - "904ce58440": "Abre los enlaces http(s) del terminal, Markdown y el editor en el navegador integrado de Orca. {{value0}} siempre usa el navegador del sistema." + "4e0fdf0a3f": "Abre los puertos del workspace como URL localhost de Orca específicas del worktree para que las pestañas del navegador sean más fáciles de distinguir." }, "use": { "search": { @@ -9653,6 +9651,10 @@ "unpackedHelp": "Development builds must be updated from their source checkout.", "legacyHelp": "Update this server manually once to enable remote updates." }, + "BrowserLinkRoutingSetting": { + "description": "Abre los enlaces http(s) del terminal, Markdown y el editor en el navegador integrado de Orca. {{shortcut}} siempre usa el navegador del sistema.", + "descriptionBase": "Abre los enlaces http(s) del terminal, Markdown y el editor en el navegador integrado de Orca." + }, "BrowserLinkRoutingModifierSetting": { "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 501875af7a6a..25c60820949a 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -7795,9 +7795,7 @@ "a942905148": "新規ブラウザ タブを作成するときに開かれる URL。空白のタブを開くには、空白のままにします。", "c3903322d2": "デフォルトのホームページ", "19ea5607cf": "ローカルホストのワークツリーのラベル", - "4e0fdf0a3f": "ワークスペース ポートをワークツリー固有の Orca localhost URL として開くと、ブラウザーのタブを区別しやすくなります。", - "linkRoutingBase": "ターミナル、Markdown、エディターの http(s) リンクを Orca の組み込みブラウザで開きます。", - "904ce58440": "ターミナル、Markdown、エディターの http(s) リンクを Orca の組み込みブラウザで開きます。{{value0}} は常にシステム ブラウザを使用します。" + "4e0fdf0a3f": "ワークスペース ポートをワークツリー固有の Orca localhost URL として開くと、ブラウザーのタブを区別しやすくなります。" }, "use": { "search": { @@ -9653,6 +9651,10 @@ "unpackedHelp": "開発ビルドはソースチェックアウトから更新する必要があります。", "legacyHelp": "リモート更新を有効にするには、このサーバーを手動で一度更新してください。" }, + "BrowserLinkRoutingSetting": { + "description": "ターミナル、Markdown、エディターの http(s) リンクを Orca の組み込みブラウザで開きます。{{shortcut}} は常にシステム ブラウザを使用します。", + "descriptionBase": "ターミナル、Markdown、エディターの http(s) リンクを Orca の組み込みブラウザで開きます。" + }, "BrowserLinkRoutingModifierSetting": { "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index f4f12fa46c68..95eef890f570 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -7758,9 +7758,7 @@ "a942905148": "새 브라우저 탭을 만들 때 열리는 URL입니다. 빈 탭을 열려면 비워 두세요.", "c3903322d2": "기본 홈 페이지", "19ea5607cf": "로컬호스트 작업 트리 레이블", - "4e0fdf0a3f": "브라우저 탭을 더 쉽게 구분할 수 있도록 작업 트리별 Orca 로컬 호스트 URL로 워크스페이스 포트를 엽니다.", - "linkRoutingBase": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다.", - "904ce58440": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다. {{value0}}을(를) 누르면 항상 시스템 브라우저를 사용합니다." + "4e0fdf0a3f": "브라우저 탭을 더 쉽게 구분할 수 있도록 작업 트리별 Orca 로컬 호스트 URL로 워크스페이스 포트를 엽니다." }, "use": { "search": { @@ -9653,6 +9651,10 @@ "unpackedHelp": "개발 빌드는 소스 체크아웃에서 업데이트해야 합니다.", "legacyHelp": "원격 업데이트를 활성화하려면 이 서버를 수동으로 한 번 업데이트하세요." }, + "BrowserLinkRoutingSetting": { + "description": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다. {{shortcut}}을(를) 누르면 항상 시스템 브라우저를 사용합니다.", + "descriptionBase": "터미널, Markdown, 편집기의 http(s) 링크를 Orca 내장 브라우저에서 엽니다." + }, "BrowserLinkRoutingModifierSetting": { "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 57609c9f13b9..f0f620efb364 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -7758,9 +7758,7 @@ "a942905148": "创建新浏览器选项卡时打开的 URL。留空以打开空白选项卡。", "c3903322d2": "默认主页", "19ea5607cf": "本地主机工作区标签", - "4e0fdf0a3f": "将工作区端口打开为特定于工作区的 Orca localhost URL,便于区分浏览器标签页。", - "linkRoutingBase": "在 Orca 内置浏览器中打开来自终端、Markdown 和编辑器的 http(s) 链接。", - "904ce58440": "在 Orca 内置浏览器中打开来自终端、Markdown 和编辑器的 http(s) 链接。{{value0}} 始终使用系统浏览器。" + "4e0fdf0a3f": "将工作区端口打开为特定于工作区的 Orca localhost URL,便于区分浏览器标签页。" }, "use": { "search": { @@ -9653,6 +9651,10 @@ "unpackedHelp": "开发版本必须从其源代码检出进行更新。", "legacyHelp": "手动更新此服务器一次以启用远程更新。" }, + "BrowserLinkRoutingSetting": { + "description": "在 Orca 内置浏览器中打开来自终端、Markdown 和编辑器的 http(s) 链接。{{shortcut}} 始终使用系统浏览器。", + "descriptionBase": "在 Orca 内置浏览器中打开来自终端、Markdown 和编辑器的 http(s) 链接。" + }, "BrowserLinkRoutingModifierSetting": { "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca",