summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-20 05:40:44 -0600
committerAdam <[email protected]>2026-01-20 17:58:06 -0600
commit92beae14100af23c20afe7b6bc2bb393643d698f (patch)
tree1047cf04130c98edac5dd322613608e3ec4b5f46 /packages/app/src/pages
parent0470717c7fbb9ff175b70c6d76ffb2330ef40a1a (diff)
downloadopencode-92beae14100af23c20afe7b6bc2bb393643d698f.tar.gz
opencode-92beae14100af23c20afe7b6bc2bb393643d698f.zip
wip(app): i18n
Diffstat (limited to 'packages/app/src/pages')
-rw-r--r--packages/app/src/pages/layout.tsx59
-rw-r--r--packages/app/src/pages/session.tsx171
2 files changed, 117 insertions, 113 deletions
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index bd6c044a8..f5910b88b 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -114,11 +114,12 @@ export default function Layout(props: ParentProps) {
const initialDir = params.dir
const availableThemeEntries = createMemo(() => Object.entries(theme.themes()))
const colorSchemeOrder: ColorScheme[] = ["system", "light", "dark"]
- const colorSchemeLabel: Record<ColorScheme, string> = {
- system: "System",
- light: "Light",
- dark: "Dark",
+ const colorSchemeKey: Record<ColorScheme, "theme.scheme.system" | "theme.scheme.light" | "theme.scheme.dark"> = {
+ system: "theme.scheme.system",
+ light: "theme.scheme.light",
+ dark: "theme.scheme.dark",
}
+ const colorSchemeLabel = (scheme: ColorScheme) => language.t(colorSchemeKey[scheme])
const [editor, setEditor] = createStore({
active: "" as string,
@@ -252,7 +253,7 @@ export default function Layout(props: ParentProps) {
theme.setTheme(nextThemeId)
const nextTheme = theme.themes()[nextThemeId]
showToast({
- title: "Theme switched",
+ title: language.t("toast.theme.title"),
description: nextTheme?.name ?? nextThemeId,
})
}
@@ -265,8 +266,8 @@ export default function Layout(props: ParentProps) {
const next = colorSchemeOrder[nextIndex]
theme.setColorScheme(next)
showToast({
- title: "Color scheme",
- description: colorSchemeLabel[next],
+ title: language.t("toast.scheme.title"),
+ description: colorSchemeLabel(next),
})
}
@@ -827,28 +828,28 @@ export default function Layout(props: ParentProps) {
const commands: CommandOption[] = [
{
id: "sidebar.toggle",
- title: "Toggle sidebar",
- category: "View",
+ title: language.t("command.sidebar.toggle"),
+ category: language.t("command.category.view"),
keybind: "mod+b",
onSelect: () => layout.sidebar.toggle(),
},
{
id: "project.open",
- title: "Open project",
- category: "Project",
+ title: language.t("command.project.open"),
+ category: language.t("command.category.project"),
keybind: "mod+o",
onSelect: () => chooseProject(),
},
{
id: "provider.connect",
- title: "Connect provider",
- category: "Provider",
+ title: language.t("command.provider.connect"),
+ category: language.t("command.category.provider"),
onSelect: () => connectProvider(),
},
{
id: "server.switch",
- title: "Switch server",
- category: "Server",
+ title: language.t("command.server.switch"),
+ category: language.t("command.category.server"),
onSelect: () => openServer(),
},
{
@@ -860,22 +861,22 @@ export default function Layout(props: ParentProps) {
},
{
id: "session.previous",
- title: "Previous session",
- category: "Session",
+ title: language.t("command.session.previous"),
+ category: language.t("command.category.session"),
keybind: "alt+arrowup",
onSelect: () => navigateSessionByOffset(-1),
},
{
id: "session.next",
- title: "Next session",
- category: "Session",
+ title: language.t("command.session.next"),
+ category: language.t("command.category.session"),
keybind: "alt+arrowdown",
onSelect: () => navigateSessionByOffset(1),
},
{
id: "session.archive",
- title: "Archive session",
- category: "Session",
+ title: language.t("command.session.archive"),
+ category: language.t("command.category.session"),
keybind: "mod+shift+backspace",
disabled: !params.dir || !params.id,
onSelect: () => {
@@ -885,8 +886,8 @@ export default function Layout(props: ParentProps) {
},
{
id: "theme.cycle",
- title: "Cycle theme",
- category: "Theme",
+ title: language.t("command.theme.cycle"),
+ category: language.t("command.category.theme"),
keybind: "mod+shift+t",
onSelect: () => cycleTheme(1),
},
@@ -895,8 +896,8 @@ export default function Layout(props: ParentProps) {
for (const [id, definition] of availableThemeEntries()) {
commands.push({
id: `theme.set.${id}`,
- title: `Use theme: ${definition.name ?? id}`,
- category: "Theme",
+ title: language.t("command.theme.set", { theme: definition.name ?? id }),
+ category: language.t("command.category.theme"),
onSelect: () => theme.commitPreview(),
onHighlight: () => {
theme.previewTheme(id)
@@ -907,8 +908,8 @@ export default function Layout(props: ParentProps) {
commands.push({
id: "theme.scheme.cycle",
- title: "Cycle color scheme",
- category: "Theme",
+ title: language.t("command.theme.scheme.cycle"),
+ category: language.t("command.category.theme"),
keybind: "mod+shift+s",
onSelect: () => cycleColorScheme(1),
})
@@ -916,8 +917,8 @@ export default function Layout(props: ParentProps) {
for (const scheme of colorSchemeOrder) {
commands.push({
id: `theme.scheme.${scheme}`,
- title: `Use color scheme: ${colorSchemeLabel[scheme]}`,
- category: "Theme",
+ title: language.t("command.theme.scheme.set", { scheme: colorSchemeLabel(scheme) }),
+ category: language.t("command.category.theme"),
onSelect: () => theme.commitPreview(),
onHighlight: () => {
theme.previewColorScheme(scheme)
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 14f77d63e..8803b063e 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -33,6 +33,7 @@ import { DialogSelectModel } from "@/components/dialog-select-model"
import { DialogSelectMcp } from "@/components/dialog-select-mcp"
import { DialogFork } from "@/components/dialog-fork"
import { useCommand } from "@/context/command"
+import { useLanguage } from "@/context/language"
import { useNavigate, useParams } from "@solidjs/router"
import { UserMessage } from "@opencode-ai/sdk/v2"
import type { FileDiff } from "@opencode-ai/sdk/v2/client"
@@ -161,6 +162,7 @@ export default function Page() {
const dialog = useDialog()
const codeComponent = useCodeComponent()
const command = useCommand()
+ const language = useLanguage()
const platform = usePlatform()
const params = useParams()
const navigate = useNavigate()
@@ -433,51 +435,51 @@ export default function Page() {
command.register(() => [
{
id: "session.new",
- title: "New session",
- category: "Session",
+ title: language.t("command.session.new"),
+ category: language.t("command.category.session"),
keybind: "mod+shift+s",
slash: "new",
onSelect: () => navigate(`/${params.dir}/session`),
},
{
id: "file.open",
- title: "Open file",
- description: "Search files and commands",
- category: "File",
+ title: language.t("command.file.open"),
+ description: language.t("command.file.open.description"),
+ category: language.t("command.category.file"),
keybind: "mod+p",
slash: "open",
onSelect: () => dialog.show(() => <DialogSelectFile />),
},
{
id: "terminal.toggle",
- title: "Toggle terminal",
+ title: language.t("command.terminal.toggle"),
description: "",
- category: "View",
+ category: language.t("command.category.view"),
keybind: "ctrl+`",
slash: "terminal",
onSelect: () => view().terminal.toggle(),
},
{
id: "review.toggle",
- title: "Toggle review",
+ title: language.t("command.review.toggle"),
description: "",
- category: "View",
+ category: language.t("command.category.view"),
keybind: "mod+shift+r",
onSelect: () => view().reviewPanel.toggle(),
},
{
id: "terminal.new",
- title: "New terminal",
- description: "Create a new terminal tab",
- category: "Terminal",
+ title: language.t("command.terminal.new"),
+ description: language.t("command.terminal.new.description"),
+ category: language.t("command.category.terminal"),
keybind: "ctrl+alt+t",
onSelect: () => terminal.new(),
},
{
id: "steps.toggle",
- title: "Toggle steps",
- description: "Show or hide steps for the current message",
- category: "View",
+ title: language.t("command.steps.toggle"),
+ description: language.t("command.steps.toggle.description"),
+ category: language.t("command.category.view"),
keybind: "mod+e",
slash: "steps",
disabled: !params.id,
@@ -489,62 +491,62 @@ export default function Page() {
},
{
id: "message.previous",
- title: "Previous message",
- description: "Go to the previous user message",
- category: "Session",
+ title: language.t("command.message.previous"),
+ description: language.t("command.message.previous.description"),
+ category: language.t("command.category.session"),
keybind: "mod+arrowup",
disabled: !params.id,
onSelect: () => navigateMessageByOffset(-1),
},
{
id: "message.next",
- title: "Next message",
- description: "Go to the next user message",
- category: "Session",
+ title: language.t("command.message.next"),
+ description: language.t("command.message.next.description"),
+ category: language.t("command.category.session"),
keybind: "mod+arrowdown",
disabled: !params.id,
onSelect: () => navigateMessageByOffset(1),
},
{
id: "model.choose",
- title: "Choose model",
- description: "Select a different model",
- category: "Model",
+ title: language.t("command.model.choose"),
+ description: language.t("command.model.choose.description"),
+ category: language.t("command.category.model"),
keybind: "mod+'",
slash: "model",
onSelect: () => dialog.show(() => <DialogSelectModel />),
},
{
id: "mcp.toggle",
- title: "Toggle MCPs",
- description: "Toggle MCPs",
- category: "MCP",
+ title: language.t("command.mcp.toggle"),
+ description: language.t("command.mcp.toggle.description"),
+ category: language.t("command.category.mcp"),
keybind: "mod+;",
slash: "mcp",
onSelect: () => dialog.show(() => <DialogSelectMcp />),
},
{
id: "agent.cycle",
- title: "Cycle agent",
- description: "Switch to the next agent",
- category: "Agent",
+ title: language.t("command.agent.cycle"),
+ description: language.t("command.agent.cycle.description"),
+ category: language.t("command.category.agent"),
keybind: "mod+.",
slash: "agent",
onSelect: () => local.agent.move(1),
},
{
id: "agent.cycle.reverse",
- title: "Cycle agent backwards",
- description: "Switch to the previous agent",
- category: "Agent",
+ title: language.t("command.agent.cycle.reverse"),
+ description: language.t("command.agent.cycle.reverse.description"),
+ category: language.t("command.category.agent"),
keybind: "shift+mod+.",
onSelect: () => local.agent.move(-1),
},
{
id: "model.variant.cycle",
- title: "Cycle thinking effort",
- description: "Switch to the next effort level",
- category: "Model",
+ title: language.t("command.model.variant.cycle"),
+ description: language.t("command.model.variant.cycle.description"),
+ category: language.t("command.category.model"),
keybind: "shift+mod+d",
onSelect: () => {
local.model.variant.cycle()
@@ -554,30 +556,31 @@ export default function Page() {
id: "permissions.autoaccept",
title:
params.id && permission.isAutoAccepting(params.id, sdk.directory)
- ? "Stop auto-accepting edits"
- : "Auto-accept edits",
- category: "Permissions",
+ ? language.t("command.permissions.autoaccept.disable")
+ : language.t("command.permissions.autoaccept.enable"),
+ category: language.t("command.category.permissions"),
keybind: "mod+shift+a",
disabled: !params.id || !permission.permissionsEnabled(),
onSelect: () => {
const sessionID = params.id
if (!sessionID) return
permission.toggleAutoAccept(sessionID, sdk.directory)
+ const enabled = permission.isAutoAccepting(sessionID, sdk.directory)
showToast({
- title: permission.isAutoAccepting(sessionID, sdk.directory)
- ? "Auto-accepting edits"
- : "Stopped auto-accepting edits",
- description: permission.isAutoAccepting(sessionID, sdk.directory)
- ? "Edit and write permissions will be automatically approved"
- : "Edit and write permissions will require approval",
+ title: enabled
+ ? language.t("toast.permissions.autoaccept.on.title")
+ : language.t("toast.permissions.autoaccept.off.title"),
+ description: enabled
+ ? language.t("toast.permissions.autoaccept.on.description")
+ : language.t("toast.permissions.autoaccept.off.description"),
})
},
},
{
id: "session.undo",
- title: "Undo",
- description: "Undo the last message",
- category: "Session",
+ title: language.t("command.session.undo"),
+ description: language.t("command.session.undo.description"),
+ category: language.t("command.category.session"),
slash: "undo",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: async () => {
@@ -604,9 +607,9 @@ export default function Page() {
},
{
id: "session.redo",
- title: "Redo",
- description: "Redo the last undone message",
- category: "Session",
+ title: language.t("command.session.redo"),
+ description: language.t("command.session.redo.description"),
+ category: language.t("command.category.session"),
slash: "redo",
disabled: !params.id || !info()?.revert?.messageID,
onSelect: async () => {
@@ -633,9 +636,9 @@ export default function Page() {
},
{
id: "session.compact",
- title: "Compact session",
- description: "Summarize the session to reduce context size",
- category: "Session",
+ title: language.t("command.session.compact"),
+ description: language.t("command.session.compact.description"),
+ category: language.t("command.category.session"),
slash: "compact",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: async () => {
@@ -644,8 +647,8 @@ export default function Page() {
const model = local.model.current()
if (!model) {
showToast({
- title: "No model selected",
- description: "Connect a provider to summarize this session",
+ title: language.t("toast.model.none.title"),
+ description: language.t("toast.model.none.description"),
})
return
}
@@ -658,72 +661,72 @@ export default function Page() {
},
{
id: "session.fork",
- title: "Fork from message",
- description: "Create a new session from a previous message",
- category: "Session",
+ title: language.t("command.session.fork"),
+ description: language.t("command.session.fork.description"),
+ category: language.t("command.category.session"),
slash: "fork",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: () => dialog.show(() => <DialogFork />),
},
...(sync.data.config.share !== "disabled"
? [
- {
- id: "session.share",
- title: "Share session",
- description: "Share this session and copy the URL to clipboard",
- category: "Session",
- slash: "share",
- disabled: !params.id || !!info()?.share?.url,
- onSelect: async () => {
+ {
+ id: "session.share",
+ title: language.t("command.session.share"),
+ description: language.t("command.session.share.description"),
+ category: language.t("command.category.session"),
+ slash: "share",
+ disabled: !params.id || !!info()?.share?.url,
+ onSelect: async () => {
if (!params.id) return
await sdk.client.session
.share({ sessionID: params.id })
.then((res) => {
navigator.clipboard.writeText(res.data!.share!.url).catch(() =>
showToast({
- title: "Failed to copy URL to clipboard",
+ title: language.t("toast.session.share.copyFailed.title"),
variant: "error",
}),
)
})
.then(() =>
showToast({
- title: "Session shared",
- description: "Share URL copied to clipboard!",
+ title: language.t("toast.session.share.success.title"),
+ description: language.t("toast.session.share.success.description"),
variant: "success",
}),
)
.catch(() =>
showToast({
- title: "Failed to share session",
- description: "An error occurred while sharing the session",
+ title: language.t("toast.session.share.failed.title"),
+ description: language.t("toast.session.share.failed.description"),
variant: "error",
}),
)
},
},
- {
- id: "session.unshare",
- title: "Unshare session",
- description: "Stop sharing this session",
- category: "Session",
- slash: "unshare",
- disabled: !params.id || !info()?.share?.url,
- onSelect: async () => {
+ {
+ id: "session.unshare",
+ title: language.t("command.session.unshare"),
+ description: language.t("command.session.unshare.description"),
+ category: language.t("command.category.session"),
+ slash: "unshare",
+ disabled: !params.id || !info()?.share?.url,
+ onSelect: async () => {
if (!params.id) return
await sdk.client.session
.unshare({ sessionID: params.id })
.then(() =>
showToast({
- title: "Session unshared",
- description: "Session unshared successfully!",
+ title: language.t("toast.session.unshare.success.title"),
+ description: language.t("toast.session.unshare.success.description"),
variant: "success",
}),
)
.catch(() =>
showToast({
- title: "Failed to unshare session",
- description: "An error occurred while unsharing the session",
+ title: language.t("toast.session.unshare.failed.title"),
+ description: language.t("toast.session.unshare.failed.description"),
variant: "error",
}),
)