fix i18n review comments and locale test robustness
This commit is contained in:
committed by
Nathan Esquenazi
parent
c4efe96725
commit
204dc23c6b
@@ -584,7 +584,45 @@ function applyBotName(){
|
||||
(async()=>{
|
||||
// Load send key preference
|
||||
let _bootSettings={};
|
||||
try{const s=await api('/api/settings');_bootSettings=s;window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;window._soundEnabled=!!s.sound_enabled;window._notificationsEnabled=!!s.notifications_enabled;window._botName=s.bot_name||'Hermes';const _theme=s.theme||'dark';document.documentElement.dataset.theme=_theme;localStorage.setItem('hermes-theme',_theme);document.body.classList.toggle('bubble-layout',!!s.bubble_layout);if(typeof setLocale==='function'){const _lang=typeof resolvePreferredLocale==='function'?resolvePreferredLocale(s.language,localStorage.getItem('hermes-lang')):(s.language||localStorage.getItem('hermes-lang')||'en');setLocale(_lang);if(typeof applyLocaleToDOM==='function')applyLocaleToDOM();}applyBotName();}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;window._soundEnabled=false;window._notificationsEnabled=false;window._botName='Hermes';_bootSettings={check_for_updates:false};document.body.classList.remove('bubble-layout');}
|
||||
try{
|
||||
const s=await api('/api/settings');
|
||||
_bootSettings=s;
|
||||
window._sendKey=s.send_key||'enter';
|
||||
window._showTokenUsage=!!s.show_token_usage;
|
||||
window._showCliSessions=!!s.show_cli_sessions;
|
||||
window._soundEnabled=!!s.sound_enabled;
|
||||
window._notificationsEnabled=!!s.notifications_enabled;
|
||||
window._botName=s.bot_name||'Hermes';
|
||||
const _theme=s.theme||'dark';
|
||||
document.documentElement.dataset.theme=_theme;
|
||||
localStorage.setItem('hermes-theme',_theme);
|
||||
document.body.classList.toggle('bubble-layout',!!s.bubble_layout);
|
||||
if(typeof setLocale==='function'){
|
||||
const _lang=typeof resolvePreferredLocale==='function'
|
||||
? resolvePreferredLocale(s.language, localStorage.getItem('hermes-lang'))
|
||||
: (s.language || localStorage.getItem('hermes-lang') || 'en');
|
||||
setLocale(_lang);
|
||||
if(typeof applyLocaleToDOM==='function')applyLocaleToDOM();
|
||||
}
|
||||
applyBotName();
|
||||
}catch(e){
|
||||
window._sendKey='enter';
|
||||
window._showTokenUsage=false;
|
||||
window._showCliSessions=false;
|
||||
window._soundEnabled=false;
|
||||
window._notificationsEnabled=false;
|
||||
window._botName='Hermes';
|
||||
_bootSettings={check_for_updates:false};
|
||||
document.body.classList.remove('bubble-layout');
|
||||
if(typeof setLocale==='function'){
|
||||
const _lang=typeof resolvePreferredLocale==='function'
|
||||
? resolvePreferredLocale(null, localStorage.getItem('hermes-lang'))
|
||||
: (localStorage.getItem('hermes-lang') || 'en');
|
||||
setLocale(_lang);
|
||||
if(typeof applyLocaleToDOM==='function')applyLocaleToDOM();
|
||||
}
|
||||
applyBotName();
|
||||
}
|
||||
// Non-blocking update check (fire-and-forget, once per tab session)
|
||||
// ?test_updates=1 in URL forces banner display for testing (bypasses sessionStorage guards)
|
||||
const _testUpdates=new URLSearchParams(location.search).get('test_updates')==='1';
|
||||
|
||||
@@ -379,8 +379,10 @@ const LOCALES = {
|
||||
profile_gateway_stopped: 'Gateway stopped',
|
||||
profile_active: 'ACTIVE',
|
||||
profile_no_configuration: 'No configuration',
|
||||
profile_skill_count: (count) => `${count} skill${count === 1 ? '' : 's'}`,
|
||||
profile_use: 'Use',
|
||||
profile_switch_title: 'Switch to this profile',
|
||||
profile_delete_title: 'Delete this profile',
|
||||
manage_profiles: 'Manage profiles',
|
||||
profiles_load_failed: 'Failed to load profiles',
|
||||
profiles_busy_switch: 'Cannot switch profiles while agent is running',
|
||||
@@ -771,8 +773,10 @@ const LOCALES = {
|
||||
profile_gateway_stopped: 'Gateway stopped',
|
||||
profile_active: 'ACTIVE',
|
||||
profile_no_configuration: 'No configuration',
|
||||
profile_skill_count: (count) => `${count} habilidad${count === 1 ? '' : 'es'}`,
|
||||
profile_use: 'Use',
|
||||
profile_switch_title: 'Switch to this profile',
|
||||
profile_delete_title: 'Eliminar este perfil',
|
||||
manage_profiles: 'Manage profiles',
|
||||
profiles_load_failed: 'Failed to load profiles',
|
||||
profiles_busy_switch: 'Cannot switch profiles while agent is running',
|
||||
@@ -1358,8 +1362,10 @@ const LOCALES = {
|
||||
profile_gateway_stopped: '网关已停止',
|
||||
profile_active: '当前',
|
||||
profile_no_configuration: '无配置',
|
||||
profile_skill_count: (count) => `${count} 个技能`,
|
||||
profile_use: '使用',
|
||||
profile_switch_title: '切换到此配置档',
|
||||
profile_delete_title: '删除此配置档',
|
||||
manage_profiles: '管理配置档',
|
||||
profiles_load_failed: '加载配置档失败',
|
||||
profiles_busy_switch: 'Agent 运行中,无法切换配置档',
|
||||
|
||||
@@ -808,7 +808,7 @@ async function loadProfilesPanel() {
|
||||
const meta = [];
|
||||
if (p.model) meta.push(p.model.split('/').pop());
|
||||
if (p.provider) meta.push(p.provider);
|
||||
if (p.skill_count) meta.push(p.skill_count + ' skill' + (p.skill_count !== 1 ? 's' : ''));
|
||||
if (p.skill_count) meta.push(t('profile_skill_count', p.skill_count));
|
||||
if (p.has_env) meta.push(t('profile_api_keys_configured'));
|
||||
const gwDot = p.gateway_running
|
||||
? `<span class="profile-opt-badge running" title="${esc(t('profile_gateway_running'))}"></span>`
|
||||
@@ -823,7 +823,7 @@ async function loadProfilesPanel() {
|
||||
</div>
|
||||
<div class="profile-card-actions">
|
||||
${!isActive ? `<button class="ws-action-btn" onclick="switchToProfile('${esc(p.name)}')" title="${esc(t('profile_switch_title'))}">${esc(t('profile_use'))}</button>` : ''}
|
||||
${!p.is_default ? `<button class="ws-action-btn danger" onclick="deleteProfile('${esc(p.name)}')" title="Delete this profile">${li('x',12)}</button>` : ''}
|
||||
${!p.is_default ? `<button class="ws-action-btn danger" onclick="deleteProfile('${esc(p.name)}')" title="${esc(t('profile_delete_title'))}">${li('x',12)}</button>` : ''}
|
||||
</div>
|
||||
</div>`;
|
||||
panel.appendChild(card);
|
||||
@@ -844,7 +844,7 @@ function renderProfileDropdown(data) {
|
||||
opt.className = 'profile-opt' + (p.name === active ? ' active' : '');
|
||||
const meta = [];
|
||||
if (p.model) meta.push(p.model.split('/').pop());
|
||||
if (p.skill_count) meta.push(p.skill_count + ' skills');
|
||||
if (p.skill_count) meta.push(t('profile_skill_count', p.skill_count));
|
||||
const gwDot = `<span class="profile-opt-badge ${p.gateway_running ? 'running' : 'stopped'}"></span>`;
|
||||
const checkmark = p.name === active ? ' <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--link)" stroke-width="3" style="vertical-align:-1px"><polyline points="20 6 9 17 4 12"/></svg>' : '';
|
||||
opt.innerHTML = `<div class="profile-opt-name">${gwDot}${esc(p.name)}${p.is_default ? ' <span style="opacity:.5;font-weight:400">(default)</span>' : ''}${checkmark}</div>` +
|
||||
@@ -1000,7 +1000,10 @@ async function submitProfileCreate() {
|
||||
toggleProfileForm();
|
||||
await loadProfilesPanel();
|
||||
showToast(t('profile_created', name));
|
||||
} catch (e) { errEl.textContent = e.message || 'Create failed'; errEl.style.display = ''; }
|
||||
} catch (e) {
|
||||
errEl.textContent = e.message || t('create_failed');
|
||||
errEl.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteProfile(name) {
|
||||
|
||||
Reference in New Issue
Block a user