summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-20 10:20:43 -0600
committerAdam <[email protected]>2026-01-20 17:58:06 -0600
commitbe493e8be045f25f38e619b79730f437839752a8 (patch)
treecaed9ba4dfac65a4b372df4569cbea74634f1c09 /packages/app/src
parent7e8e4d9938fc473e187a80e0b8012b0d9bed2dc6 (diff)
downloadopencode-be493e8be045f25f38e619b79730f437839752a8.tar.gz
opencode-be493e8be045f25f38e619b79730f437839752a8.zip
wip(app): i18n
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/session-context-usage.tsx16
-rw-r--r--packages/app/src/components/session/session-context-tab.tsx15
-rw-r--r--packages/app/src/components/session/session-new-view.tsx18
-rw-r--r--packages/app/src/i18n/en.ts10
-rw-r--r--packages/app/src/i18n/zh.ts10
5 files changed, 49 insertions, 20 deletions
diff --git a/packages/app/src/components/session-context-usage.tsx b/packages/app/src/components/session-context-usage.tsx
index 680f32713..53148d416 100644
--- a/packages/app/src/components/session-context-usage.tsx
+++ b/packages/app/src/components/session-context-usage.tsx
@@ -7,6 +7,7 @@ import { AssistantMessage } from "@opencode-ai/sdk/v2/client"
import { useLayout } from "@/context/layout"
import { useSync } from "@/context/sync"
+import { useLanguage } from "@/context/language"
interface SessionContextUsageProps {
variant?: "button" | "indicator"
@@ -16,6 +17,7 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
const sync = useSync()
const params = useParams()
const layout = useLayout()
+ const language = useLanguage()
const variant = createMemo(() => props.variant ?? "button")
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
@@ -24,14 +26,16 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
const messages = createMemo(() => (params.id ? (sync.data.message[params.id] ?? []) : []))
const cost = createMemo(() => {
+ const locale = language.locale()
const total = messages().reduce((sum, x) => sum + (x.role === "assistant" ? x.cost : 0), 0)
- return new Intl.NumberFormat("en-US", {
+ return new Intl.NumberFormat(locale, {
style: "currency",
currency: "USD",
}).format(total)
})
const context = createMemo(() => {
+ const locale = language.locale()
const last = messages().findLast((x) => {
if (x.role !== "assistant") return false
const total = x.tokens.input + x.tokens.output + x.tokens.reasoning + x.tokens.cache.read + x.tokens.cache.write
@@ -42,7 +46,7 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
const model = sync.data.provider.all.find((x) => x.id === last.providerID)?.models[last.modelID]
return {
- tokens: total.toLocaleString(),
+ tokens: total.toLocaleString(locale),
percentage: model?.limit.context ? Math.round((total / model.limit.context) * 100) : null,
}
})
@@ -67,21 +71,21 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
<>
<div class="flex items-center gap-2">
<span class="text-text-invert-strong">{ctx().tokens}</span>
- <span class="text-text-invert-base">Tokens</span>
+ <span class="text-text-invert-base">{language.t("context.usage.tokens")}</span>
</div>
<div class="flex items-center gap-2">
<span class="text-text-invert-strong">{ctx().percentage ?? 0}%</span>
- <span class="text-text-invert-base">Usage</span>
+ <span class="text-text-invert-base">{language.t("context.usage.usage")}</span>
</div>
</>
)}
</Show>
<div class="flex items-center gap-2">
<span class="text-text-invert-strong">{cost()}</span>
- <span class="text-text-invert-base">Cost</span>
+ <span class="text-text-invert-base">{language.t("context.usage.cost")}</span>
</div>
<Show when={variant() === "button"}>
- <div class="text-11-regular text-text-invert-base mt-1">Click to view context</div>
+ <div class="text-11-regular text-text-invert-base mt-1">{language.t("context.usage.clickToView")}</div>
</Show>
</div>
)
diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx
index 030ae6d58..3758dd6e8 100644
--- a/packages/app/src/components/session/session-context-tab.tsx
+++ b/packages/app/src/components/session/session-context-tab.tsx
@@ -61,8 +61,9 @@ export function SessionContextTab(props: SessionContextTabProps) {
})
const cost = createMemo(() => {
+ const locale = language.locale()
const total = props.messages().reduce((sum, x) => sum + (x.role === "assistant" ? x.cost : 0), 0)
- return new Intl.NumberFormat("en-US", {
+ return new Intl.NumberFormat(locale, {
style: "currency",
currency: "USD",
}).format(total)
@@ -91,18 +92,18 @@ export function SessionContextTab(props: SessionContextTabProps) {
const number = (value: number | null | undefined) => {
if (value === undefined) return "—"
if (value === null) return "—"
- return value.toLocaleString()
+ return value.toLocaleString(language.locale())
}
const percent = (value: number | null | undefined) => {
if (value === undefined) return "—"
if (value === null) return "—"
- return value.toString() + "%"
+ return value.toLocaleString(language.locale()) + "%"
}
const time = (value: number | undefined) => {
if (!value) return "—"
- return DateTime.fromMillis(value).toLocaleString(DateTime.DATETIME_MED)
+ return DateTime.fromMillis(value).setLocale(language.locale()).toLocaleString(DateTime.DATETIME_MED)
}
const providerLabel = createMemo(() => {
@@ -246,7 +247,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
const count = counts()
return [
{ label: language.t("context.stats.session"), value: props.info()?.title ?? params.id ?? "—" },
- { label: language.t("context.stats.messages"), value: count.all.toLocaleString() },
+ { label: language.t("context.stats.messages"), value: count.all.toLocaleString(language.locale()) },
{ label: language.t("context.stats.provider"), value: providerLabel() },
{ label: language.t("context.stats.model"), value: modelLabel() },
{ label: language.t("context.stats.limit"), value: number(c?.limit) },
@@ -259,8 +260,8 @@ export function SessionContextTab(props: SessionContextTabProps) {
label: language.t("context.stats.cacheTokens"),
value: `${number(c?.cacheRead)} / ${number(c?.cacheWrite)}`,
},
- { label: language.t("context.stats.userMessages"), value: count.user.toLocaleString() },
- { label: language.t("context.stats.assistantMessages"), value: count.assistant.toLocaleString() },
+ { label: language.t("context.stats.userMessages"), value: count.user.toLocaleString(language.locale()) },
+ { label: language.t("context.stats.assistantMessages"), value: count.assistant.toLocaleString(language.locale()) },
{ label: language.t("context.stats.totalCost"), value: cost() },
{ label: language.t("context.stats.sessionCreated"), value: time(props.info()?.time.created) },
{ label: language.t("context.stats.lastActivity"), value: time(c?.message.time.created) },
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx
index 68ef0cc1f..6d6078d40 100644
--- a/packages/app/src/components/session/session-new-view.tsx
+++ b/packages/app/src/components/session/session-new-view.tsx
@@ -1,6 +1,7 @@
import { Show, createMemo } from "solid-js"
import { DateTime } from "luxon"
import { useSync } from "@/context/sync"
+import { useLanguage } from "@/context/language"
import { Icon } from "@opencode-ai/ui/icon"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
import { Select } from "@opencode-ai/ui/select"
@@ -15,6 +16,7 @@ interface NewSessionViewProps {
export function NewSessionView(props: NewSessionViewProps) {
const sync = useSync()
+ const language = useLanguage()
const sandboxes = createMemo(() => sync.project?.sandboxes ?? [])
const options = createMemo(() => [MAIN_WORKTREE, ...sandboxes(), CREATE_WORKTREE])
@@ -32,13 +34,13 @@ export function NewSessionView(props: NewSessionViewProps) {
const label = (value: string) => {
if (value === MAIN_WORKTREE) {
- if (isWorktree()) return "Main branch"
+ if (isWorktree()) return language.t("session.new.worktree.main")
const branch = sync.data.vcs?.branch
- if (branch) return `Main branch (${branch})`
- return "Main branch"
+ if (branch) return language.t("session.new.worktree.mainWithBranch", { branch })
+ return language.t("session.new.worktree.main")
}
- if (value === CREATE_WORKTREE) return "Create new worktree"
+ if (value === CREATE_WORKTREE) return language.t("session.new.worktree.create")
return getFilename(value)
}
@@ -48,7 +50,7 @@ export function NewSessionView(props: NewSessionViewProps) {
class="size-full flex flex-col pb-45 justify-end items-start gap-4 flex-[1_0_0] self-stretch max-w-200 mx-auto px-6"
style={{ "padding-bottom": "calc(var(--prompt-height, 11.25rem) + 64px)" }}
>
- <div class="text-20-medium text-text-weaker">New session</div>
+ <div class="text-20-medium text-text-weaker">{language.t("command.session.new")}</div>
<div class="flex justify-center items-center gap-3">
<Icon name="folder" size="small" />
<div class="text-12-medium text-text-weak">
@@ -76,9 +78,11 @@ export function NewSessionView(props: NewSessionViewProps) {
<div class="flex justify-center items-center gap-3">
<Icon name="pencil-line" size="small" />
<div class="text-12-medium text-text-weak">
- Last modified&nbsp;
+ {language.t("session.new.lastModified")}&nbsp;
<span class="text-text-strong">
- {DateTime.fromMillis(project().time.updated ?? project().time.created).toRelative()}
+ {DateTime.fromMillis(project().time.updated ?? project().time.created)
+ .setLocale(language.locale())
+ .toRelative()}
</span>
</div>
</div>
diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts
index cab1bd29d..97ab9e0bf 100644
--- a/packages/app/src/i18n/en.ts
+++ b/packages/app/src/i18n/en.ts
@@ -256,6 +256,11 @@ export const dict = {
"context.stats.sessionCreated": "Session Created",
"context.stats.lastActivity": "Last Activity",
+ "context.usage.tokens": "Tokens",
+ "context.usage.usage": "Usage",
+ "context.usage.cost": "Cost",
+ "context.usage.clickToView": "Click to view context",
+
"language.en": "English",
"language.zh": "Chinese",
@@ -344,6 +349,11 @@ export const dict = {
"session.context.addToContext": "Add {{selection}} to context",
+ "session.new.worktree.main": "Main branch",
+ "session.new.worktree.mainWithBranch": "Main branch ({{branch}})",
+ "session.new.worktree.create": "Create new worktree",
+ "session.new.lastModified": "Last modified",
+
"session.header.search.placeholder": "Search {{project}}",
"session.share.popover.title": "Publish on web",
diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts
index 2ded1d677..014fa5353 100644
--- a/packages/app/src/i18n/zh.ts
+++ b/packages/app/src/i18n/zh.ts
@@ -255,6 +255,11 @@ export const dict = {
"context.stats.sessionCreated": "创建时间",
"context.stats.lastActivity": "最后活动",
+ "context.usage.tokens": "Token",
+ "context.usage.usage": "使用率",
+ "context.usage.cost": "成本",
+ "context.usage.clickToView": "点击查看上下文",
+
"language.en": "英语",
"language.zh": "中文",
@@ -341,6 +346,11 @@ export const dict = {
"session.context.addToContext": "将 {{selection}} 添加到上下文",
+ "session.new.worktree.main": "主分支",
+ "session.new.worktree.mainWithBranch": "主分支 ({{branch}})",
+ "session.new.worktree.create": "创建新的 worktree",
+ "session.new.lastModified": "最后修改",
+
"session.header.search.placeholder": "搜索 {{project}}",
"session.share.popover.title": "发布到网页",