feat(i18n): localize hardcoded application copy (#40377)

Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot]
2026-08-04 16:56:03 +10:00
committed by GitHub
parent 6c3299103c
commit e85735028c
121 changed files with 4758 additions and 331 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ export type Locale =
| "th"
type RawDictionary = typeof appEn & typeof desktopEn
type Dictionary = i18n.Flatten<RawDictionary>
type Dictionary = Record<keyof i18n.Flatten<RawDictionary>, string>
const LOCALES: readonly Locale[] = [
"en",
+12 -9
View File
@@ -13,6 +13,7 @@ import {
ServerConnection,
useCommand,
useWslServers,
useLanguage,
} from "@opencode-ai/app"
import type { UpdaterState } from "@opencode-ai/app/updater"
import * as Sentry from "@sentry/solid"
@@ -21,7 +22,7 @@ import { createMemoryHistory, MemoryRouter, type BaseRouterProps } from "@solidj
import { createEffect, createMemo, createResource, createSignal, onCleanup, Show } from "solid-js"
import { render } from "solid-js/web"
import pkg from "../../package.json"
import { initI18n, t } from "./i18n"
import { t } from "./i18n"
import { initializationData } from "./initialization"
import { DesktopFirstLaunchOnboarding } from "./onboarding"
import { resetZoom, setPinchZoomEnabled, webviewZoom, zoomIn, zoomOut } from "./webview-zoom"
@@ -59,8 +60,6 @@ if (import.meta.env.VITE_SENTRY_DSN) {
})
}
void initI18n()
const [updaterState, setUpdaterState] = createSignal<UpdaterState>({ status: "disabled" })
void window.api.updater.subscribe(setUpdaterState)
@@ -175,14 +174,14 @@ const createPlatform = (windowState: DesktopWindowState): Platform => {
async openDirectoryPickerDialog(opts) {
return window.api.openDirectoryPicker({
multiple: opts?.multiple ?? false,
title: opts?.title ?? t("desktop.dialog.chooseFolder"),
title: opts?.title,
})
},
async openAttachmentPickerDialog(opts, onFile) {
const result = await window.api.openFilePicker({
multiple: opts?.multiple ?? false,
title: opts?.title ?? t("desktop.dialog.chooseFile"),
title: opts?.title,
defaultPath: opts?.defaultPath,
extensions: opts?.extensions ?? ACCEPTED_FILE_EXTENSIONS,
})
@@ -204,7 +203,7 @@ const createPlatform = (windowState: DesktopWindowState): Platform => {
async saveFilePickerDialog(opts) {
return window.api.saveFilePicker({
title: opts?.title ?? t("desktop.dialog.saveFile"),
title: opts?.title,
defaultPath: opts?.defaultPath,
})
},
@@ -376,6 +375,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
function App() {
const wslServers = useWslServers()
const language = useLanguage()
const ready = createMemo(
() => !defaultServer.loading && !sidecar.loading && !locale.loading && !wslServers.isLoading,
)
@@ -384,7 +384,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
const list: ServerConnection.Any[] = []
if (data) {
list.push({
displayName: "Local Server",
displayName: language.t("desktop.server.local"),
type: "sidecar",
variant: "base",
http: {
@@ -394,7 +394,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
},
})
}
list.push(...readyWslConnections(wslServers.data))
list.push(...readyWslConnections(wslServers.data, language.t("wsl.server.label")))
return list
})
const effectiveDefaultServer = createMemo(() =>
@@ -426,7 +426,10 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
return (
<PlatformProvider value={platform}>
<AppBaseProviders locale={locale.latest}>
<AppBaseProviders
locale={locale.latest}
onNativeTranslations={(bundle) => void window.api.setNativeTranslations(bundle).catch(() => undefined)}
>
<Show when={true}>{(_) => <App />}</Show>
</AppBaseProviders>
</PlatformProvider>
@@ -34,6 +34,10 @@ describe("WSL desktop connections", () => {
])
})
test("uses the renderer translation for the WSL connection label", () => {
expect(readyWslConnections(state("ready"), "Translated WSL")[0]?.label).toBe("Translated WSL")
})
test("does not block desktop startup on a configured WSL default", () => {
const key = "wsl:Debian"
expect(availableStartupServer(key, undefined)).toBe("sidecar")
@@ -1,12 +1,12 @@
import type { WslServersState } from "@opencode-ai/app/wsl/types"
export function readyWslConnections(state?: WslServersState) {
export function readyWslConnections(state?: WslServersState, label = "WSL") {
return (state?.servers ?? []).flatMap((item) => {
if (item.runtime.kind !== "ready") return []
return [
{
displayName: item.config.distro,
label: "WSL",
label,
type: "sidecar" as const,
variant: "wsl" as const,
distro: item.config.distro,