Merge pull request #3884 from leeyazhou/i18n
feat(i18n): add toast i18n with en/zh locale and plugin config support
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
declare const require: (name: string) => any
|
||||
const { describe, test, expect, beforeEach, afterEach, mock } = require("bun:test")
|
||||
import type { ConcurrencyManager } from "../background-agent/concurrency"
|
||||
import { initI18n } from "../../shared/i18n"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
type TaskToastManagerClass = typeof import("./manager").TaskToastManager
|
||||
@@ -28,6 +29,7 @@ describe("TaskToastManager", () => {
|
||||
const mod = await import("./manager")
|
||||
TaskToastManager = mod.TaskToastManager
|
||||
|
||||
initI18n({ locale: "en" })
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
toastManager = new TaskToastManager(unsafeTestValue(mockClient), mockConcurrencyManager)
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import type { TrackedTask, TaskStatus, ModelFallbackInfo } from "./types"
|
||||
import { t } from "../../shared/i18n"
|
||||
import type { ConcurrencyManager } from "../background-agent/concurrency"
|
||||
import type { ModelFallbackInfo, TaskStatus, TrackedTask } from "./types"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
@@ -119,7 +120,7 @@ export class TaskToastManager {
|
||||
const total = running.length + queued.length
|
||||
const limit = this.concurrencyManager.getConcurrencyLimit("default")
|
||||
if (limit === Infinity) return ""
|
||||
return ` [${total}/${limit}]`
|
||||
return t("toast.concurrency_info", { total, limit })
|
||||
}
|
||||
|
||||
private buildTaskListMessage(newTask: TrackedTask): string {
|
||||
@@ -143,21 +144,21 @@ export class TaskToastManager {
|
||||
)
|
||||
if (isFallback) {
|
||||
const suffixMap: Record<"inherited" | "system-default" | "runtime-fallback", string> = {
|
||||
inherited: " (inherited from parent)",
|
||||
"system-default": " (system default fallback)",
|
||||
"runtime-fallback": " (runtime fallback)",
|
||||
inherited: t("toast.fallback_inherited"),
|
||||
"system-default": t("toast.fallback_system_default"),
|
||||
"runtime-fallback": t("toast.fallback_runtime"),
|
||||
}
|
||||
const suffix = suffixMap[newTask.modelInfo!.type as "inherited" | "system-default" | "runtime-fallback"]
|
||||
lines.push(`[FALLBACK] Model: ${newTask.modelInfo!.model}${suffix}`)
|
||||
lines.push(t("toast.fallback_prefix", { model: newTask.modelInfo!.model, suffix }))
|
||||
lines.push("")
|
||||
}
|
||||
|
||||
if (running.length > 0) {
|
||||
lines.push(`Running (${running.length}):${concurrencyInfo}`)
|
||||
lines.push(t("toast.task_list_running", { count: running.length }) + concurrencyInfo)
|
||||
for (const task of running) {
|
||||
const duration = this.formatDuration(task.startedAt)
|
||||
const bgIcon = task.isBackground ? "[BG]" : "[RUN]"
|
||||
const isNew = task.id === newTask.id ? " ← NEW" : ""
|
||||
const isNew = task.id === newTask.id ? t("toast.task_list_new") : ""
|
||||
const taskId = formatTaskIdentifier(task)
|
||||
const skillsInfo = task.skills?.length ? ` [${task.skills.join(", ")}]` : ""
|
||||
lines.push(`${bgIcon} ${task.description} (${taskId})${skillsInfo} - ${duration}${isNew}`)
|
||||
@@ -166,13 +167,13 @@ export class TaskToastManager {
|
||||
|
||||
if (queued.length > 0) {
|
||||
if (lines.length > 0) lines.push("")
|
||||
lines.push(`Queued (${queued.length}):`)
|
||||
lines.push(t("toast.task_list_queued", { count: queued.length }))
|
||||
for (const task of queued) {
|
||||
const bgIcon = task.isBackground ? "[Q]" : "[W]"
|
||||
const taskId = formatTaskIdentifier(task)
|
||||
const skillsInfo = task.skills?.length ? ` [${task.skills.join(", ")}]` : ""
|
||||
const isNew = task.id === newTask.id ? " ← NEW" : ""
|
||||
lines.push(`${bgIcon} ${task.description} (${taskId})${skillsInfo} - Queued${isNew}`)
|
||||
const isNew = task.id === newTask.id ? t("toast.task_list_new") : ""
|
||||
lines.push(`${bgIcon} ${task.description} (${taskId})${skillsInfo} - ${t("toast.status_queued")}${isNew}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +192,8 @@ export class TaskToastManager {
|
||||
const queued = this.getQueuedTasks()
|
||||
|
||||
const title = newTask.isBackground
|
||||
? `New Background Task`
|
||||
: `New Task Executed`
|
||||
? t("toast.new_background_task")
|
||||
: t("toast.new_task_executed")
|
||||
|
||||
tuiClient.tui.showToast({
|
||||
body: {
|
||||
@@ -216,14 +217,14 @@ export class TaskToastManager {
|
||||
const remaining = this.getRunningTasks()
|
||||
const queued = this.getQueuedTasks()
|
||||
|
||||
let message = `"${task.description}" finished in ${task.duration}`
|
||||
let message = t("toast.task_completion_message", { description: task.description, duration: task.duration })
|
||||
if (remaining.length > 0 || queued.length > 0) {
|
||||
message += `\n\nStill running: ${remaining.length} | Queued: ${queued.length}`
|
||||
message += `\n\n${t("toast.task_completion_remaining", { running: remaining.length, queued: queued.length })}`
|
||||
}
|
||||
|
||||
tuiClient.tui.showToast({
|
||||
body: {
|
||||
title: "Task Completed",
|
||||
title: t("toast.task_completed"),
|
||||
message,
|
||||
variant: "success",
|
||||
duration: 5000,
|
||||
|
||||
Reference in New Issue
Block a user