feat/voice #4

Merged
daniel.w merged 3 commits from feat/voice into main 2026-09-06 06:01:36 +00:00
4 changed files with 12 additions and 12 deletions
Showing only changes of commit e4ceb626ab - Show all commits

View File

@ -329,7 +329,6 @@ export function App(){
<div className="account-wrap" onClick={event=>event.stopPropagation()}>
{accountOpen&&<div className="account-menu" role="menu">
<button type="button" role="menuitem" onClick={()=>openAccount("phone")}><Smartphone/>{t("openOnPhone")}</button>
<button type="button" role="menuitem" onClick={()=>setLocale(getLocale()==="zh-TW"?"en":"zh-TW")}>{t("language")}: {getLocale()==="zh-TW"?t("languageEn"):t("languageZh")}</button>
<button type="button" role="menuitem" onClick={()=>openAccount("settings")}><Settings/>{t("settings")}</button>
<button type="button" role="menuitem" onClick={()=>openAccount("model")}><BotIcon/>{t("modelSettings")}</button>
<button type="button" role="menuitem" onClick={()=>openAccount("voice")}><PhoneIcon/>{t("voiceSettings")}</button>
@ -854,11 +853,12 @@ function FeedbackDialog({close}:{close:()=>void}){
function LoginScreen({authenticated}:{authenticated:()=>void}){
useLocale();
const[token,setToken]=useState("");const[busy,setBusy]=useState(false);const[error,setError]=useState("");
return <main className="login-screen"><form className="dialog compact login-dialog" onSubmit={async e=>{e.preventDefault();if(!token)return;setBusy(true);setError("");try{await api("/api/session",{method:"POST",body:JSON.stringify({token})});authenticated()}catch(err){setError(err instanceof Error?localizeError(err.message):t("loginFailed"))}finally{setBusy(false)}}}>
<div className="login-lang">
<button type="button" className={getLocale()==="zh-TW"?"picked":""} onClick={()=>setLocale("zh-TW")}>{t("languageZh")}</button>
<button type="button" className={getLocale()==="en"?"picked":""} onClick={()=>setLocale("en")}>{t("languageEn")}</button>
return <main className="login-screen">
<div className="login-lang" role="group" aria-label={t("language")}>
<button type="button" aria-pressed={getLocale()==="zh-TW"} className={getLocale()==="zh-TW"?"picked":""} onClick={()=>setLocale("zh-TW")}>{t("languageZh")}</button>
<button type="button" aria-pressed={getLocale()==="en"} className={getLocale()==="en"?"picked":""} onClick={()=>setLocale("en")}>{t("languageEn")}</button>
</div>
<form className="dialog compact login-dialog" onSubmit={async e=>{e.preventDefault();if(!token)return;setBusy(true);setError("");try{await api("/api/session",{method:"POST",body:JSON.stringify({token})});authenticated()}catch(err){setError(err instanceof Error?localizeError(err.message):t("loginFailed"))}finally{setBusy(false)}}}>
<Avatar name="L" size={58}/><h1>{t("loginTitle")}</h1><p>{t("loginDescription")}</p><label>{t("accessToken")}<input type="password" autoFocus autoComplete="current-password" value={token} onChange={e=>setToken(e.target.value)}/></label>{error&&<div className="login-error">{error}</div>}<button className="primary" disabled={busy||!token}>{busy?t("verifying"):t("login")}</button>
</form></main>;
}

View File

@ -415,12 +415,12 @@ export const en: { [K in keyof typeof zhTW]: string } = {
schedHours: "hours",
schedDays: "days",
computerLoginHint: "Sign in inside this bots own browser. The session stays on its computer — dont type passwords in chat.",
language: "Language",
languageZh: "中文",
language: "Interface language",
languageZh: "繁體中文",
languageEn: "English",
languageHint: "Interface language. Chat history and agent replies are not translated.",
helpLanguageTitle: "Language",
helpLanguage: "Switch Chinese and English from the workspace menu or Settings.",
helpLanguage: "Switch between Traditional Chinese and English in Settings, accessible from the workspace menu.",
clipboardSynced: "Clipboard synced",
clipboardSyncBlocked: "The browser blocked sync. Use the copy button.",
clipboardPasted: "Pasted",

View File

@ -126,9 +126,9 @@ export const zhTW = {
schedEveryWeek: "每週一", schedEveryMonth: "每月", schedInterval: "間隔", schedAdvanced: "進階 cron",
schedMinutes: "分鐘", schedHours: "小時", schedDays: "天",
computerLoginHint: "在這台機器人自己的瀏覽器登入。Session 留在它的電腦,不要把密碼打在聊天裡。",
language: "語言", languageZh: "中文", languageEn: "English",
language: "介面語言", languageZh: "繁體中文", languageEn: "English",
languageHint: "介面語言。對話內容與 Agent 回覆不會自動翻譯。",
helpLanguageTitle: "語言", helpLanguage: "工作區選單或設定裡可切換中文與英文。",
helpLanguageTitle: "語言", helpLanguage: "在左下角工作區選單的設定裡,可切換繁體中文與英文。",
clipboardSynced: "剪貼簿已同步", clipboardSyncBlocked: "瀏覽器未允許同步,請按複製按鈕",
clipboardPasted: "已貼上文字", clipboardPasteFailed: "貼上失敗,請確認已接管電腦後重試",
clipboardCopiedSelection: "已複製選取文字", clipboardCopyFailed: "複製未同步;請按複製按鈕,或在遠端使用 Ctrl+Shift+C",

View File

@ -587,7 +587,7 @@
.memory-clear-confirm{display:flex;align-items:center;gap:8px;margin-right:auto;color:var(--muted);font-size:13px}
.login-screen{display:grid;min-height:100%;place-items:center;padding:20px;background:radial-gradient(circle at 50% 20%,#18201e 0,#080809 55%)}
.login-screen{position:relative;display:grid;min-height:100%;place-items:center;padding:88px 20px;background:radial-gradient(circle at 50% 20%,#18201e 0,#080809 55%)}
.login-dialog{display:grid;justify-items:stretch}
@ -599,7 +599,7 @@
.login-error{color:var(--danger-soft);font-size:13px}
.login-lang{display:flex;justify-content:center;gap:6px;margin-bottom:4px}
.login-lang{position:absolute;top:24px;right:24px;display:flex;align-items:center;gap:6px}
.login-lang button{height:32px;padding:0 12px;border:1px solid var(--border);border-radius:9px;background:transparent;color:var(--muted);cursor:pointer}