Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<GlobalSettings, 'openLinksInApp' | 'openLinksInAppModifierInverts'>
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/components/settings/BrowserPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { afterEach, describe, expect, it } from 'vitest'

import { i18n } from '@/i18n/i18n'
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
// 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
)
}
})
})
88 changes: 83 additions & 5 deletions src/renderer/src/components/settings/browser-search.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { describe, expect, it } from 'vitest'
import { getBrowserLinkRoutingDescription, getBrowserPaneSearchEntries } from './browser-search'
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,
getLinkRoutingModifierDescription,
getLinkRoutingModifierTitle
} from './browser-link-routing-modifier-copy'
} from './browser-link-routing-copy'

describe('browser settings search copy', () => {
it('uses macOS shortcut keywords for Link Routing search metadata', () => {
it('uses macOS shortcut symbols for Link Routing copy and search metadata', () => {
expect(getBrowserLinkRoutingShortcutLabel({ isMac: true })).toBe('⇧⌘-click')

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'
)
Expand All @@ -20,7 +33,14 @@ describe('browser settings search copy', () => {
expect(defaultZoomEntry?.keywords).toContain('zoom')
})

it('uses Ctrl shortcut keywords for Link Routing search metadata off macOS', () => {
it('uses Ctrl shortcut text for Link Routing copy and search metadata off macOS', () => {
expect(getBrowserLinkRoutingShortcutLabel({ isMac: false })).toBe('Shift+Ctrl+click')

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'
)
Expand Down Expand Up @@ -102,3 +122,61 @@ describe('browser link routing modifier copy', () => {
expect(entry?.keywords).toContain(getLinkRoutingModifierTitle(true))
})
})

// 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.BrowserLinkRoutingSetting.description'
const BASE_KEY = 'auto.components.settings.BrowserLinkRoutingSetting.descriptionBase'

beforeEach(async () => {
await i18n.changeLanguage('en')
})

it('renders the Korean copy with the shortcut interpolated', async () => {
const koCopy = (
ko.auto.components.settings.BrowserLinkRoutingSetting as unknown as Record<string, string>
)['description']
expect(koCopy).toBeTruthy()
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('{{shortcut}}', '⇧⌘-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('renders the Korean copy for the invert-on variant', async () => {
const koBase = (
ko.auto.components.settings.BrowserLinkRoutingSetting as unknown as Record<string, string>
)['descriptionBase']
expect(koBase).toBeTruthy()

i18n.addResourceBundle('ko', 'translation', ko, true, true)
await i18n.changeLanguage('ko')

const description = getBrowserLinkRoutingDescription({ isMac: true }, true)
expect(description).toBe(koBase)
// Fails when the invert-on branch regresses to a hardcoded English literal.
expect(description).not.toContain("Orca's built-in browser")
})

it('uses the catalog key rather than an inline literal', () => {
expect(i18n.exists(KEY)).toBe(true)
expect(i18n.exists(BASE_KEY)).toBe(true)
})
})
16 changes: 2 additions & 14 deletions src/renderer/src/components/settings/browser-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -16,19 +17,6 @@ function getDefaultBrowserShortcutPlatform(): BrowserShortcutPlatform {
}
}

// 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.
export function getBrowserLinkRoutingDescription(
platform: BrowserShortcutPlatform = getDefaultBrowserShortcutPlatform(),
modifierInverts = false
): string {
const base =
"Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor."
return modifierInverts
? base
: `${base} ${platform.isMac ? '⇧⌘-click' : 'Shift+Ctrl+click'} always uses your system browser.`
}

export function getBrowserPaneSearchEntries(
platform: BrowserShortcutPlatform = getDefaultBrowserShortcutPlatform()
): SettingsSearchEntry[] {
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9685,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",
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -9651,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",
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -9651,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",
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/i18n/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -9651,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",
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -9651,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",
Expand Down