chore(app): i18n sync (#15362)

This commit is contained in:
Adam
2026-02-27 09:45:00 -06:00
committed by GitHub
parent e5ae6c51b0
commit 6ef3af73df
65 changed files with 1096 additions and 71 deletions

View File

@@ -2,6 +2,7 @@ import { createSignal } from "solid-js"
import { Dialog } from "@opencode-ai/ui/dialog"
import { Button } from "@opencode-ai/ui/button"
import { useDialog } from "@opencode-ai/ui/context/dialog"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
export type Highlight = {
@@ -16,6 +17,7 @@ export type Highlight = {
export function DialogReleaseNotes(props: { highlights: Highlight[] }) {
const dialog = useDialog()
const language = useLanguage()
const settings = useSettings()
const [index, setIndex] = createSignal(0)
@@ -83,16 +85,16 @@ export function DialogReleaseNotes(props: { highlights: Highlight[] }) {
<div class="flex flex-col items-start gap-3">
{isLast() ? (
<Button variant="primary" size="large" onClick={handleClose}>
Get started
{language.t("dialog.releaseNotes.action.getStarted")}
</Button>
) : (
<Button variant="secondary" size="large" onClick={handleNext}>
Next
{language.t("dialog.releaseNotes.action.next")}
</Button>
)}
<Button variant="ghost" size="small" onClick={handleDisable}>
Don't show these in the future
{language.t("dialog.releaseNotes.action.hideFuture")}
</Button>
</div>
@@ -128,7 +130,7 @@ export function DialogReleaseNotes(props: { highlights: Highlight[] }) {
{feature()!.media!.type === "image" ? (
<img
src={feature()!.media!.src}
alt={feature()!.media!.alt ?? feature()?.title ?? "Release preview"}
alt={feature()!.media!.alt ?? feature()?.title ?? language.t("dialog.releaseNotes.media.alt")}
class="w-full h-full object-cover"
/>
) : (

View File

@@ -449,7 +449,7 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil
</div>
<Show when={item.updated}>
<span class="text-12-regular text-text-weak whitespace-nowrap ml-2">
{getRelativeTime(new Date(item.updated!).toISOString())}
{getRelativeTime(new Date(item.updated!).toISOString(), language.t)}
</span>
</Show>
</div>

View File

@@ -430,7 +430,7 @@ export function SessionHeader() {
<Spinner class="size-3.5 text-icon-base" />
</Show>
</div>
<span class="text-12-regular text-text-strong">Open</span>
<span class="text-12-regular text-text-strong">{language.t("common.open")}</span>
</Button>
<div class="self-stretch w-px bg-border-weak-base" />
<DropdownMenu

View File

@@ -162,7 +162,7 @@ export const SettingsProviders: Component = () => {
when={canDisconnect(item)}
fallback={
<span class="text-14-regular text-text-base opacity-0 group-hover:opacity-100 transition-opacity duration-200 pr-3 cursor-default">
Connected from your environment variables
{language.t("settings.providers.connected.environmentDescription")}
</span>
}
>
@@ -229,10 +229,12 @@ export const SettingsProviders: Component = () => {
<div class="flex flex-col min-w-0">
<div class="flex flex-wrap items-center gap-x-3 gap-y-1">
<ProviderIcon id={icon("synthetic")} class="size-5 shrink-0 icon-strong-base" />
<span class="text-14-medium text-text-strong">Custom provider</span>
<span class="text-14-medium text-text-strong">{language.t("provider.custom.title")}</span>
<Tag>{language.t("settings.providers.tag.custom")}</Tag>
</div>
<span class="text-12-regular text-text-weak pl-8">Add an OpenAI-compatible provider by base URL.</span>
<span class="text-12-regular text-text-weak pl-8">
{language.t("settings.providers.custom.description")}
</span>
</div>
<Button
size="large"

View File

@@ -204,7 +204,10 @@ function createGlobalSync() {
showToast({
variant: "error",
title: language.t("toast.session.listFailed.title", { project }),
description: formatServerError(err),
description: formatServerError(err, {
unknown: language.t("error.chain.unknown"),
invalidConfiguration: language.t("error.server.invalidConfiguration"),
}),
})
})
@@ -234,6 +237,8 @@ function createGlobalSync() {
setStore: child[1],
vcsCache: cache,
loadSessions,
unknownError: language.t("error.chain.unknown"),
invalidConfigurationError: language.t("error.server.invalidConfiguration"),
})
})()
@@ -308,6 +313,9 @@ function createGlobalSync() {
url: globalSDK.url,
}),
requestFailedTitle: language.t("common.requestFailed"),
unknownError: language.t("error.chain.unknown"),
invalidConfigurationError: language.t("error.server.invalidConfiguration"),
formatMoreCount: (count) => language.t("common.moreCountSuffix", { count }),
setGlobalStore,
})
}

View File

@@ -36,6 +36,9 @@ export async function bootstrapGlobal(input: {
connectErrorTitle: string
connectErrorDescription: string
requestFailedTitle: string
unknownError: string
invalidConfigurationError: string
formatMoreCount: (count: number) => string
setGlobalStore: SetStoreFunction<GlobalStore>
}) {
const health = await input.globalSDK.global
@@ -88,8 +91,11 @@ export async function bootstrapGlobal(input: {
const results = await Promise.allSettled(tasks)
const errors = results.filter((r): r is PromiseRejectedResult => r.status === "rejected").map((r) => r.reason)
if (errors.length) {
const message = errors[0] instanceof Error ? errors[0].message : String(errors[0])
const more = errors.length > 1 ? ` (+${errors.length - 1} more)` : ""
const message = formatServerError(errors[0], {
unknown: input.unknownError,
invalidConfiguration: input.invalidConfigurationError,
})
const more = errors.length > 1 ? input.formatMoreCount(errors.length - 1) : ""
showToast({
variant: "error",
title: input.requestFailedTitle,
@@ -116,6 +122,8 @@ export async function bootstrapDirectory(input: {
setStore: SetStoreFunction<State>
vcsCache: VcsCache
loadSessions: (directory: string) => Promise<void> | void
unknownError: string
invalidConfigurationError: string
}) {
if (input.store.status !== "complete") input.setStore("status", "loading")
@@ -137,7 +145,10 @@ export async function bootstrapDirectory(input: {
showToast({
variant: "error",
title: `Failed to reload ${project}`,
description: formatServerError(err),
description: formatServerError(err, {
unknown: input.unknownError,
invalidConfiguration: input.invalidConfigurationError,
}),
})
input.setStore("status", "partial")
return

View File

@@ -734,4 +734,18 @@ export const dict = {
"workspace.reset.archived.one": "ستتم أرشفة جلسة واحدة.",
"workspace.reset.archived.many": "ستتم أرشفة {{count}} جلسات.",
"workspace.reset.note": "سيؤدي هذا إلى إعادة تعيين مساحة العمل لتتطابق مع الفرع الافتراضي.",
"common.open": "فتح",
"dialog.releaseNotes.action.getStarted": "البدء",
"dialog.releaseNotes.action.next": "التالي",
"dialog.releaseNotes.action.hideFuture": "عدم إظهار هذا في المستقبل",
"dialog.releaseNotes.media.alt": "معاينة الإصدار",
"toast.project.reloadFailed.title": "فشل في إعادة تحميل {{project}}",
"error.server.invalidConfiguration": "تكوين غير صالح",
"common.moreCountSuffix": " (+{{count}} إضافي)",
"common.time.justNow": "الآن",
"common.time.minutesAgo.short": "قبل {{count}} د",
"common.time.hoursAgo.short": "قبل {{count}} س",
"common.time.daysAgo.short": "قبل {{count}} ي",
"settings.providers.connected.environmentDescription": "متصل من متغيرات البيئة الخاصة بك",
"settings.providers.custom.description": "أضف مزود متوافق مع OpenAI بواسطة عنوان URL الأساسي.",
}

View File

@@ -742,4 +742,18 @@ export const dict = {
"workspace.reset.archived.one": "1 sessão será arquivada.",
"workspace.reset.archived.many": "{{count}} sessões serão arquivadas.",
"workspace.reset.note": "Isso redefinirá o espaço de trabalho para corresponder ao branch padrão.",
"common.open": "Abrir",
"dialog.releaseNotes.action.getStarted": "Começar",
"dialog.releaseNotes.action.next": "Próximo",
"dialog.releaseNotes.action.hideFuture": "Não mostrar isso no futuro",
"dialog.releaseNotes.media.alt": "Prévia do lançamento",
"toast.project.reloadFailed.title": "Falha ao recarregar {{project}}",
"error.server.invalidConfiguration": "Configuração inválida",
"common.moreCountSuffix": " (+{{count}} mais)",
"common.time.justNow": "Agora mesmo",
"common.time.minutesAgo.short": "{{count}}m atrás",
"common.time.hoursAgo.short": "{{count}}h atrás",
"common.time.daysAgo.short": "{{count}}d atrás",
"settings.providers.connected.environmentDescription": "Conectado a partir de suas variáveis de ambiente",
"settings.providers.custom.description": "Adicionar um provedor compatível com a OpenAI através do URL base.",
}

View File

@@ -819,4 +819,18 @@ export const dict = {
"workspace.reset.archived.one": "1 sesija će biti arhivirana.",
"workspace.reset.archived.many": "Biće arhivirano {{count}} sesija.",
"workspace.reset.note": "Ovo će resetovati radni prostor da odgovara podrazumijevanoj grani.",
"common.open": "Otvori",
"dialog.releaseNotes.action.getStarted": "Započni",
"dialog.releaseNotes.action.next": "Sljedeće",
"dialog.releaseNotes.action.hideFuture": "Ne prikazuj ovo u budućnosti",
"dialog.releaseNotes.media.alt": "Pregled izdanja",
"toast.project.reloadFailed.title": "Nije uspjelo ponovno učitavanje {{project}}",
"error.server.invalidConfiguration": "Nevažeća konfiguracija",
"common.moreCountSuffix": " (+{{count}} više)",
"common.time.justNow": "Upravo sada",
"common.time.minutesAgo.short": "prije {{count}} min",
"common.time.hoursAgo.short": "prije {{count}} h",
"common.time.daysAgo.short": "prije {{count}} d",
"settings.providers.connected.environmentDescription": "Povezano sa vašim varijablama okruženja",
"settings.providers.custom.description": "Dodajte provajdera kompatibilnog s OpenAI putem osnovnog URL-a.",
}

View File

@@ -813,4 +813,18 @@ export const dict = {
"workspace.reset.archived.one": "1 session vil blive arkiveret.",
"workspace.reset.archived.many": "{{count}} sessioner vil blive arkiveret.",
"workspace.reset.note": "Dette vil nulstille arbejdsområdet til at matche hovedgrenen.",
"common.open": "Åbn",
"dialog.releaseNotes.action.getStarted": "Kom i gang",
"dialog.releaseNotes.action.next": "Næste",
"dialog.releaseNotes.action.hideFuture": "Vis ikke disse i fremtiden",
"dialog.releaseNotes.media.alt": "Forhåndsvisning af udgivelse",
"toast.project.reloadFailed.title": "Kunne ikke genindlæse {{project}}",
"error.server.invalidConfiguration": "Ugyldig konfiguration",
"common.moreCountSuffix": " (+{{count}} mere)",
"common.time.justNow": "Lige nu",
"common.time.minutesAgo.short": "{{count}}m siden",
"common.time.hoursAgo.short": "{{count}}t siden",
"common.time.daysAgo.short": "{{count}}d siden",
"settings.providers.connected.environmentDescription": "Tilsluttet fra dine miljøvariabler",
"settings.providers.custom.description": "Tilføj en OpenAI-kompatibel udbyder via basis-URL.",
}

View File

@@ -751,4 +751,18 @@ export const dict = {
"workspace.reset.archived.one": "1 Sitzung wird archiviert.",
"workspace.reset.archived.many": "{{count}} Sitzungen werden archiviert.",
"workspace.reset.note": "Dadurch wird der Arbeitsbereich auf den Standard-Branch zurückgesetzt.",
"common.open": "Öffnen",
"dialog.releaseNotes.action.getStarted": "Loslegen",
"dialog.releaseNotes.action.next": "Weiter",
"dialog.releaseNotes.action.hideFuture": "In Zukunft nicht mehr anzeigen",
"dialog.releaseNotes.media.alt": "Vorschau auf die Version",
"toast.project.reloadFailed.title": "Fehler beim Neuladen von {{project}}",
"error.server.invalidConfiguration": "Ungültige Konfiguration",
"common.moreCountSuffix": " (+{{count}} weitere)",
"common.time.justNow": "Gerade eben",
"common.time.minutesAgo.short": "vor {{count}} Min",
"common.time.hoursAgo.short": "vor {{count}} Std",
"common.time.daysAgo.short": "vor {{count}} Tg",
"settings.providers.connected.environmentDescription": "Verbunden aus Ihren Umgebungsvariablen",
"settings.providers.custom.description": "Fügen Sie einen OpenAI-kompatiblen Anbieter per Basis-URL hinzu.",
} satisfies Partial<Record<Keys, string>>

View File

@@ -218,6 +218,7 @@ export const dict = {
"common.loading": "Loading",
"common.loading.ellipsis": "...",
"common.cancel": "Cancel",
"common.open": "Open",
"common.connect": "Connect",
"common.disconnect": "Disconnect",
"common.submit": "Submit",
@@ -347,6 +348,11 @@ export const dict = {
"dialog.project.edit.worktree.startup.description": "Runs after creating a new workspace (worktree).",
"dialog.project.edit.worktree.startup.placeholder": "e.g. bun install",
"dialog.releaseNotes.action.getStarted": "Get started",
"dialog.releaseNotes.action.next": "Next",
"dialog.releaseNotes.action.hideFuture": "Don't show these in the future",
"dialog.releaseNotes.media.alt": "Release preview",
"context.breakdown.title": "Context Breakdown",
"context.breakdown.note": 'Approximate breakdown of input tokens. "Other" includes tool definitions and overhead.',
"context.breakdown.system": "System",
@@ -436,6 +442,7 @@ export const dict = {
"toast.session.unshare.failed.description": "An error occurred while unsharing the session",
"toast.session.listFailed.title": "Failed to load sessions for {{project}}",
"toast.project.reloadFailed.title": "Failed to reload {{project}}",
"toast.update.title": "Update available",
"toast.update.description": "A new version of OpenCode ({{version}}) is now available to install.",
@@ -460,6 +467,7 @@ export const dict = {
"directory.error.invalidUrl": "Invalid directory in URL.",
"error.chain.unknown": "Unknown error",
"error.server.invalidConfiguration": "Invalid configuration",
"error.chain.causedBy": "Caused by:",
"error.chain.apiError": "API error",
"error.chain.status": "Status: {{status}}",
@@ -570,6 +578,7 @@ export const dict = {
"common.closeTab": "Close tab",
"common.dismiss": "Dismiss",
"common.moreCountSuffix": " (+{{count}} more)",
"common.requestFailed": "Request failed",
"common.moreOptions": "More options",
"common.learnMore": "Learn more",
@@ -582,6 +591,11 @@ export const dict = {
"common.loadMore": "Load more",
"common.key.esc": "ESC",
"common.time.justNow": "Just now",
"common.time.minutesAgo.short": "{{count}}m ago",
"common.time.hoursAgo.short": "{{count}}h ago",
"common.time.daysAgo.short": "{{count}}d ago",
"sidebar.menu.toggle": "Toggle menu",
"sidebar.nav.projectsAndSessions": "Projects and sessions",
"sidebar.settings": "Settings",
@@ -742,7 +756,9 @@ export const dict = {
"settings.providers.description": "Provider settings will be configurable here.",
"settings.providers.section.connected": "Connected providers",
"settings.providers.connected.empty": "No connected providers",
"settings.providers.connected.environmentDescription": "Connected from your environment variables",
"settings.providers.section.popular": "Popular providers",
"settings.providers.custom.description": "Add an OpenAI-compatible provider by base URL.",
"settings.providers.tag.environment": "Environment",
"settings.providers.tag.config": "Config",
"settings.providers.tag.custom": "Custom",

View File

@@ -825,4 +825,18 @@ export const dict = {
"workspace.reset.archived.one": "1 sesión será archivada.",
"workspace.reset.archived.many": "{{count}} sesiones serán archivadas.",
"workspace.reset.note": "Esto restablecerá el espacio de trabajo para coincidir con la rama predeterminada.",
"common.open": "Abrir",
"dialog.releaseNotes.action.getStarted": "Comenzar",
"dialog.releaseNotes.action.next": "Siguiente",
"dialog.releaseNotes.action.hideFuture": "No mostrar esto en el futuro",
"dialog.releaseNotes.media.alt": "Vista previa de la versión",
"toast.project.reloadFailed.title": "Error al recargar {{project}}",
"error.server.invalidConfiguration": "Configuración inválida",
"common.moreCountSuffix": " (+{{count}} más)",
"common.time.justNow": "Justo ahora",
"common.time.minutesAgo.short": "hace {{count}} min",
"common.time.hoursAgo.short": "hace {{count}} h",
"common.time.daysAgo.short": "hace {{count}} d",
"settings.providers.connected.environmentDescription": "Conectado desde tus variables de entorno",
"settings.providers.custom.description": "Añade un proveedor compatible con OpenAI por su URL base.",
}

View File

@@ -749,4 +749,18 @@ export const dict = {
"workspace.reset.archived.one": "1 session sera archivée.",
"workspace.reset.archived.many": "{{count}} sessions seront archivées.",
"workspace.reset.note": "Cela réinitialisera l'espace de travail pour correspondre à la branche par défaut.",
"common.open": "Ouvrir",
"dialog.releaseNotes.action.getStarted": "Commencer",
"dialog.releaseNotes.action.next": "Suivant",
"dialog.releaseNotes.action.hideFuture": "Ne plus afficher à l'avenir",
"dialog.releaseNotes.media.alt": "Aperçu de la version",
"toast.project.reloadFailed.title": "Échec du rechargement de {{project}}",
"error.server.invalidConfiguration": "Configuration invalide",
"common.moreCountSuffix": " (+{{count}} de plus)",
"common.time.justNow": "À l'instant",
"common.time.minutesAgo.short": "il y a {{count}}m",
"common.time.hoursAgo.short": "il y a {{count}}h",
"common.time.daysAgo.short": "il y a {{count}}j",
"settings.providers.connected.environmentDescription": "Connecté à partir de vos variables d'environnement",
"settings.providers.custom.description": "Ajouter un fournisseur compatible avec OpenAI via l'URL de base.",
}

View File

@@ -738,4 +738,18 @@ export const dict = {
"workspace.reset.archived.one": "1つのセッションがアーカイブされます。",
"workspace.reset.archived.many": "{{count}}個のセッションがアーカイブされます。",
"workspace.reset.note": "これにより、ワークスペースはデフォルトブランチと一致するようにリセットされます。",
"common.open": "開く",
"dialog.releaseNotes.action.getStarted": "始める",
"dialog.releaseNotes.action.next": "次へ",
"dialog.releaseNotes.action.hideFuture": "今後表示しない",
"dialog.releaseNotes.media.alt": "リリースのプレビュー",
"toast.project.reloadFailed.title": "{{project}} の再読み込みに失敗しました",
"error.server.invalidConfiguration": "無効な設定",
"common.moreCountSuffix": " (他 {{count}} 件)",
"common.time.justNow": "たった今",
"common.time.minutesAgo.short": "{{count}} 分前",
"common.time.hoursAgo.short": "{{count}} 時間前",
"common.time.daysAgo.short": "{{count}} 日前",
"settings.providers.connected.environmentDescription": "環境変数から接続されました",
"settings.providers.custom.description": "ベース URL を指定して OpenAI 互換のプロバイダーを追加します。",
}

View File

@@ -738,4 +738,18 @@ export const dict = {
"workspace.reset.archived.one": "1개의 세션이 보관됩니다.",
"workspace.reset.archived.many": "{{count}}개의 세션이 보관됩니다.",
"workspace.reset.note": "이 작업은 작업 공간을 기본 브랜치와 일치하도록 재설정합니다.",
"common.open": "열기",
"dialog.releaseNotes.action.getStarted": "시작하기",
"dialog.releaseNotes.action.next": "다음",
"dialog.releaseNotes.action.hideFuture": "다시 보지 않기",
"dialog.releaseNotes.media.alt": "릴리스 미리보기",
"toast.project.reloadFailed.title": "{{project}} 다시 불러오기 실패",
"error.server.invalidConfiguration": "잘못된 구성",
"common.moreCountSuffix": " (외 {{count}}개)",
"common.time.justNow": "방금 전",
"common.time.minutesAgo.short": "{{count}}분 전",
"common.time.hoursAgo.short": "{{count}}시간 전",
"common.time.daysAgo.short": "{{count}}일 전",
"settings.providers.connected.environmentDescription": "환경 변수에서 연결됨",
"settings.providers.custom.description": "기본 URL로 OpenAI 호환 공급자를 추가합니다.",
}

View File

@@ -821,4 +821,18 @@ export const dict = {
"workspace.reset.archived.one": "1 sesjon vil bli arkivert.",
"workspace.reset.archived.many": "{{count}} sesjoner vil bli arkivert.",
"workspace.reset.note": "Dette vil tilbakestille arbeidsområdet til å samsvare med standardgrenen.",
"common.open": "Åpne",
"dialog.releaseNotes.action.getStarted": "Kom i gang",
"dialog.releaseNotes.action.next": "Neste",
"dialog.releaseNotes.action.hideFuture": "Ikke vis disse igjen",
"dialog.releaseNotes.media.alt": "Forhåndsvisning av utgivelse",
"toast.project.reloadFailed.title": "Kunne ikke laste inn {{project}} på nytt",
"error.server.invalidConfiguration": "Ugyldig konfigurasjon",
"common.moreCountSuffix": " (+{{count}} mer)",
"common.time.justNow": "Akkurat nå",
"common.time.minutesAgo.short": "{{count}} m siden",
"common.time.hoursAgo.short": "{{count}} t siden",
"common.time.daysAgo.short": "{{count}} d siden",
"settings.providers.connected.environmentDescription": "Koblet til fra miljøvariablene dine",
"settings.providers.custom.description": "Legg til en OpenAI-kompatibel leverandør via basis-URL.",
} satisfies Partial<Record<Keys, string>>

View File

@@ -740,4 +740,18 @@ export const dict = {
"workspace.reset.archived.one": "1 sesja zostanie zarchiwizowana.",
"workspace.reset.archived.many": "{{count}} sesji zostanie zarchiwizowanych.",
"workspace.reset.note": "To zresetuje przestrzeń roboczą, aby odpowiadała domyślnej gałęzi.",
"common.open": "Otwórz",
"dialog.releaseNotes.action.getStarted": "Rozpocznij",
"dialog.releaseNotes.action.next": "Dalej",
"dialog.releaseNotes.action.hideFuture": "Nie pokazuj tego w przyszłości",
"dialog.releaseNotes.media.alt": "Podgląd wydania",
"toast.project.reloadFailed.title": "Nie udało się ponownie wczytać {{project}}",
"error.server.invalidConfiguration": "Nieprawidłowa konfiguracja",
"common.moreCountSuffix": " (jeszcze {{count}})",
"common.time.justNow": "Przed chwilą",
"common.time.minutesAgo.short": "{{count}} min temu",
"common.time.hoursAgo.short": "{{count}} godz. temu",
"common.time.daysAgo.short": "{{count}} dni temu",
"settings.providers.connected.environmentDescription": "Połączono ze zmiennymi środowiskowymi",
"settings.providers.custom.description": "Dodaj dostawcę zgodnego z OpenAI poprzez podstawowy URL.",
}

View File

@@ -821,4 +821,18 @@ export const dict = {
"workspace.reset.archived.one": "1 сессия будет архивирована.",
"workspace.reset.archived.many": "{{count}} сессий будет архивировано.",
"workspace.reset.note": "Рабочее пространство будет сброшено в соответствие с веткой по умолчанию.",
"common.open": "Открыть",
"dialog.releaseNotes.action.getStarted": "Начать",
"dialog.releaseNotes.action.next": "Далее",
"dialog.releaseNotes.action.hideFuture": "Больше не показывать",
"dialog.releaseNotes.media.alt": "Превью релиза",
"toast.project.reloadFailed.title": "Не удалось перезагрузить {{project}}",
"error.server.invalidConfiguration": "Недопустимая конфигурация",
"common.moreCountSuffix": " (ещё {{count}})",
"common.time.justNow": "Только что",
"common.time.minutesAgo.short": "{{count}} мин назад",
"common.time.hoursAgo.short": "{{count}} ч назад",
"common.time.daysAgo.short": "{{count}} д назад",
"settings.providers.connected.environmentDescription": "Подключено из ваших переменных окружения",
"settings.providers.custom.description": "Добавить провайдера, совместимого с OpenAI, по базовому URL.",
}

View File

@@ -811,4 +811,18 @@ export const dict = {
"workspace.reset.archived.one": "1 เซสชันจะถูกจัดเก็บ",
"workspace.reset.archived.many": "{{count}} เซสชันจะถูกจัดเก็บ",
"workspace.reset.note": "สิ่งนี้จะรีเซ็ตพื้นที่ทำงานให้ตรงกับสาขาเริ่มต้น",
"common.open": "เปิด",
"dialog.releaseNotes.action.getStarted": "เริ่มต้น",
"dialog.releaseNotes.action.next": "ถัดไป",
"dialog.releaseNotes.action.hideFuture": "ไม่ต้องแสดงสิ่งนี้อีกในอนาคต",
"dialog.releaseNotes.media.alt": "ตัวอย่างรุ่น",
"toast.project.reloadFailed.title": "ไม่สามารถโหลด {{project}} ใหม่ได้",
"error.server.invalidConfiguration": "การกำหนดค่าไม่ถูกต้อง",
"common.moreCountSuffix": " (เพิ่มอีก {{count}})",
"common.time.justNow": "เมื่อสักครู่นี้",
"common.time.minutesAgo.short": "{{count}} นาทีที่แล้ว",
"common.time.hoursAgo.short": "{{count}} ชม. ที่แล้ว",
"common.time.daysAgo.short": "{{count}} วันที่แล้ว",
"settings.providers.connected.environmentDescription": "เชื่อมต่อจากตัวแปรสภาพแวดล้อมของคุณ",
"settings.providers.custom.description": "เพิ่มผู้ให้บริการที่รองรับ OpenAI ด้วย URL หลัก",
}

View File

@@ -832,4 +832,18 @@ export const dict = {
"workspace.reset.archived.one": "1 oturum arşivlenecek.",
"workspace.reset.archived.many": "{{count}} oturum arşivlenecek.",
"workspace.reset.note": "Bu işlem çalışma alanını varsayılan dalla eşleşecek şekilde sıfırlayacak.",
"common.open": "Aç",
"dialog.releaseNotes.action.getStarted": "Başla",
"dialog.releaseNotes.action.next": "İleri",
"dialog.releaseNotes.action.hideFuture": "Bunu gelecekte bir daha gösterme",
"dialog.releaseNotes.media.alt": "Sürüm önizlemesi",
"toast.project.reloadFailed.title": "{{project}} yeniden yüklenemedi",
"error.server.invalidConfiguration": "Geçersiz yapılandırma",
"common.moreCountSuffix": " (+{{count}} daha)",
"common.time.justNow": "Şimdi",
"common.time.minutesAgo.short": "{{count}}dk önce",
"common.time.hoursAgo.short": "{{count}}sa önce",
"common.time.daysAgo.short": "{{count}}g önce",
"settings.providers.connected.environmentDescription": "Ortam değişkenlerinizden bağlandı",
"settings.providers.custom.description": "Temel URL üzerinden OpenAI uyumlu bir sağlayıcı ekleyin.",
} satisfies Partial<Record<Keys, string>>

View File

@@ -809,4 +809,18 @@ export const dict = {
"workspace.reset.archived.one": "将归档 1 个会话。",
"workspace.reset.archived.many": "将归档 {{count}} 个会话。",
"workspace.reset.note": "这将把工作区重置为与默认分支一致。",
"common.open": "打开",
"dialog.releaseNotes.action.getStarted": "开始",
"dialog.releaseNotes.action.next": "下一步",
"dialog.releaseNotes.action.hideFuture": "不再显示",
"dialog.releaseNotes.media.alt": "发布预览",
"toast.project.reloadFailed.title": "无法重新加载 {{project}}",
"error.server.invalidConfiguration": "配置无效",
"common.moreCountSuffix": " (还有 {{count}} 个)",
"common.time.justNow": "刚刚",
"common.time.minutesAgo.short": "{{count}}分钟前",
"common.time.hoursAgo.short": "{{count}}小时前",
"common.time.daysAgo.short": "{{count}}天前",
"settings.providers.connected.environmentDescription": "已通过环境变量连接",
"settings.providers.custom.description": "通过基础 URL 添加与 OpenAI 兼容的提供商。",
} satisfies Partial<Record<Keys, string>>

View File

@@ -804,4 +804,18 @@ export const dict = {
"workspace.reset.archived.one": "將封存 1 個工作階段。",
"workspace.reset.archived.many": "將封存 {{count}} 個工作階段。",
"workspace.reset.note": "這將把工作區重設為與預設分支一致。",
"common.open": "打開",
"dialog.releaseNotes.action.getStarted": "開始",
"dialog.releaseNotes.action.next": "下一步",
"dialog.releaseNotes.action.hideFuture": "不再顯示",
"dialog.releaseNotes.media.alt": "發佈預覽",
"toast.project.reloadFailed.title": "無法重新載入 {{project}}",
"error.server.invalidConfiguration": "無效的設定",
"common.moreCountSuffix": " (還有 {{count}} 個)",
"common.time.justNow": "剛剛",
"common.time.minutesAgo.short": "{{count}}分鐘前",
"common.time.hoursAgo.short": "{{count}}小時前",
"common.time.daysAgo.short": "{{count}}天前",
"settings.providers.connected.environmentDescription": "已從環境變數連線",
"settings.providers.custom.description": "透過基本 URL 新增與 OpenAI 相容的提供者。",
} satisfies Partial<Record<Keys, string>>

View File

@@ -7,11 +7,28 @@ export type ConfigInvalidError = {
}
}
export function formatServerError(error: unknown) {
if (isConfigInvalidErrorLike(error)) return parseReabaleConfigInvalidError(error)
type Label = {
unknown: string
invalidConfiguration: string
}
const fallback: Label = {
unknown: "Unknown error",
invalidConfiguration: "Invalid configuration",
}
function resolveLabel(labels: Partial<Label> | undefined): Label {
return {
unknown: labels?.unknown ?? fallback.unknown,
invalidConfiguration: labels?.invalidConfiguration ?? fallback.invalidConfiguration,
}
}
export function formatServerError(error: unknown, labels?: Partial<Label>) {
if (isConfigInvalidErrorLike(error)) return parseReabaleConfigInvalidError(error, labels)
if (error instanceof Error && error.message) return error.message
if (typeof error === "string" && error) return error
return "Unknown error"
return resolveLabel(labels).unknown
}
function isConfigInvalidErrorLike(error: unknown): error is ConfigInvalidError {
@@ -20,8 +37,8 @@ function isConfigInvalidErrorLike(error: unknown): error is ConfigInvalidError {
return o.name === "ConfigInvalidError" && typeof o.data === "object" && o.data !== null
}
export function parseReabaleConfigInvalidError(errorInput: ConfigInvalidError) {
const head = "Invalid configuration"
export function parseReabaleConfigInvalidError(errorInput: ConfigInvalidError, labels?: Partial<Label>) {
const head = resolveLabel(labels).invalidConfiguration
const file = errorInput.data.path && errorInput.data.path !== "config" ? errorInput.data.path : ""
const detail = errorInput.data.message?.trim() ?? ""
const issues = (errorInput.data.issues ?? []).map((issue) => {

View File

@@ -1,4 +1,12 @@
export function getRelativeTime(dateString: string): string {
type TimeKey =
| "common.time.justNow"
| "common.time.minutesAgo.short"
| "common.time.hoursAgo.short"
| "common.time.daysAgo.short"
type Translate = (key: TimeKey, params?: Record<string, string | number>) => string
export function getRelativeTime(dateString: string, t: Translate): string {
const date = new Date(dateString)
const now = new Date()
const diffMs = now.getTime() - date.getTime()
@@ -7,8 +15,8 @@ export function getRelativeTime(dateString: string): string {
const diffHours = Math.floor(diffMinutes / 60)
const diffDays = Math.floor(diffHours / 24)
if (diffSeconds < 60) return "Just now"
if (diffMinutes < 60) return `${diffMinutes}m ago`
if (diffHours < 24) return `${diffHours}h ago`
return `${diffDays}d ago`
if (diffSeconds < 60) return t("common.time.justNow")
if (diffMinutes < 60) return t("common.time.minutesAgo.short", { count: diffMinutes })
if (diffHours < 24) return t("common.time.hoursAgo.short", { count: diffHours })
return t("common.time.daysAgo.short", { count: diffDays })
}

View File

@@ -3,6 +3,32 @@ import { message } from "@tauri-apps/plugin-dialog"
import { initI18n, t } from "./i18n"
import { commands } from "./bindings"
function installError(error: unknown) {
const text = String(error)
if (text.includes("CLI installation is only supported on macOS & Linux")) {
return t("desktop.cli.error.unsupportedPlatform")
}
if (text.includes("Sidecar binary not found")) {
return t("desktop.cli.error.sidecarMissing")
}
if (text.includes("Failed to write install script")) {
return t("desktop.cli.error.scriptWriteFailed")
}
if (text.includes("Failed to set script permissions")) {
return t("desktop.cli.error.scriptPermissionFailed")
}
if (text.includes("Failed to run install script")) {
return t("desktop.cli.error.scriptRunFailed")
}
if (text.includes("Install script failed")) {
return t("desktop.cli.error.scriptFailed")
}
if (text.includes("Could not determine install path")) {
return t("desktop.cli.error.installPathUnknown")
}
return text || t("desktop.cli.error.unknown")
}
export async function installCli(): Promise<void> {
await initI18n()
@@ -10,6 +36,8 @@ export async function installCli(): Promise<void> {
const path = await commands.installCli()
await message(t("desktop.cli.installed.message", { path }), { title: t("desktop.cli.installed.title") })
} catch (e) {
await message(t("desktop.cli.failed.message", { error: String(e) }), { title: t("desktop.cli.failed.title") })
await message(t("desktop.cli.failed.message", { error: installError(e) }), {
title: t("desktop.cli.failed.title"),
})
}
}

View File

@@ -23,4 +23,37 @@ export const dict = {
"desktop.cli.installed.message": "تم تثبيت CLI في {{path}}\n\nأعد تشغيل الطرفية لاستخدام الأمر 'opencode'.",
"desktop.cli.failed.title": "فشل التثبيت",
"desktop.cli.failed.message": "فشل تثبيت CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "ملف",
"desktop.menu.edit": "تعديل",
"desktop.menu.view": "عرض",
"desktop.menu.help": "مساعدة",
"desktop.menu.file.newSession": "جلسة جديدة",
"desktop.menu.file.openProject": "فتح مشروع...",
"desktop.menu.view.toggleSidebar": "تبديل الشريط الجانبي",
"desktop.menu.view.toggleTerminal": "تبديل الطرفية",
"desktop.menu.view.toggleFileTree": "تبديل شجرة الملفات",
"desktop.menu.view.back": "رجوع",
"desktop.menu.view.forward": "تقدم",
"desktop.menu.view.previousSession": "الجلسة السابقة",
"desktop.menu.view.nextSession": "الجلسة التالية",
"desktop.menu.help.documentation": "وثائق OpenCode",
"desktop.menu.help.supportForum": "منتدى الدعم",
"desktop.menu.help.shareFeedback": "مشاركة التعليقات",
"desktop.menu.help.reportBug": "الإبلاغ عن خطأ",
"desktop.cli.error.unsupportedPlatform": "تثبيت CLI مدعوم فقط على macOS و Linux.",
"desktop.cli.error.sidecarMissing": "ملف OpenCode CLI الثنائي مفقود. حاول إعادة تثبيت تطبيق سطح المكتب.",
"desktop.cli.error.scriptWriteFailed": "فشل تحضير برنامج تثبيت CLI.",
"desktop.cli.error.scriptPermissionFailed": "فشل جعل برنامج تثبيت CLI قابلاً للتنفيذ.",
"desktop.cli.error.scriptRunFailed": "فشل تشغيل برنامج تثبيت CLI.",
"desktop.cli.error.scriptFailed": "فشل برنامج تثبيت CLI.",
"desktop.cli.error.installPathUnknown": "تعذر تحديد مكان تثبيت CLI.",
"desktop.cli.error.unknown": "خطأ تثبيت غير معروف",
"desktop.loading.status.initial": "لحظة من فضلك...",
"desktop.loading.status.done": "تم الانتهاء",
"desktop.loading.status.migrating": "جارٍ ترحيل قاعدة البيانات الخاصة بك",
"desktop.loading.status.waiting": "قد يستغرق هذا بضع دقائق",
"desktop.loading.progressAria": "تقدم ترحيل قاعدة البيانات",
"desktop.server.local": "خادم محلي",
}

View File

@@ -24,4 +24,38 @@ export const dict = {
"desktop.cli.installed.message": "CLI instalada em {{path}}\n\nReinicie seu terminal para usar o comando 'opencode'.",
"desktop.cli.failed.title": "Falha na instalação",
"desktop.cli.failed.message": "Falha ao instalar a CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Arquivo",
"desktop.menu.edit": "Editar",
"desktop.menu.view": "Visualizar",
"desktop.menu.help": "Ajuda",
"desktop.menu.file.newSession": "Nova Sessão",
"desktop.menu.file.openProject": "Abrir Projeto...",
"desktop.menu.view.toggleSidebar": "Alternar Barra Lateral",
"desktop.menu.view.toggleTerminal": "Alternar Terminal",
"desktop.menu.view.toggleFileTree": "Alternar Árvore de Arquivos",
"desktop.menu.view.back": "Voltar",
"desktop.menu.view.forward": "Avançar",
"desktop.menu.view.previousSession": "Sessão Anterior",
"desktop.menu.view.nextSession": "Próxima Sessão",
"desktop.menu.help.documentation": "Documentação do OpenCode",
"desktop.menu.help.supportForum": "Fórum de Suporte",
"desktop.menu.help.shareFeedback": "Compartilhar Feedback",
"desktop.menu.help.reportBug": "Relatar um Bug",
"desktop.cli.error.unsupportedPlatform": "A instalação da CLI é suportada apenas no macOS e Linux.",
"desktop.cli.error.sidecarMissing":
"O binário da CLI do OpenCode está ausente. Tente reinstalar o aplicativo de desktop.",
"desktop.cli.error.scriptWriteFailed": "Falha ao preparar o script de instalação da CLI.",
"desktop.cli.error.scriptPermissionFailed": "Falha ao tornar o script de instalação da CLI executável.",
"desktop.cli.error.scriptRunFailed": "Falha ao executar o script de instalação da CLI.",
"desktop.cli.error.scriptFailed": "O instalador da CLI falhou.",
"desktop.cli.error.installPathUnknown": "Não foi possível determinar onde a CLI foi instalada.",
"desktop.cli.error.unknown": "Erro de instalação desconhecido",
"desktop.loading.status.initial": "Só um momento...",
"desktop.loading.status.done": "Tudo pronto",
"desktop.loading.status.migrating": "Migrando seu banco de dados",
"desktop.loading.status.waiting": "Isso pode levar alguns minutos",
"desktop.loading.progressAria": "Progresso da migração do banco de dados",
"desktop.server.local": "Servidor Local",
}

View File

@@ -25,4 +25,38 @@ export const dict = {
"CLI je instaliran u {{path}}\n\nRestartuj terminal da bi koristio komandu 'opencode'.",
"desktop.cli.failed.title": "Instalacija nije uspjela",
"desktop.cli.failed.message": "Neuspjela instalacija CLI-a: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Datoteka",
"desktop.menu.edit": "Uredi",
"desktop.menu.view": "Prikaz",
"desktop.menu.help": "Pomoć",
"desktop.menu.file.newSession": "Nova sesija",
"desktop.menu.file.openProject": "Otvori projekat...",
"desktop.menu.view.toggleSidebar": "Prebaci bočnu traku",
"desktop.menu.view.toggleTerminal": "Prebaci terminal",
"desktop.menu.view.toggleFileTree": "Prebaci stablo datoteka",
"desktop.menu.view.back": "Nazad",
"desktop.menu.view.forward": "Naprijed",
"desktop.menu.view.previousSession": "Prethodna sesija",
"desktop.menu.view.nextSession": "Sljedeća sesija",
"desktop.menu.help.documentation": "OpenCode Dokumentacija",
"desktop.menu.help.supportForum": "Forum za podršku",
"desktop.menu.help.shareFeedback": "Podijeli povratne informacije",
"desktop.menu.help.reportBug": "Prijavi grešku",
"desktop.cli.error.unsupportedPlatform": "Instalacija CLI-a je podržana samo na macOS-u i Linux-u.",
"desktop.cli.error.sidecarMissing":
"Nedostaje binarna datoteka OpenCode CLI-a. Pokušaj ponovo instalirati desktop aplikaciju.",
"desktop.cli.error.scriptWriteFailed": "Nije uspjela priprema skripte za instalaciju CLI-a.",
"desktop.cli.error.scriptPermissionFailed": "Nije uspjelo postavljanje izvršnih dozvola za instalaciju CLI-a.",
"desktop.cli.error.scriptRunFailed": "Nije uspjelo pokretanje skripte za instalaciju CLI-a.",
"desktop.cli.error.scriptFailed": "Instalacija CLI-a nije uspjela.",
"desktop.cli.error.installPathUnknown": "Nije bilo moguće utvrditi gdje je instaliran CLI.",
"desktop.cli.error.unknown": "Nepoznata greška pri instalaciji",
"desktop.loading.status.initial": "Samo trenutak...",
"desktop.loading.status.done": "Sve je gotovo",
"desktop.loading.status.migrating": "Migracija baze podataka u toku",
"desktop.loading.status.waiting": "Ovo može potrajati nekoliko minuta",
"desktop.loading.progressAria": "Napredak migracije baze podataka",
"desktop.server.local": "Lokalni server",
}

View File

@@ -25,4 +25,37 @@ export const dict = {
"CLI installeret i {{path}}\n\nGenstart din terminal for at bruge 'opencode'-kommandoen.",
"desktop.cli.failed.title": "Installation mislykkedes",
"desktop.cli.failed.message": "Kunne ikke installere CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Filer",
"desktop.menu.edit": "Rediger",
"desktop.menu.view": "Vis",
"desktop.menu.help": "Hjælp",
"desktop.menu.file.newSession": "Ny session",
"desktop.menu.file.openProject": "Åbn projekt...",
"desktop.menu.view.toggleSidebar": "Slå sidepanel til/fra",
"desktop.menu.view.toggleTerminal": "Slå terminal til/fra",
"desktop.menu.view.toggleFileTree": "Slå filoversigt til/fra",
"desktop.menu.view.back": "Tilbage",
"desktop.menu.view.forward": "Fremad",
"desktop.menu.view.previousSession": "Forrige session",
"desktop.menu.view.nextSession": "Næste session",
"desktop.menu.help.documentation": "OpenCode Dokumentation",
"desktop.menu.help.supportForum": "Supportforum",
"desktop.menu.help.shareFeedback": "Del feedback",
"desktop.menu.help.reportBug": "Rapporter en fejl",
"desktop.cli.error.unsupportedPlatform": "CLI-installation understøttes kun på macOS og Linux.",
"desktop.cli.error.sidecarMissing": "OpenCode CLI-binærfil mangler. Prøv at geninstallere desktop-appen.",
"desktop.cli.error.scriptWriteFailed": "Kunne ikke forberede CLI-installationsscriptet.",
"desktop.cli.error.scriptPermissionFailed": "Kunne ikke gøre CLI-installationsscriptet eksekverbart.",
"desktop.cli.error.scriptRunFailed": "Kunne ikke køre CLI-installationsscriptet.",
"desktop.cli.error.scriptFailed": "CLI-installationsprogrammet mislykkedes.",
"desktop.cli.error.installPathUnknown": "Kunne ikke fastslå, hvor CLI'en blev installeret.",
"desktop.cli.error.unknown": "Ukendt installationsfejl",
"desktop.loading.status.initial": "Lige et øjeblik...",
"desktop.loading.status.done": "Helt færdig",
"desktop.loading.status.migrating": "Migrerer din database",
"desktop.loading.status.waiting": "Dette kan tage et par minutter",
"desktop.loading.progressAria": "Status for databasemigrering",
"desktop.server.local": "Lokal server",
}

View File

@@ -25,4 +25,38 @@ export const dict = {
"CLI wurde in {{path}} installiert\n\nStarten Sie Ihr Terminal neu, um den Befehl 'opencode' zu verwenden.",
"desktop.cli.failed.title": "Installation fehlgeschlagen",
"desktop.cli.failed.message": "CLI konnte nicht installiert werden: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Datei",
"desktop.menu.edit": "Bearbeiten",
"desktop.menu.view": "Ansicht",
"desktop.menu.help": "Hilfe",
"desktop.menu.file.newSession": "Neue Sitzung",
"desktop.menu.file.openProject": "Projekt öffnen...",
"desktop.menu.view.toggleSidebar": "Seitenleiste umschalten",
"desktop.menu.view.toggleTerminal": "Terminal umschalten",
"desktop.menu.view.toggleFileTree": "Dateibaum umschalten",
"desktop.menu.view.back": "Zurück",
"desktop.menu.view.forward": "Vorwärts",
"desktop.menu.view.previousSession": "Vorherige Sitzung",
"desktop.menu.view.nextSession": "Nächste Sitzung",
"desktop.menu.help.documentation": "OpenCode-Dokumentation",
"desktop.menu.help.supportForum": "Support-Forum",
"desktop.menu.help.shareFeedback": "Feedback teilen",
"desktop.menu.help.reportBug": "Einen Fehler melden",
"desktop.cli.error.unsupportedPlatform": "Die CLI-Installation wird nur unter macOS und Linux unterstützt.",
"desktop.cli.error.sidecarMissing":
"Das OpenCode CLI-Binary fehlt. Versuchen Sie, die Desktop-App neu zu installieren.",
"desktop.cli.error.scriptWriteFailed": "Das CLI-Installationsskript konnte nicht vorbereitet werden.",
"desktop.cli.error.scriptPermissionFailed": "Das CLI-Installationsskript konnte nicht ausführbar gemacht werden.",
"desktop.cli.error.scriptRunFailed": "Das CLI-Installationsskript konnte nicht ausgeführt werden.",
"desktop.cli.error.scriptFailed": "Das CLI-Installationsprogramm ist fehlgeschlagen.",
"desktop.cli.error.installPathUnknown": "Es konnte nicht ermittelt werden, wo die CLI installiert wurde.",
"desktop.cli.error.unknown": "Unbekannter Installationsfehler",
"desktop.loading.status.initial": "Einen Moment bitte...",
"desktop.loading.status.done": "Alles erledigt",
"desktop.loading.status.migrating": "Ihre Datenbank wird migriert",
"desktop.loading.status.waiting": "Dies kann einige Minuten dauern",
"desktop.loading.progressAria": "Fortschritt der Datenbankmigration",
"desktop.server.local": "Lokaler Server",
}

View File

@@ -3,6 +3,24 @@ export const dict = {
"desktop.menu.installCli": "Install CLI...",
"desktop.menu.reloadWebview": "Reload Webview",
"desktop.menu.restart": "Restart",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "File",
"desktop.menu.edit": "Edit",
"desktop.menu.view": "View",
"desktop.menu.help": "Help",
"desktop.menu.file.newSession": "New Session",
"desktop.menu.file.openProject": "Open Project...",
"desktop.menu.view.toggleSidebar": "Toggle Sidebar",
"desktop.menu.view.toggleTerminal": "Toggle Terminal",
"desktop.menu.view.toggleFileTree": "Toggle File Tree",
"desktop.menu.view.back": "Back",
"desktop.menu.view.forward": "Forward",
"desktop.menu.view.previousSession": "Previous Session",
"desktop.menu.view.nextSession": "Next Session",
"desktop.menu.help.documentation": "OpenCode Documentation",
"desktop.menu.help.supportForum": "Support Forum",
"desktop.menu.help.shareFeedback": "Share Feedback",
"desktop.menu.help.reportBug": "Report a Bug",
"desktop.dialog.chooseFolder": "Choose a folder",
"desktop.dialog.chooseFile": "Choose a file",
@@ -24,4 +42,20 @@ export const dict = {
"desktop.cli.installed.message": "CLI installed to {{path}}\n\nRestart your terminal to use the 'opencode' command.",
"desktop.cli.failed.title": "Installation Failed",
"desktop.cli.failed.message": "Failed to install CLI: {{error}}",
"desktop.cli.error.unsupportedPlatform": "CLI installation is only supported on macOS and Linux.",
"desktop.cli.error.sidecarMissing": "OpenCode CLI binary is missing. Try reinstalling the desktop app.",
"desktop.cli.error.scriptWriteFailed": "Failed to prepare CLI installer script.",
"desktop.cli.error.scriptPermissionFailed": "Failed to make CLI installer executable.",
"desktop.cli.error.scriptRunFailed": "Failed to run CLI installer script.",
"desktop.cli.error.scriptFailed": "CLI installer failed.",
"desktop.cli.error.installPathUnknown": "Could not determine where the CLI was installed.",
"desktop.cli.error.unknown": "Unknown installation error",
"desktop.loading.status.initial": "Just a moment...",
"desktop.loading.status.done": "All done",
"desktop.loading.status.migrating": "Migrating your database",
"desktop.loading.status.waiting": "This may take a couple of minutes",
"desktop.loading.progressAria": "Database migration progress",
"desktop.server.local": "Local Server",
}

View File

@@ -24,4 +24,38 @@ export const dict = {
"desktop.cli.installed.message": "CLI instalada en {{path}}\n\nReinicia tu terminal para usar el comando 'opencode'.",
"desktop.cli.failed.title": "Instalación fallida",
"desktop.cli.failed.message": "No se pudo instalar la CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Archivo",
"desktop.menu.edit": "Editar",
"desktop.menu.view": "Ver",
"desktop.menu.help": "Ayuda",
"desktop.menu.file.newSession": "Nueva sesión",
"desktop.menu.file.openProject": "Abrir proyecto...",
"desktop.menu.view.toggleSidebar": "Alternar barra lateral",
"desktop.menu.view.toggleTerminal": "Alternar terminal",
"desktop.menu.view.toggleFileTree": "Alternar árbol de archivos",
"desktop.menu.view.back": "Atrás",
"desktop.menu.view.forward": "Adelante",
"desktop.menu.view.previousSession": "Sesión anterior",
"desktop.menu.view.nextSession": "Siguiente sesión",
"desktop.menu.help.documentation": "Documentación de OpenCode",
"desktop.menu.help.supportForum": "Foro de soporte",
"desktop.menu.help.shareFeedback": "Compartir comentarios",
"desktop.menu.help.reportBug": "Informar de un error",
"desktop.cli.error.unsupportedPlatform": "La instalación de la CLI solo es compatible con macOS y Linux.",
"desktop.cli.error.sidecarMissing":
"Falta el binario de la CLI de OpenCode. Intenta reinstalar la aplicación de escritorio.",
"desktop.cli.error.scriptWriteFailed": "No se pudo preparar el script del instalador de la CLI.",
"desktop.cli.error.scriptPermissionFailed": "No se pudo hacer ejecutable el script del instalador de la CLI.",
"desktop.cli.error.scriptRunFailed": "No se pudo ejecutar el script del instalador de la CLI.",
"desktop.cli.error.scriptFailed": "El instalador de la CLI falló.",
"desktop.cli.error.installPathUnknown": "No se pudo determinar dónde se instaló la CLI.",
"desktop.cli.error.unknown": "Error de instalación desconocido",
"desktop.loading.status.initial": "Un momento...",
"desktop.loading.status.done": "Todo listo",
"desktop.loading.status.migrating": "Migrando tu base de datos",
"desktop.loading.status.waiting": "Esto puede tardar unos minutos",
"desktop.loading.progressAria": "Progreso de migración de la base de datos",
"desktop.server.local": "Servidor local",
}

View File

@@ -25,4 +25,38 @@ export const dict = {
"CLI installée dans {{path}}\n\nRedémarrez votre terminal pour utiliser la commande 'opencode'.",
"desktop.cli.failed.title": "Échec de l'installation",
"desktop.cli.failed.message": "Impossible d'installer la CLI : {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Fichier",
"desktop.menu.edit": "Édition",
"desktop.menu.view": "Affichage",
"desktop.menu.help": "Aide",
"desktop.menu.file.newSession": "Nouvelle session",
"desktop.menu.file.openProject": "Ouvrir un projet...",
"desktop.menu.view.toggleSidebar": "Basculer la barre latérale",
"desktop.menu.view.toggleTerminal": "Basculer le terminal",
"desktop.menu.view.toggleFileTree": "Basculer l'arborescence des fichiers",
"desktop.menu.view.back": "Retour",
"desktop.menu.view.forward": "Suivant",
"desktop.menu.view.previousSession": "Session précédente",
"desktop.menu.view.nextSession": "Session suivante",
"desktop.menu.help.documentation": "Documentation d'OpenCode",
"desktop.menu.help.supportForum": "Forum d'assistance",
"desktop.menu.help.shareFeedback": "Partager des commentaires",
"desktop.menu.help.reportBug": "Signaler un bug",
"desktop.cli.error.unsupportedPlatform": "L'installation de la CLI n'est prise en charge que sur macOS et Linux.",
"desktop.cli.error.sidecarMissing":
"Le binaire de la CLI OpenCode est manquant. Essayez de réinstaller l'application de bureau.",
"desktop.cli.error.scriptWriteFailed": "Impossible de préparer le script d'installation de la CLI.",
"desktop.cli.error.scriptPermissionFailed": "Impossible de rendre le script d'installation de la CLI exécutable.",
"desktop.cli.error.scriptRunFailed": "Impossible d'exécuter le script d'installation de la CLI.",
"desktop.cli.error.scriptFailed": "L'installateur de la CLI a échoué.",
"desktop.cli.error.installPathUnknown": "Impossible de déterminer où la CLI a été installée.",
"desktop.cli.error.unknown": "Erreur d'installation inconnue",
"desktop.loading.status.initial": "Un instant...",
"desktop.loading.status.done": "Terminé",
"desktop.loading.status.migrating": "Migration de votre base de données",
"desktop.loading.status.waiting": "Cela peut prendre quelques minutes",
"desktop.loading.progressAria": "Progression de la migration de la base de données",
"desktop.server.local": "Serveur local",
}

View File

@@ -25,4 +25,38 @@ export const dict = {
"CLI を {{path}} にインストールしました\n\nターミナルを再起動して 'opencode' コマンドを使用してください。",
"desktop.cli.failed.title": "インストールに失敗しました",
"desktop.cli.failed.message": "CLI のインストールに失敗しました: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "ファイル",
"desktop.menu.edit": "編集",
"desktop.menu.view": "表示",
"desktop.menu.help": "ヘルプ",
"desktop.menu.file.newSession": "新しいセッション",
"desktop.menu.file.openProject": "プロジェクトを開く...",
"desktop.menu.view.toggleSidebar": "サイドバーの切り替え",
"desktop.menu.view.toggleTerminal": "ターミナルの切り替え",
"desktop.menu.view.toggleFileTree": "ファイルツリーの切り替え",
"desktop.menu.view.back": "戻る",
"desktop.menu.view.forward": "進む",
"desktop.menu.view.previousSession": "前のセッション",
"desktop.menu.view.nextSession": "次のセッション",
"desktop.menu.help.documentation": "OpenCode ドキュメント",
"desktop.menu.help.supportForum": "サポートフォーラム",
"desktop.menu.help.shareFeedback": "フィードバックを共有",
"desktop.menu.help.reportBug": "バグを報告",
"desktop.cli.error.unsupportedPlatform": "CLI のインストールは macOS と Linux のみでサポートされています。",
"desktop.cli.error.sidecarMissing":
"OpenCode CLI のバイナリが見つかりません。デスクトップアプリを再インストールしてみてください。",
"desktop.cli.error.scriptWriteFailed": "CLI インストーラースクリプトの準備に失敗しました。",
"desktop.cli.error.scriptPermissionFailed": "CLI インストーラースクリプトに実行権限を付与できませんでした。",
"desktop.cli.error.scriptRunFailed": "CLI インストーラースクリプトの実行に失敗しました。",
"desktop.cli.error.scriptFailed": "CLI インストーラーが失敗しました。",
"desktop.cli.error.installPathUnknown": "CLI がどこにインストールされたか特定できませんでした。",
"desktop.cli.error.unknown": "不明なインストールエラー",
"desktop.loading.status.initial": "少々お待ちください...",
"desktop.loading.status.done": "完了しました",
"desktop.loading.status.migrating": "データベースを移行しています",
"desktop.loading.status.waiting": "これには数分かかる場合があります",
"desktop.loading.progressAria": "データベース移行の進行状況",
"desktop.server.local": "ローカルサーバー",
}

View File

@@ -24,4 +24,37 @@ export const dict = {
"CLI가 {{path}}에 설치되었습니다\n\n터미널을 다시 시작하여 'opencode' 명령을 사용하세요.",
"desktop.cli.failed.title": "설치 실패",
"desktop.cli.failed.message": "CLI 설치 실패: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "파일",
"desktop.menu.edit": "편집",
"desktop.menu.view": "보기",
"desktop.menu.help": "도움말",
"desktop.menu.file.newSession": "새 세션",
"desktop.menu.file.openProject": "프로젝트 열기...",
"desktop.menu.view.toggleSidebar": "사이드바 전환",
"desktop.menu.view.toggleTerminal": "터미널 전환",
"desktop.menu.view.toggleFileTree": "파일 트리 전환",
"desktop.menu.view.back": "뒤로",
"desktop.menu.view.forward": "앞으로",
"desktop.menu.view.previousSession": "이전 세션",
"desktop.menu.view.nextSession": "다음 세션",
"desktop.menu.help.documentation": "OpenCode 문서",
"desktop.menu.help.supportForum": "지원 포럼",
"desktop.menu.help.shareFeedback": "피드백 공유",
"desktop.menu.help.reportBug": "버그 신고",
"desktop.cli.error.unsupportedPlatform": "CLI 설치는 macOS 및 Linux에서만 지원됩니다.",
"desktop.cli.error.sidecarMissing": "OpenCode CLI 바이너리가 누락되었습니다. 데스크톱 앱을 다시 설치해 보세요.",
"desktop.cli.error.scriptWriteFailed": "CLI 설치 스크립트를 준비하지 못했습니다.",
"desktop.cli.error.scriptPermissionFailed": "CLI 설치 스크립트를 실행 가능하게 만들지 못했습니다.",
"desktop.cli.error.scriptRunFailed": "CLI 설치 스크립트를 실행하지 못했습니다.",
"desktop.cli.error.scriptFailed": "CLI 설치 프로그램이 실패했습니다.",
"desktop.cli.error.installPathUnknown": "CLI가 어디에 설치되었는지 확인할 수 없습니다.",
"desktop.cli.error.unknown": "알 수 없는 설치 오류",
"desktop.loading.status.initial": "잠시만 기다려 주세요...",
"desktop.loading.status.done": "모두 완료되었습니다",
"desktop.loading.status.migrating": "데이터베이스 마이그레이션 중",
"desktop.loading.status.waiting": "이 작업은 몇 분 정도 걸릴 수 있습니다",
"desktop.loading.progressAria": "데이터베이스 마이그레이션 진행률",
"desktop.server.local": "로컬 서버",
}

View File

@@ -25,4 +25,37 @@ export const dict = {
"CLI installert til {{path}}\n\nStart terminalen på nytt for å bruke 'opencode'-kommandoen.",
"desktop.cli.failed.title": "Installasjon mislyktes",
"desktop.cli.failed.message": "Kunne ikke installere CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Fil",
"desktop.menu.edit": "Rediger",
"desktop.menu.view": "Vis",
"desktop.menu.help": "Hjelp",
"desktop.menu.file.newSession": "Ny sesjon",
"desktop.menu.file.openProject": "Åpne prosjekt...",
"desktop.menu.view.toggleSidebar": "Vis/skjul sidefelt",
"desktop.menu.view.toggleTerminal": "Vis/skjul terminal",
"desktop.menu.view.toggleFileTree": "Vis/skjul filtre",
"desktop.menu.view.back": "Tilbake",
"desktop.menu.view.forward": "Frem",
"desktop.menu.view.previousSession": "Forrige sesjon",
"desktop.menu.view.nextSession": "Neste sesjon",
"desktop.menu.help.documentation": "OpenCode Dokumentasjon",
"desktop.menu.help.supportForum": "Støtteforum",
"desktop.menu.help.shareFeedback": "Del tilbakemelding",
"desktop.menu.help.reportBug": "Rapporter en feil",
"desktop.cli.error.unsupportedPlatform": "CLI-installasjon støttes kun på macOS og Linux.",
"desktop.cli.error.sidecarMissing": "OpenCode CLI-binærfil mangler. Prøv å installere skrivebordsappen på nytt.",
"desktop.cli.error.scriptWriteFailed": "Kunne ikke klargjøre CLI-installasjonsskriptet.",
"desktop.cli.error.scriptPermissionFailed": "Kunne ikke gjøre CLI-installasjonsskriptet kjørbart.",
"desktop.cli.error.scriptRunFailed": "Kunne ikke kjøre CLI-installasjonsskriptet.",
"desktop.cli.error.scriptFailed": "CLI-installasjonsprogrammet mislyktes.",
"desktop.cli.error.installPathUnknown": "Kunne ikke avgjøre hvor CLI ble installert.",
"desktop.cli.error.unknown": "Ukjent installasjonsfeil",
"desktop.loading.status.initial": "Et øyeblikk...",
"desktop.loading.status.done": "Alt ferdig",
"desktop.loading.status.migrating": "Migrerer databasen din",
"desktop.loading.status.waiting": "Dette kan ta et par minutter",
"desktop.loading.progressAria": "Fremdrift for databasemigrering",
"desktop.server.local": "Lokal server",
}

View File

@@ -25,4 +25,38 @@ export const dict = {
"CLI zainstalowane w {{path}}\n\nUruchom ponownie terminal, aby użyć polecenia 'opencode'.",
"desktop.cli.failed.title": "Instalacja nie powiodła się",
"desktop.cli.failed.message": "Nie udało się zainstalować CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Plik",
"desktop.menu.edit": "Edycja",
"desktop.menu.view": "Widok",
"desktop.menu.help": "Pomoc",
"desktop.menu.file.newSession": "Nowa sesja",
"desktop.menu.file.openProject": "Otwórz projekt...",
"desktop.menu.view.toggleSidebar": "Przełącz pasek boczny",
"desktop.menu.view.toggleTerminal": "Przełącz terminal",
"desktop.menu.view.toggleFileTree": "Przełącz drzewo plików",
"desktop.menu.view.back": "Wstecz",
"desktop.menu.view.forward": "Dalej",
"desktop.menu.view.previousSession": "Poprzednia sesja",
"desktop.menu.view.nextSession": "Następna sesja",
"desktop.menu.help.documentation": "Dokumentacja OpenCode",
"desktop.menu.help.supportForum": "Forum wsparcia",
"desktop.menu.help.shareFeedback": "Prześlij opinię",
"desktop.menu.help.reportBug": "Zgłoś błąd",
"desktop.cli.error.unsupportedPlatform": "Instalacja CLI jest obsługiwana tylko na macOS i Linux.",
"desktop.cli.error.sidecarMissing":
"Brakuje pliku binarnego OpenCode CLI. Spróbuj ponownie zainstalować aplikację na komputer.",
"desktop.cli.error.scriptWriteFailed": "Nie udało się przygotować skryptu instalatora CLI.",
"desktop.cli.error.scriptPermissionFailed": "Nie udało się nadać uprawnień do wykonania skryptu instalatora CLI.",
"desktop.cli.error.scriptRunFailed": "Nie udało się uruchomić skryptu instalatora CLI.",
"desktop.cli.error.scriptFailed": "Instalator CLI nie powiódł się.",
"desktop.cli.error.installPathUnknown": "Nie udało się ustalić, gdzie zostało zainstalowane CLI.",
"desktop.cli.error.unknown": "Nieznany błąd instalacji",
"desktop.loading.status.initial": "Chwileczkę...",
"desktop.loading.status.done": "Gotowe",
"desktop.loading.status.migrating": "Migrowanie bazy danych",
"desktop.loading.status.waiting": "Może to potrwać kilka minut",
"desktop.loading.progressAria": "Postęp migracji bazy danych",
"desktop.server.local": "Serwer lokalny",
}

View File

@@ -24,4 +24,38 @@ export const dict = {
"CLI установлен в {{path}}\n\nПерезапустите терминал, чтобы использовать команду 'opencode'.",
"desktop.cli.failed.title": "Ошибка установки",
"desktop.cli.failed.message": "Не удалось установить CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Файл",
"desktop.menu.edit": "Правка",
"desktop.menu.view": "Вид",
"desktop.menu.help": "Справка",
"desktop.menu.file.newSession": "Новая сессия",
"desktop.menu.file.openProject": "Открыть проект...",
"desktop.menu.view.toggleSidebar": "Переключить боковую панель",
"desktop.menu.view.toggleTerminal": "Переключить терминал",
"desktop.menu.view.toggleFileTree": "Переключить дерево файлов",
"desktop.menu.view.back": "Назад",
"desktop.menu.view.forward": "Вперед",
"desktop.menu.view.previousSession": "Предыдущая сессия",
"desktop.menu.view.nextSession": "Следующая сессия",
"desktop.menu.help.documentation": "Документация OpenCode",
"desktop.menu.help.supportForum": "Форум поддержки",
"desktop.menu.help.shareFeedback": "Поделиться отзывом",
"desktop.menu.help.reportBug": "Сообщить об ошибке",
"desktop.cli.error.unsupportedPlatform": "Установка CLI поддерживается только в macOS и Linux.",
"desktop.cli.error.sidecarMissing":
"Отсутствует бинарный файл OpenCode CLI. Попробуйте переустановить настольное приложение.",
"desktop.cli.error.scriptWriteFailed": "Не удалось подготовить скрипт установщика CLI.",
"desktop.cli.error.scriptPermissionFailed": "Не удалось сделать скрипт установщика CLI исполняемым.",
"desktop.cli.error.scriptRunFailed": "Не удалось запустить скрипт установщика CLI.",
"desktop.cli.error.scriptFailed": "Ошибка установщика CLI.",
"desktop.cli.error.installPathUnknown": "Не удалось определить, куда был установлен CLI.",
"desktop.cli.error.unknown": "Неизвестная ошибка установки",
"desktop.loading.status.initial": "Минуточку...",
"desktop.loading.status.done": "Всё готово",
"desktop.loading.status.migrating": "Миграция вашей базы данных",
"desktop.loading.status.waiting": "Это может занять пару минут",
"desktop.loading.progressAria": "Прогресс миграции базы данных",
"desktop.server.local": "Локальный сервер",
}

View File

@@ -23,4 +23,37 @@ export const dict = {
"desktop.cli.installed.message": "CLI 已安装到 {{path}}\n\n重启终端以使用 'opencode' 命令。",
"desktop.cli.failed.title": "安装失败",
"desktop.cli.failed.message": "无法安装 CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "文件",
"desktop.menu.edit": "编辑",
"desktop.menu.view": "查看",
"desktop.menu.help": "帮助",
"desktop.menu.file.newSession": "新会话",
"desktop.menu.file.openProject": "打开项目...",
"desktop.menu.view.toggleSidebar": "切换侧边栏",
"desktop.menu.view.toggleTerminal": "切换终端",
"desktop.menu.view.toggleFileTree": "切换文件树",
"desktop.menu.view.back": "后退",
"desktop.menu.view.forward": "前进",
"desktop.menu.view.previousSession": "上一个会话",
"desktop.menu.view.nextSession": "下一个会话",
"desktop.menu.help.documentation": "OpenCode 文档",
"desktop.menu.help.supportForum": "支持论坛",
"desktop.menu.help.shareFeedback": "分享反馈",
"desktop.menu.help.reportBug": "报告错误",
"desktop.cli.error.unsupportedPlatform": "CLI 安装仅在 macOS 和 Linux 上受支持。",
"desktop.cli.error.sidecarMissing": "OpenCode CLI 二进制文件缺失。请尝试重新安装桌面应用程序。",
"desktop.cli.error.scriptWriteFailed": "无法准备 CLI 安装脚本。",
"desktop.cli.error.scriptPermissionFailed": "无法使 CLI 安装脚本可执行。",
"desktop.cli.error.scriptRunFailed": "无法运行 CLI 安装脚本。",
"desktop.cli.error.scriptFailed": "CLI 安装程序失败。",
"desktop.cli.error.installPathUnknown": "无法确定 CLI 的安装位置。",
"desktop.cli.error.unknown": "未知的安装错误",
"desktop.loading.status.initial": "稍等片刻...",
"desktop.loading.status.done": "全部完成",
"desktop.loading.status.migrating": "正在迁移您的数据库",
"desktop.loading.status.waiting": "这可能需要几分钟",
"desktop.loading.progressAria": "数据库迁移进度",
"desktop.server.local": "本地服务器",
}

View File

@@ -23,4 +23,37 @@ export const dict = {
"desktop.cli.installed.message": "CLI 已安裝到 {{path}}\n\n重新啟動終端機以使用 'opencode' 命令。",
"desktop.cli.failed.title": "安裝失敗",
"desktop.cli.failed.message": "無法安裝 CLI: {{error}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "檔案",
"desktop.menu.edit": "編輯",
"desktop.menu.view": "檢視",
"desktop.menu.help": "說明",
"desktop.menu.file.newSession": "新工作階段",
"desktop.menu.file.openProject": "開啟專案...",
"desktop.menu.view.toggleSidebar": "切換側邊欄",
"desktop.menu.view.toggleTerminal": "切換終端機",
"desktop.menu.view.toggleFileTree": "切換檔案樹",
"desktop.menu.view.back": "上一步",
"desktop.menu.view.forward": "下一步",
"desktop.menu.view.previousSession": "上一個工作階段",
"desktop.menu.view.nextSession": "下一個工作階段",
"desktop.menu.help.documentation": "OpenCode 文件",
"desktop.menu.help.supportForum": "支援論壇",
"desktop.menu.help.shareFeedback": "分享意見回饋",
"desktop.menu.help.reportBug": "回報錯誤",
"desktop.cli.error.unsupportedPlatform": "CLI 安裝僅支援 macOS 與 Linux。",
"desktop.cli.error.sidecarMissing": "OpenCode CLI 執行檔遺失。請嘗試重新安裝桌面應用程式。",
"desktop.cli.error.scriptWriteFailed": "無法準備 CLI 安裝指令碼。",
"desktop.cli.error.scriptPermissionFailed": "無法將 CLI 安裝指令碼設為可執行。",
"desktop.cli.error.scriptRunFailed": "無法執行 CLI 安裝指令碼。",
"desktop.cli.error.scriptFailed": "CLI 安裝程式失敗。",
"desktop.cli.error.installPathUnknown": "無法確定 CLI 的安裝位置。",
"desktop.cli.error.unknown": "未知的安裝錯誤",
"desktop.loading.status.initial": "稍等片刻...",
"desktop.loading.status.done": "全部完成",
"desktop.loading.status.migrating": "正在移轉您的資料庫",
"desktop.loading.status.waiting": "這可能需要幾分鐘",
"desktop.loading.progressAria": "資料庫移轉進度",
"desktop.server.local": "本機伺服器",
}

View File

@@ -445,7 +445,7 @@ render(() => {
}
const server: ServerConnection.Any = data.is_sidecar
? {
displayName: "Local Server",
displayName: t("desktop.server.local"),
type: "sidecar",
variant: "base",
http,

View File

@@ -8,11 +8,18 @@ import "./styles.css"
import { createEffect, createMemo, createSignal, onCleanup, onMount } from "solid-js"
import { commands, events, InitStep } from "./bindings"
import { Channel } from "@tauri-apps/api/core"
import { initI18n, t } from "./i18n"
const root = document.getElementById("root")!
const lines = ["Just a moment...", "Migrating your database", "This may take a couple of minutes"]
const lines = [
t("desktop.loading.status.initial"),
t("desktop.loading.status.migrating"),
t("desktop.loading.status.waiting"),
]
const delays = [3000, 9000]
void initI18n()
render(() => {
const [step, setStep] = createSignal<InitStep | null>(null)
const [line, setLine] = createSignal(0)
@@ -54,9 +61,9 @@ render(() => {
})
const status = createMemo(() => {
if (phase() === "done") return "All done"
if (phase() === "done") return t("desktop.loading.status.done")
if (phase() === "sqlite_waiting") return lines[line()]
return "Just a moment..."
return t("desktop.loading.status.initial")
})
return (
@@ -72,7 +79,7 @@ render(() => {
<Progress
value={value()}
class="w-20 [&_[data-slot='progress-track']]:h-1 [&_[data-slot='progress-track']]:border-0 [&_[data-slot='progress-track']]:rounded-none [&_[data-slot='progress-track']]:bg-surface-weak [&_[data-slot='progress-fill']]:rounded-none [&_[data-slot='progress-fill']]:bg-icon-warning-base"
aria-label="Database migration progress"
aria-label={t("desktop.loading.progressAria")}
getValueLabel={({ value }) => `${Math.round(value)}%`}
/>
</div>

View File

@@ -16,7 +16,7 @@ export async function createMenu(trigger: (id: string) => void) {
const menu = await Menu.new({
items: [
await Submenu.new({
text: "OpenCode",
text: t("desktop.menu.app"),
items: [
await PredefinedMenuItem.new({
item: { About: null },
@@ -62,15 +62,15 @@ export async function createMenu(trigger: (id: string) => void) {
].filter(Boolean),
}),
await Submenu.new({
text: "File",
text: t("desktop.menu.file"),
items: [
await MenuItem.new({
text: "New Session",
text: t("desktop.menu.file.newSession"),
accelerator: "Shift+Cmd+S",
action: () => trigger("session.new"),
}),
await MenuItem.new({
text: "Open Project...",
text: t("desktop.menu.file.openProject"),
accelerator: "Cmd+O",
action: () => trigger("project.open"),
}),
@@ -83,7 +83,7 @@ export async function createMenu(trigger: (id: string) => void) {
],
}),
await Submenu.new({
text: "Edit",
text: t("desktop.menu.edit"),
items: [
await PredefinedMenuItem.new({
item: "Undo",
@@ -109,44 +109,44 @@ export async function createMenu(trigger: (id: string) => void) {
],
}),
await Submenu.new({
text: "View",
text: t("desktop.menu.view"),
items: [
await MenuItem.new({
action: () => trigger("sidebar.toggle"),
text: "Toggle Sidebar",
text: t("desktop.menu.view.toggleSidebar"),
accelerator: "Cmd+B",
}),
await MenuItem.new({
action: () => trigger("terminal.toggle"),
text: "Toggle Terminal",
text: t("desktop.menu.view.toggleTerminal"),
accelerator: "Ctrl+`",
}),
await MenuItem.new({
action: () => trigger("fileTree.toggle"),
text: "Toggle File Tree",
text: t("desktop.menu.view.toggleFileTree"),
}),
await PredefinedMenuItem.new({
item: "Separator",
}),
await MenuItem.new({
action: () => trigger("common.goBack"),
text: "Back",
text: t("desktop.menu.view.back"),
}),
await MenuItem.new({
action: () => trigger("common.goForward"),
text: "Forward",
text: t("desktop.menu.view.forward"),
}),
await PredefinedMenuItem.new({
item: "Separator",
}),
await MenuItem.new({
action: () => trigger("session.previous"),
text: "Previous Session",
text: t("desktop.menu.view.previousSession"),
accelerator: "Option+ArrowUp",
}),
await MenuItem.new({
action: () => trigger("session.next"),
text: "Next Session",
text: t("desktop.menu.view.nextSession"),
accelerator: "Option+ArrowDown",
}),
await PredefinedMenuItem.new({
@@ -155,16 +155,16 @@ export async function createMenu(trigger: (id: string) => void) {
],
}),
await Submenu.new({
text: "Help",
text: t("desktop.menu.help"),
items: [
// missing native macos search
await MenuItem.new({
action: () => openUrl("https://opencode.ai/docs"),
text: "OpenCode Documentation",
text: t("desktop.menu.help.documentation"),
}),
await MenuItem.new({
action: () => openUrl("https://discord.com/invite/opencode"),
text: "Support Forum",
text: t("desktop.menu.help.supportForum"),
}),
await PredefinedMenuItem.new({
item: "Separator",
@@ -177,11 +177,11 @@ export async function createMenu(trigger: (id: string) => void) {
}),
await MenuItem.new({
action: () => openUrl("https://github.com/anomalyco/opencode/issues/new?template=feature_request.yml"),
text: "Share Feedback",
text: t("desktop.menu.help.shareFeedback"),
}),
await MenuItem.new({
action: () => openUrl("https://github.com/anomalyco/opencode/issues/new?template=bug_report.yml"),
text: "Report a Bug",
text: t("desktop.menu.help.reportBug"),
}),
],
}),

View File

@@ -56,8 +56,9 @@ function detectLocale() {
function UiI18nBridge(props: ParentProps) {
const locale = createMemo(() => detectLocale())
const zh = uiZh as Partial<Record<string, string>>
const t = (key: keyof typeof uiEn, params?: UiI18nParams) => {
const value = locale() === "zh" ? (uiZh[key] ?? uiEn[key]) : uiEn[key]
const value = locale() === "zh" ? (zh[key] ?? uiEn[key]) : uiEn[key]
const text = value ?? String(key)
return resolveTemplate(text, params)
}

View File

@@ -463,14 +463,22 @@ function contextToolTrigger(part: ToolPart, i18n: ReturnType<typeof useI18n>) {
}
}
function contextToolSummary(parts: ToolPart[]) {
function contextToolSummary(parts: ToolPart[], i18n: ReturnType<typeof useI18n>) {
const read = parts.filter((part) => part.tool === "read").length
const search = parts.filter((part) => part.tool === "glob" || part.tool === "grep").length
const list = parts.filter((part) => part.tool === "list").length
return [
read ? `${read} ${read === 1 ? "read" : "reads"}` : undefined,
search ? `${search} ${search === 1 ? "search" : "searches"}` : undefined,
list ? `${list} ${list === 1 ? "list" : "lists"}` : undefined,
read
? i18n.t(read === 1 ? "ui.messagePart.context.read.one" : "ui.messagePart.context.read.other", { count: read })
: undefined,
search
? i18n.t(search === 1 ? "ui.messagePart.context.search.one" : "ui.messagePart.context.search.other", {
count: search,
})
: undefined,
list
? i18n.t(list === 1 ? "ui.messagePart.context.list.one" : "ui.messagePart.context.list.other", { count: list })
: undefined,
].filter((value): value is string => !!value)
}
@@ -595,7 +603,7 @@ function ContextToolGroup(props: { parts: ToolPart[]; busy?: boolean }) {
() =>
!!props.busy || props.parts.some((part) => part.state.status === "pending" || part.state.status === "running"),
)
const summary = createMemo(() => contextToolSummary(props.parts))
const summary = createMemo(() => contextToolSummary(props.parts, i18n))
const details = createMemo(() => summary().join(", "))
return (
@@ -979,7 +987,7 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
return (
<div style="width: 100%; display: flex; justify-content: flex-end;">
<span class="text-13-regular text-text-weak cursor-default">
{i18n.t("ui.tool.questions")} dismissed
{i18n.t("ui.messagePart.questions.dismissed")}
</span>
</div>
)

View File

@@ -1,4 +1,5 @@
import { createSignal, onCleanup, onMount, splitProps, type ComponentProps, Show, mergeProps } from "solid-js"
import { useI18n } from "../context/i18n"
export interface ScrollViewProps extends ComponentProps<"div"> {
viewportRef?: (el: HTMLDivElement) => void
@@ -6,6 +7,7 @@ export interface ScrollViewProps extends ComponentProps<"div"> {
}
export function ScrollView(props: ScrollViewProps) {
const i18n = useI18n()
const merged = mergeProps({ orientation: "vertical" }, props)
const [local, events, rest] = splitProps(
merged,
@@ -188,7 +190,7 @@ export function ScrollView(props: ScrollViewProps) {
onClick={events.onClick as any}
tabIndex={0}
role="region"
aria-label="scrollable content"
aria-label={i18n.t("ui.scrollView.ariaLabel")}
onKeyDown={(e) => {
onKeyDown(e)
if (typeof events.onKeyDown === "function") events.onKeyDown(e as any)

View File

@@ -16,18 +16,8 @@ import { useFileComponent } from "../context/file"
import { useI18n } from "../context/i18n"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
import { checksum } from "@opencode-ai/util/encode"
import {
createEffect,
createMemo,
createSignal,
For,
Match,
onCleanup,
Show,
Switch,
untrack,
type JSX,
} from "solid-js"
import { createEffect, createMemo, createSignal, For, Match, Show, Switch, untrack, type JSX } from "solid-js"
import { onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
@@ -191,6 +181,15 @@ export const SessionReview = (props: SessionReviewProps) => {
highlightedFile = undefined
}
const openFileLabel = () => i18n.t("ui.sessionReview.openFile")
const selectionLabel = (range: SelectedLineRange) => {
const start = Math.min(range.start, range.end)
const end = Math.max(range.start, range.end)
if (start === end) return i18n.t("ui.sessionReview.selection.line", { line: start })
return i18n.t("ui.sessionReview.selection.lines", { start, end })
}
const focusSearch = () => {
if (!hasDiffs()) return
setSearchOpen(true)
@@ -475,7 +474,8 @@ export const SessionReview = (props: SessionReviewProps) => {
const wrapper = anchors.get(focus.file)
const anchor = wrapper?.querySelector(`[data-comment-id="${focus.id}"]`)
const ready = anchor instanceof HTMLElement
const ready =
anchor instanceof HTMLElement && anchor.style.pointerEvents !== "none" && anchor.style.opacity !== "0"
const target = ready ? anchor : wrapper
if (!target) {
@@ -751,11 +751,11 @@ export const SessionReview = (props: SessionReviewProps) => {
</Show>
<span data-slot="session-review-filename">{getFilename(file)}</span>
<Show when={props.onViewFile}>
<Tooltip value="Open file" placement="top" gutter={4}>
<Tooltip value={openFileLabel()} placement="top" gutter={4}>
<button
data-slot="session-review-view-button"
type="button"
aria-label="Open file"
aria-label={openFileLabel()}
onClick={(e) => {
e.stopPropagation()
props.onViewFile?.(file)

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "تغييرات آخر دور",
"ui.sessionReview.diffStyle.unified": "موحد",
"ui.sessionReview.diffStyle.split": "منقسم",
"ui.sessionReview.openFile": "فتح ملف",
"ui.sessionReview.selection.line": "سطر {{line}}",
"ui.sessionReview.selection.lines": "الأسطر {{start}}-{{end}}",
"ui.sessionReview.expandAll": "توسيع الكل",
"ui.sessionReview.collapseAll": "طي الكل",
"ui.sessionReview.change.added": "مضاف",
@@ -53,6 +56,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "جمع الأفكار",
"ui.sessionTurn.status.consideringNextSteps": "النظر في الخطوات التالية",
"ui.messagePart.questions.dismissed": "تم رفض الأسئلة",
"ui.messagePart.context.read.one": "{{count}} قراءة",
"ui.messagePart.context.read.other": "{{count}} قراءات",
"ui.messagePart.context.search.one": "{{count}} بحث",
"ui.messagePart.context.search.other": "{{count}} عمليات بحث",
"ui.messagePart.context.list.one": "{{count}} قائمة",
"ui.messagePart.context.list.other": "{{count}} قوائم",
"ui.messagePart.diagnostic.error": "خطأ",
"ui.messagePart.title.edit": "تحرير",
"ui.messagePart.title.write": "كتابة",
@@ -72,6 +82,7 @@ export const dict = {
"ui.textField.copied": "تم النسخ",
"ui.imagePreview.alt": "معاينة الصورة",
"ui.scrollView.ariaLabel": "محتوى قابل للتمرير",
"ui.tool.read": "قراءة",
"ui.tool.loaded": "تم التحميل",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Alterações do último turno",
"ui.sessionReview.diffStyle.unified": "Unificado",
"ui.sessionReview.diffStyle.split": "Dividido",
"ui.sessionReview.openFile": "Abrir arquivo",
"ui.sessionReview.selection.line": "linha {{line}}",
"ui.sessionReview.selection.lines": "linhas {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Expandir tudo",
"ui.sessionReview.collapseAll": "Recolher tudo",
"ui.sessionReview.change.added": "Adicionado",
@@ -53,6 +56,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Organizando pensamentos",
"ui.sessionTurn.status.consideringNextSteps": "Considerando próximos passos",
"ui.messagePart.questions.dismissed": "Perguntas descartadas",
"ui.messagePart.context.read.one": "{{count}} leitura",
"ui.messagePart.context.read.other": "{{count}} leituras",
"ui.messagePart.context.search.one": "{{count}} pesquisa",
"ui.messagePart.context.search.other": "{{count}} pesquisas",
"ui.messagePart.context.list.one": "{{count}} lista",
"ui.messagePart.context.list.other": "{{count}} listas",
"ui.messagePart.diagnostic.error": "Erro",
"ui.messagePart.title.edit": "Editar",
"ui.messagePart.title.write": "Escrever",
@@ -72,6 +82,7 @@ export const dict = {
"ui.textField.copied": "Copiado",
"ui.imagePreview.alt": "Visualização de imagem",
"ui.scrollView.ariaLabel": "conteúdo rolável",
"ui.tool.read": "Ler",
"ui.tool.loaded": "Carregado",

View File

@@ -7,6 +7,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Promjene u posljednjem potezu",
"ui.sessionReview.diffStyle.unified": "Ujedinjeno",
"ui.sessionReview.diffStyle.split": "Podijeljeno",
"ui.sessionReview.openFile": "Otvori fajl",
"ui.sessionReview.selection.line": "linija {{line}}",
"ui.sessionReview.selection.lines": "linije {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Proširi sve",
"ui.sessionReview.collapseAll": "Sažmi sve",
"ui.sessionReview.change.added": "Dodano",
@@ -57,6 +60,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Sređivanje misli",
"ui.sessionTurn.status.consideringNextSteps": "Razmatranje sljedećih koraka",
"ui.messagePart.questions.dismissed": "Pitanja odbačena",
"ui.messagePart.context.read.one": "{{count}} čitanje",
"ui.messagePart.context.read.other": "{{count}} čitanja",
"ui.messagePart.context.search.one": "{{count}} pretraga",
"ui.messagePart.context.search.other": "{{count}} pretrage",
"ui.messagePart.context.list.one": "{{count}} lista",
"ui.messagePart.context.list.other": "{{count}} liste",
"ui.messagePart.diagnostic.error": "Greška",
"ui.messagePart.title.edit": "Uredi",
"ui.messagePart.title.write": "Napiši",
@@ -76,6 +86,7 @@ export const dict = {
"ui.textField.copied": "Kopirano",
"ui.imagePreview.alt": "Pregled slike",
"ui.scrollView.ariaLabel": "sadržaj za pomjeranje",
"ui.tool.read": "Čitanje",
"ui.tool.loaded": "Učitano",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Ændringer fra sidste tur",
"ui.sessionReview.diffStyle.unified": "Samlet",
"ui.sessionReview.diffStyle.split": "Opdelt",
"ui.sessionReview.openFile": "Åbn fil",
"ui.sessionReview.selection.line": "linje {{line}}",
"ui.sessionReview.selection.lines": "linjer {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Udvid alle",
"ui.sessionReview.collapseAll": "Skjul alle",
@@ -52,6 +55,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Samler tanker",
"ui.sessionTurn.status.consideringNextSteps": "Overvejer næste skridt",
"ui.messagePart.questions.dismissed": "Spørgsmål afvist",
"ui.messagePart.context.read.one": "{{count}} læsning",
"ui.messagePart.context.read.other": "{{count}} læsninger",
"ui.messagePart.context.search.one": "{{count}} søgning",
"ui.messagePart.context.search.other": "{{count}} søgninger",
"ui.messagePart.context.list.one": "{{count}} liste",
"ui.messagePart.context.list.other": "{{count}} lister",
"ui.messagePart.diagnostic.error": "Fejl",
"ui.messagePart.title.edit": "Rediger",
"ui.messagePart.title.write": "Skriv",
@@ -71,6 +81,7 @@ export const dict = {
"ui.textField.copied": "Kopieret",
"ui.imagePreview.alt": "Billedforhåndsvisning",
"ui.scrollView.ariaLabel": "rulbart indhold",
"ui.tool.read": "Læs",
"ui.tool.loaded": "Indlæst",

View File

@@ -7,6 +7,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Änderungen der letzten Runde",
"ui.sessionReview.diffStyle.unified": "Vereinheitlicht",
"ui.sessionReview.diffStyle.split": "Geteilt",
"ui.sessionReview.openFile": "Datei öffnen",
"ui.sessionReview.selection.line": "Zeile {{line}}",
"ui.sessionReview.selection.lines": "Zeilen {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Alle erweitern",
"ui.sessionReview.collapseAll": "Alle reduzieren",
@@ -58,6 +61,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Gedanken sammeln",
"ui.sessionTurn.status.consideringNextSteps": "Nächste Schritte erwägen",
"ui.messagePart.questions.dismissed": "Fragen verworfen",
"ui.messagePart.context.read.one": "{{count}} Lesevorgang",
"ui.messagePart.context.read.other": "{{count}} Lesevorgänge",
"ui.messagePart.context.search.one": "{{count}} Suche",
"ui.messagePart.context.search.other": "{{count}} Suchen",
"ui.messagePart.context.list.one": "{{count}} Liste",
"ui.messagePart.context.list.other": "{{count}} Listen",
"ui.messagePart.diagnostic.error": "Fehler",
"ui.messagePart.title.edit": "Bearbeiten",
"ui.messagePart.title.write": "Schreiben",
@@ -77,6 +87,7 @@ export const dict = {
"ui.textField.copied": "Kopiert",
"ui.imagePreview.alt": "Bildvorschau",
"ui.scrollView.ariaLabel": "scrollbarer Inhalt",
"ui.tool.read": "Lesen",
"ui.tool.loaded": "Geladen",

View File

@@ -1,4 +1,4 @@
export const dict = {
export const dict: Record<string, string> = {
"ui.sessionReview.title": "Session changes",
"ui.sessionReview.title.lastTurn": "Last turn changes",
"ui.sessionReview.diffStyle.unified": "Unified",
@@ -13,6 +13,9 @@ export const dict = {
"ui.sessionReview.largeDiff.title": "Diff too large to render",
"ui.sessionReview.largeDiff.meta": "Limit: {{limit}} changed lines. Current: {{current}} changed lines.",
"ui.sessionReview.largeDiff.renderAnyway": "Render anyway",
"ui.sessionReview.openFile": "Open file",
"ui.sessionReview.selection.line": "line {{line}}",
"ui.sessionReview.selection.lines": "lines {{start}}-{{end}}",
"ui.fileMedia.kind.image": "image",
"ui.fileMedia.kind.audio": "audio",
@@ -59,6 +62,13 @@ export const dict = {
"ui.messagePart.title.write": "Write",
"ui.messagePart.option.typeOwnAnswer": "Type your own answer",
"ui.messagePart.review.title": "Review your answers",
"ui.messagePart.questions.dismissed": "Questions dismissed",
"ui.messagePart.context.read.one": "{{count}} read",
"ui.messagePart.context.read.other": "{{count}} reads",
"ui.messagePart.context.search.one": "{{count}} search",
"ui.messagePart.context.search.other": "{{count}} searches",
"ui.messagePart.context.list.one": "{{count}} list",
"ui.messagePart.context.list.other": "{{count}} lists",
"ui.list.loading": "Loading",
"ui.list.empty": "No results",
@@ -73,6 +83,7 @@ export const dict = {
"ui.textField.copied": "Copied",
"ui.imagePreview.alt": "Image preview",
"ui.scrollView.ariaLabel": "scrollable content",
"ui.tool.read": "Read",
"ui.tool.loaded": "Loaded",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Cambios del último turno",
"ui.sessionReview.diffStyle.unified": "Unificado",
"ui.sessionReview.diffStyle.split": "Dividido",
"ui.sessionReview.openFile": "Abrir archivo",
"ui.sessionReview.selection.line": "línea {{line}}",
"ui.sessionReview.selection.lines": "líneas {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Expandir todo",
"ui.sessionReview.collapseAll": "Colapsar todo",
"ui.sessionReview.change.added": "Añadido",
@@ -53,6 +56,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Recopilando pensamientos",
"ui.sessionTurn.status.consideringNextSteps": "Considerando siguientes pasos",
"ui.messagePart.questions.dismissed": "Preguntas descartadas",
"ui.messagePart.context.read.one": "{{count}} lectura",
"ui.messagePart.context.read.other": "{{count}} lecturas",
"ui.messagePart.context.search.one": "{{count}} búsqueda",
"ui.messagePart.context.search.other": "{{count}} búsquedas",
"ui.messagePart.context.list.one": "{{count}} lista",
"ui.messagePart.context.list.other": "{{count}} listas",
"ui.messagePart.diagnostic.error": "Error",
"ui.messagePart.title.edit": "Editar",
"ui.messagePart.title.write": "Escribir",
@@ -72,6 +82,7 @@ export const dict = {
"ui.textField.copied": "Copiado",
"ui.imagePreview.alt": "Vista previa de imagen",
"ui.scrollView.ariaLabel": "contenido desplazable",
"ui.tool.read": "Leer",
"ui.tool.loaded": "Cargado",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Modifications du dernier tour",
"ui.sessionReview.diffStyle.unified": "Unifié",
"ui.sessionReview.diffStyle.split": "Divisé",
"ui.sessionReview.openFile": "Ouvrir le fichier",
"ui.sessionReview.selection.line": "ligne {{line}}",
"ui.sessionReview.selection.lines": "lignes {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Tout développer",
"ui.sessionReview.collapseAll": "Tout réduire",
"ui.sessionReview.change.added": "Ajouté",
@@ -53,6 +56,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Rassemblement des idées",
"ui.sessionTurn.status.consideringNextSteps": "Examen des prochaines étapes",
"ui.messagePart.questions.dismissed": "Questions ignorées",
"ui.messagePart.context.read.one": "{{count}} lecture",
"ui.messagePart.context.read.other": "{{count}} lectures",
"ui.messagePart.context.search.one": "{{count}} recherche",
"ui.messagePart.context.search.other": "{{count}} recherches",
"ui.messagePart.context.list.one": "{{count}} liste",
"ui.messagePart.context.list.other": "{{count}} listes",
"ui.messagePart.diagnostic.error": "Erreur",
"ui.messagePart.title.edit": "Modifier",
"ui.messagePart.title.write": "Écrire",
@@ -72,6 +82,7 @@ export const dict = {
"ui.textField.copied": "Copié",
"ui.imagePreview.alt": "Aperçu de l'image",
"ui.scrollView.ariaLabel": "contenu défilable",
"ui.tool.read": "Lire",
"ui.tool.loaded": "Chargé",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "前回ターンの変更",
"ui.sessionReview.diffStyle.unified": "Unified",
"ui.sessionReview.diffStyle.split": "Split",
"ui.sessionReview.openFile": "ファイルを開く",
"ui.sessionReview.selection.line": "{{line}} 行目",
"ui.sessionReview.selection.lines": "{{start}}-{{end}} 行目",
"ui.sessionReview.expandAll": "すべて展開",
"ui.sessionReview.collapseAll": "すべて折りたたむ",
@@ -52,6 +55,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "考えをまとめています",
"ui.sessionTurn.status.consideringNextSteps": "次のステップを検討中",
"ui.messagePart.questions.dismissed": "質問をスキップしました",
"ui.messagePart.context.read.one": "{{count}} 件の読み取り",
"ui.messagePart.context.read.other": "{{count}} 件の読み取り",
"ui.messagePart.context.search.one": "{{count}} 件の検索",
"ui.messagePart.context.search.other": "{{count}} 件の検索",
"ui.messagePart.context.list.one": "{{count}} 件のリスト",
"ui.messagePart.context.list.other": "{{count}} 件のリスト",
"ui.messagePart.diagnostic.error": "エラー",
"ui.messagePart.title.edit": "編集",
"ui.messagePart.title.write": "作成",
@@ -71,6 +81,7 @@ export const dict = {
"ui.textField.copied": "コピーしました",
"ui.imagePreview.alt": "画像プレビュー",
"ui.scrollView.ariaLabel": "スクロール可能なコンテンツ",
"ui.tool.read": "読み込み",
"ui.tool.loaded": "読み込み済み",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "마지막 턴 변경 사항",
"ui.sessionReview.diffStyle.unified": "통합 보기",
"ui.sessionReview.diffStyle.split": "분할 보기",
"ui.sessionReview.openFile": "파일 열기",
"ui.sessionReview.selection.line": "{{line}}번 줄",
"ui.sessionReview.selection.lines": "{{start}}-{{end}}번 줄",
"ui.sessionReview.expandAll": "모두 펼치기",
"ui.sessionReview.collapseAll": "모두 접기",
"ui.sessionReview.change.added": "추가됨",
@@ -53,6 +56,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "생각 정리 중",
"ui.sessionTurn.status.consideringNextSteps": "다음 단계 고려 중",
"ui.messagePart.questions.dismissed": "질문 무시됨",
"ui.messagePart.context.read.one": "{{count}}개 읽음",
"ui.messagePart.context.read.other": "{{count}}개 읽음",
"ui.messagePart.context.search.one": "{{count}}개 검색",
"ui.messagePart.context.search.other": "{{count}}개 검색",
"ui.messagePart.context.list.one": "{{count}}개 목록",
"ui.messagePart.context.list.other": "{{count}}개 목록",
"ui.messagePart.diagnostic.error": "오류",
"ui.messagePart.title.edit": "편집",
"ui.messagePart.title.write": "작성",
@@ -72,6 +82,7 @@ export const dict = {
"ui.textField.copied": "복사됨",
"ui.imagePreview.alt": "이미지 미리보기",
"ui.scrollView.ariaLabel": "스크롤 가능한 콘텐츠",
"ui.tool.read": "읽기",
"ui.tool.loaded": "로드됨",

View File

@@ -6,6 +6,9 @@ export const dict: Record<Keys, string> = {
"ui.sessionReview.title.lastTurn": "Endringer i siste tur",
"ui.sessionReview.diffStyle.unified": "Samlet",
"ui.sessionReview.diffStyle.split": "Delt",
"ui.sessionReview.openFile": "Åpne fil",
"ui.sessionReview.selection.line": "linje {{line}}",
"ui.sessionReview.selection.lines": "linjer {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Utvid alle",
"ui.sessionReview.collapseAll": "Fold sammen alle",
"ui.sessionReview.change.added": "Lagt til",
@@ -56,6 +59,13 @@ export const dict: Record<Keys, string> = {
"ui.sessionTurn.status.gatheringThoughts": "Samler tanker",
"ui.sessionTurn.status.consideringNextSteps": "Vurderer neste trinn",
"ui.messagePart.questions.dismissed": "Spørsmål avvist",
"ui.messagePart.context.read.one": "{{count}} lest",
"ui.messagePart.context.read.other": "{{count}} lest",
"ui.messagePart.context.search.one": "{{count}} søk",
"ui.messagePart.context.search.other": "{{count}} søk",
"ui.messagePart.context.list.one": "{{count}} liste",
"ui.messagePart.context.list.other": "{{count}} lister",
"ui.messagePart.diagnostic.error": "Feil",
"ui.messagePart.title.edit": "Rediger",
"ui.messagePart.title.write": "Skriv",
@@ -75,6 +85,7 @@ export const dict: Record<Keys, string> = {
"ui.textField.copied": "Kopiert",
"ui.imagePreview.alt": "Bildeforhåndsvisning",
"ui.scrollView.ariaLabel": "rullbart innhold",
"ui.tool.read": "Les",
"ui.tool.loaded": "Lastet",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Zmiany z ostatniej tury",
"ui.sessionReview.diffStyle.unified": "Ujednolicony",
"ui.sessionReview.diffStyle.split": "Podzielony",
"ui.sessionReview.openFile": "Otwórz plik",
"ui.sessionReview.selection.line": "linia {{line}}",
"ui.sessionReview.selection.lines": "linie {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Rozwiń wszystko",
"ui.sessionReview.collapseAll": "Zwiń wszystko",
@@ -52,6 +55,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Zbieranie myśli",
"ui.sessionTurn.status.consideringNextSteps": "Rozważanie kolejnych kroków",
"ui.messagePart.questions.dismissed": "Pytania odrzucone",
"ui.messagePart.context.read.one": "{{count}} odczyt",
"ui.messagePart.context.read.other": "{{count}} odczyty",
"ui.messagePart.context.search.one": "{{count}} wyszukiwanie",
"ui.messagePart.context.search.other": "{{count}} wyszukiwania",
"ui.messagePart.context.list.one": "{{count}} lista",
"ui.messagePart.context.list.other": "{{count}} listy",
"ui.messagePart.diagnostic.error": "Błąd",
"ui.messagePart.title.edit": "Edycja",
"ui.messagePart.title.write": "Pisanie",
@@ -71,6 +81,7 @@ export const dict = {
"ui.textField.copied": "Skopiowano",
"ui.imagePreview.alt": "Podgląd obrazu",
"ui.scrollView.ariaLabel": "treść przewijana",
"ui.tool.read": "Odczyt",
"ui.tool.loaded": "Załadowano",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Изменения последнего хода",
"ui.sessionReview.diffStyle.unified": "Объединённый",
"ui.sessionReview.diffStyle.split": "Разделённый",
"ui.sessionReview.openFile": "Открыть файл",
"ui.sessionReview.selection.line": "строка {{line}}",
"ui.sessionReview.selection.lines": "строки {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Развернуть всё",
"ui.sessionReview.collapseAll": "Свернуть всё",
@@ -52,6 +55,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Сбор мыслей",
"ui.sessionTurn.status.consideringNextSteps": "Рассмотрение следующих шагов",
"ui.messagePart.questions.dismissed": "Вопросы отклонены",
"ui.messagePart.context.read.one": "{{count}} чтение",
"ui.messagePart.context.read.other": "{{count}} чтений",
"ui.messagePart.context.search.one": "{{count}} поиск",
"ui.messagePart.context.search.other": "{{count}} поисков",
"ui.messagePart.context.list.one": "{{count}} список",
"ui.messagePart.context.list.other": "{{count}} списков",
"ui.messagePart.diagnostic.error": "Ошибка",
"ui.messagePart.title.edit": "Редактировать",
"ui.messagePart.title.write": "Написать",
@@ -71,6 +81,7 @@ export const dict = {
"ui.textField.copied": "Скопировано",
"ui.imagePreview.alt": "Предпросмотр изображения",
"ui.scrollView.ariaLabel": "прокручиваемый контент",
"ui.tool.read": "Чтение",
"ui.tool.loaded": "Загружено",

View File

@@ -3,6 +3,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "การเปลี่ยนแปลงของเทิร์นล่าสุด",
"ui.sessionReview.diffStyle.unified": "แบบรวม",
"ui.sessionReview.diffStyle.split": "แบบแยก",
"ui.sessionReview.openFile": "เปิดไฟล์",
"ui.sessionReview.selection.line": "บรรทัดที่ {{line}}",
"ui.sessionReview.selection.lines": "บรรทัดที่ {{start}}-{{end}}",
"ui.sessionReview.expandAll": "ขยายทั้งหมด",
"ui.sessionReview.collapseAll": "ย่อทั้งหมด",
"ui.sessionReview.change.added": "เพิ่ม",
@@ -54,6 +57,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "รวบรวมความคิด",
"ui.sessionTurn.status.consideringNextSteps": "พิจารณาขั้นตอนถัดไป",
"ui.messagePart.questions.dismissed": "ละทิ้งคำถามแล้ว",
"ui.messagePart.context.read.one": "อ่าน {{count}} รายการ",
"ui.messagePart.context.read.other": "อ่าน {{count}} รายการ",
"ui.messagePart.context.search.one": "ค้นหา {{count}} รายการ",
"ui.messagePart.context.search.other": "ค้นหา {{count}} รายการ",
"ui.messagePart.context.list.one": "รายการ {{count}} รายการ",
"ui.messagePart.context.list.other": "รายการ {{count}} รายการ",
"ui.messagePart.diagnostic.error": "ข้อผิดพลาด",
"ui.messagePart.title.edit": "แก้ไข",
"ui.messagePart.title.write": "เขียน",
@@ -73,6 +83,7 @@ export const dict = {
"ui.textField.copied": "คัดลอกแล้ว",
"ui.imagePreview.alt": "ตัวอย่างรูปภาพ",
"ui.scrollView.ariaLabel": "เนื้อหาที่เลื่อนได้",
"ui.tool.read": "อ่าน",
"ui.tool.loaded": "โหลดแล้ว",

View File

@@ -7,6 +7,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "Son tur değişiklikleri",
"ui.sessionReview.diffStyle.unified": "Birleşik",
"ui.sessionReview.diffStyle.split": "Bölünmüş",
"ui.sessionReview.openFile": "Dosyayı aç",
"ui.sessionReview.selection.line": "satır {{line}}",
"ui.sessionReview.selection.lines": "satırlar {{start}}-{{end}}",
"ui.sessionReview.expandAll": "Tümünü genişlet",
"ui.sessionReview.collapseAll": "Tümünü daralt",
@@ -49,6 +52,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "Düşünceler toplanıyor",
"ui.sessionTurn.status.consideringNextSteps": "Sonraki adımlar değerlendiriliyor",
"ui.messagePart.questions.dismissed": "Sorular reddedildi",
"ui.messagePart.context.read.one": "{{count}} okuma",
"ui.messagePart.context.read.other": "{{count}} okuma",
"ui.messagePart.context.search.one": "{{count}} arama",
"ui.messagePart.context.search.other": "{{count}} arama",
"ui.messagePart.context.list.one": "{{count}} liste",
"ui.messagePart.context.list.other": "{{count}} liste",
"ui.messagePart.diagnostic.error": "Hata",
"ui.messagePart.title.edit": "Düzenle",
"ui.messagePart.title.write": "Yaz",
@@ -68,6 +78,7 @@ export const dict = {
"ui.textField.copied": "Kopyalandı",
"ui.imagePreview.alt": "Görsel önizleme",
"ui.scrollView.ariaLabel": "kaydırılabilir içerik",
"ui.tool.read": "Oku",
"ui.tool.loaded": "Yüklendi",

View File

@@ -7,6 +7,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "上一轮变更",
"ui.sessionReview.diffStyle.unified": "统一",
"ui.sessionReview.diffStyle.split": "拆分",
"ui.sessionReview.openFile": "打开文件",
"ui.sessionReview.selection.line": "第 {{line}} 行",
"ui.sessionReview.selection.lines": "第 {{start}}-{{end}} 行",
"ui.sessionReview.expandAll": "全部展开",
"ui.sessionReview.collapseAll": "全部收起",
"ui.sessionReview.change.added": "已添加",
@@ -57,6 +60,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "正在整理思路",
"ui.sessionTurn.status.consideringNextSteps": "正在考虑下一步",
"ui.messagePart.questions.dismissed": "问题已忽略",
"ui.messagePart.context.read.one": "{{count}} 次读取",
"ui.messagePart.context.read.other": "{{count}} 次读取",
"ui.messagePart.context.search.one": "{{count}} 次搜索",
"ui.messagePart.context.search.other": "{{count}} 次搜索",
"ui.messagePart.context.list.one": "{{count}} 个列表",
"ui.messagePart.context.list.other": "{{count}} 个列表",
"ui.messagePart.diagnostic.error": "错误",
"ui.messagePart.title.edit": "编辑",
"ui.messagePart.title.write": "写入",
@@ -76,6 +86,7 @@ export const dict = {
"ui.textField.copied": "已复制",
"ui.imagePreview.alt": "图片预览",
"ui.scrollView.ariaLabel": "可滚动内容",
"ui.tool.read": "读取",
"ui.tool.loaded": "已加载",

View File

@@ -7,6 +7,9 @@ export const dict = {
"ui.sessionReview.title.lastTurn": "上一輪變更",
"ui.sessionReview.diffStyle.unified": "整合",
"ui.sessionReview.diffStyle.split": "拆分",
"ui.sessionReview.openFile": "開啟檔案",
"ui.sessionReview.selection.line": "第 {{line}} 行",
"ui.sessionReview.selection.lines": "第 {{start}}-{{end}} 行",
"ui.sessionReview.expandAll": "全部展開",
"ui.sessionReview.collapseAll": "全部收合",
"ui.sessionReview.change.added": "已新增",
@@ -57,6 +60,13 @@ export const dict = {
"ui.sessionTurn.status.gatheringThoughts": "正在整理思緒",
"ui.sessionTurn.status.consideringNextSteps": "正在考慮下一步",
"ui.messagePart.questions.dismissed": "問題已略過",
"ui.messagePart.context.read.one": "{{count}} 次讀取",
"ui.messagePart.context.read.other": "{{count}} 次讀取",
"ui.messagePart.context.search.one": "{{count}} 次搜尋",
"ui.messagePart.context.search.other": "{{count}} 次搜尋",
"ui.messagePart.context.list.one": "{{count}} 個清單",
"ui.messagePart.context.list.other": "{{count}} 個清單",
"ui.messagePart.diagnostic.error": "錯誤",
"ui.messagePart.title.edit": "編輯",
"ui.messagePart.title.write": "寫入",
@@ -76,6 +86,7 @@ export const dict = {
"ui.textField.copied": "已複製",
"ui.imagePreview.alt": "圖片預覽",
"ui.scrollView.ariaLabel": "可捲動內容",
"ui.tool.read": "讀取",
"ui.tool.loaded": "已載入",