Q174: choosing a language no longer restarts the app; the restart waits for the user

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-09 04:53:25 -04:00
1 parent 3f14e3f706
commit dc3127c26f
9 files changed
+95 -27

No files matched your search

+6
View File
@@ -696,6 +696,12 @@ export const zh: Record<string, string> = {
"Resets {date} (UTC)": "{date} 重置(UTC)",
"Unsaved": "未保存",
"Working language": "工作语言",
"{language} applies after a restart.": "{language} 将在重启后生效。",
"Restart now": "立即重启",
"Restart to switch language?": "重启以切换语言?",
"Text you typed but have not sent or saved is lost.": "已输入但尚未发送或保存的文字会丢失。",
"Running agent sessions: {count}. They stop now; their tasks stay open and start a new session when next queued, by heartbeat or Run, and a chat reply in progress is not sent.": "运行中的 Agent 会话:{count}。它们会立即停止;其任务保持未完成,并在下次通过心跳或“运行”排队时开始新会话,进行中的聊天回复不会发出。",
"Counting running agent sessions…": "正在统计运行中的 Agent 会话…",
"Company default ({language})": "公司默认({language})",
"Agents' working language": "Agent 工作语言",
"Agents write messages, tasks, documents and deliverables in it. The display language does not change it, and a task can set its own.": "Agent 用它撰写消息、任务、文档和交付物。显示语言不会改变它,单个任务也可以单独设置。",
@@ -0,0 +1,58 @@
import { useState } from "react";
import type { UiLanguage, UiPreferences } from "../../../../shared/domain";
import type { SnapshotActions } from "../../app/useSnapshot";
import { Dialog } from "../../shared/Dialog";
import { Button, Field } from "../../shared/ui";
import { t } from "../../i18n/i18n";
const NAMES: Record<UiLanguage, string> = { en: "English", zh: "中文" };
/** The display language is fixed per launch, so a choice waits for a restart the user starts after seeing what it interrupts. */
export function LanguageField({ uiPreferences, actions }: { uiPreferences: UiPreferences; actions: SnapshotActions }) {
const [confirming, setConfirming] = useState(false);
const [running, setRunning] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);
const confirm = () => {
setRunning(null);
setError(null);
setConfirming(true);
void window.agentCompany.runningSessionCount().then((result) => {
if (result.ok) setRunning(result.data);
else setError(result.error.message);
});
};
const pending = uiPreferences.language !== window.agentCompany.language;
const restart = () => {
setError(null);
void window.agentCompany.relaunchApp().then((result) => { if (!result.ok) setError(result.error.message); });
};
return (
<Field label={t("Language")}>
<select
className="input"
aria-label={t("Language")}
value={uiPreferences.language}
onChange={(event) => void actions.run(() => window.agentCompany.setUiPreferences({ language: event.target.value as UiLanguage }))}
>
<option value="en">{NAMES.en}</option>
<option value="zh">{NAMES.zh}</option>
</select>
<span style={{ fontSize: 12, color: "var(--text-3)" }}>{t("Changes only what you see; agents keep the company's working language.")}</span>
{pending && (
<span className="row" style={{ gap: 8, fontSize: 12 }} role="status">
{t("{language} applies after a restart.", { language: NAMES[uiPreferences.language] })}
<Button size="small" onClick={confirm}>{t("Restart now")}</Button>
</span>
)}
<Dialog title={t("Restart to switch language?")} open={confirming} submitLabel={t("Restart now")} onClose={() => setConfirming(false)} onSubmit={(event) => { event.preventDefault(); restart(); }}>
<ul style={{ margin: 0, paddingLeft: 18, lineHeight: 1.6, fontSize: 13 }}>
<li>{t("Text you typed but have not sent or saved is lost.")}</li>
<li>{running === null
? t("Counting running agent sessions…")
: t("Running agent sessions: {count}. They stop now; their tasks stay open and start a new session when next queued, by heartbeat or Run, and a chat reply in progress is not sent.", { count: running })}</li>
</ul>
{error && <div className="form-error" role="alert">{error}</div>}
</Dialog>
</Field>
);
}
@@ -1,3 +1,4 @@
import { LanguageField } from "./LanguageField";
import { WorkspaceRow } from "./WorkspaceRow";
import { CompanyDialog } from "./CompanyDialog";
import { ScopeNote } from "./ScopeNote";
@@ -5,7 +6,6 @@ import { useState, type FormEvent } from "react";
import type {
OrganizationRecord,
ProjectRecord,
UiLanguage,
UiPreferences,
UiTheme,
WorkspaceRecord,
@@ -102,20 +102,7 @@ export function WorkspacePanel({
<option value="dark">{t("Dark")}</option>
</select>
</Field>
<Field label={t("Language")}>
<select
className="input"
aria-label={t("Language")}
value={uiPreferences.language}
onChange={(event) =>
void actions.run(() => window.agentCompany.setUiPreferences({ language: event.target.value as UiLanguage }))
}
>
<option value="en">English</option>
<option value="zh">中文</option>
</select>
<span style={{ fontSize: 12, color: "var(--text-3)" }}>{t("Changes only what you see; agents keep the company's working language.")}</span>
</Field>
<LanguageField uiPreferences={uiPreferences} actions={actions} />
</div>
<div className="row reveal-row" style={{ marginBottom: 8 }}>