diff --git a/static/i18n.js b/static/i18n.js index 671afbf6..71cc6878 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -231,6 +231,11 @@ const LOCALES = { settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.', settings_section_system_title: 'System', settings_section_system_meta: 'Instance version and access controls.', + settings_check_now: 'Check now', + settings_checking: 'Checking\u2026', + settings_up_to_date: 'Up to date \u2713', + settings_updates_available: '{count} update(s) available', + settings_updates_disabled: 'Update checks disabled', settings_dropdown_conversation: 'Conversation', settings_dropdown_appearance: 'Appearance', settings_dropdown_preferences: 'Preferences', @@ -1174,6 +1179,11 @@ const LOCALES = { settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.', settings_section_preferences_title: 'Preferences', settings_section_system_meta: 'Instance version and access controls.', + settings_check_now: 'Проверить', + settings_checking: 'Проверка\u2026', + settings_up_to_date: 'Актуально \u2713', + settings_updates_available: 'Доступно обновлений: {count}', + settings_updates_disabled: 'Проверка обновлений отключена', settings_section_system_title: 'System', settings_tab_appearance: 'Appearance', settings_tab_conversation: 'Conversation', @@ -1714,6 +1724,11 @@ const LOCALES = { settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.', settings_section_preferences_title: 'Preferences', settings_section_system_meta: 'Instance version and access controls.', + settings_check_now: 'Comprobar ahora', + settings_checking: 'Comprobando\u2026', + settings_up_to_date: 'Actualizado \u2713', + settings_updates_available: '{count} actualización(es) disponible(s)', + settings_updates_disabled: 'Comprobación de actualizaciones desactivada', settings_section_system_title: 'System', settings_tab_appearance: 'Appearance', settings_tab_conversation: 'Conversation', @@ -2038,6 +2053,11 @@ const LOCALES = { settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.', settings_section_preferences_title: 'Preferences', settings_section_system_meta: 'Instance version and access controls.', + settings_check_now: 'Jetzt prüfen', + settings_checking: 'Prüfung\u2026', + settings_up_to_date: 'Aktuell \u2713', + settings_updates_available: '{count} Update(s) verfügbar', + settings_updates_disabled: 'Update-Prüfung deaktiviert', settings_section_system_title: 'System', settings_tab_appearance: 'Appearance', settings_tab_conversation: 'Conversation', @@ -2575,6 +2595,11 @@ const LOCALES = { settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.', settings_section_preferences_title: 'Preferences', settings_section_system_meta: 'Instance version and access controls.', + settings_check_now: '立即检查', + settings_checking: '检查中\u2026', + settings_up_to_date: '已是最新 \u2713', + settings_updates_available: '有 {count} 个更新可用', + settings_updates_disabled: '更新检查已禁用', settings_section_system_title: 'System', settings_tab_appearance: 'Appearance', settings_tab_conversation: 'Conversation', @@ -2742,6 +2767,11 @@ const LOCALES = { settings_section_preferences_meta: 'Hermes Web UI 的預設值與介面行為。', settings_section_system_title: '系統', settings_section_system_meta: '實例版本與存取控制。', + settings_check_now: '立即檢查', + settings_checking: '檢查中\u2026', + settings_up_to_date: '已是最新 \u2713', + settings_updates_available: '有 {count} 個更新可用', + settings_updates_disabled: '更新檢查已禁用', settings_dropdown_conversation: '對話', settings_dropdown_appearance: '外觀', settings_dropdown_preferences: '偏好設定', diff --git a/static/index.html b/static/index.html index 5cd43e22..56ca2f02 100644 --- a/static/index.html +++ b/static/index.html @@ -684,7 +684,11 @@
System
Instance version and access controls.
- +
+ + + +
diff --git a/static/panels.js b/static/panels.js index 980970aa..2600b702 100644 --- a/static/panels.js +++ b/static/panels.js @@ -2507,6 +2507,42 @@ function _applySavedSettingsUi(saved, body, opts){ if(typeof renderSessionList==='function') renderSessionList(); } +async function checkUpdatesNow(){ + const btn=$('btnCheckUpdatesNow'); + const label=$('checkUpdatesLabel'); + const spinner=$('checkUpdatesSpinner'); + const status=$('checkUpdatesStatus'); + if(!btn||!label) return; + // Disable button, show spinner + btn.disabled=true; + if(spinner) spinner.style.display=''; + if(label) label.textContent=t('settings_checking'); + if(status) status.textContent=''; + try { + const data=await api('/api/updates/check?force=1'); + if(data.disabled){ + if(status){status.textContent=t('settings_updates_disabled');status.style.color='var(--muted)';} + } else { + const parts=[]; + if(data.webui&&data.webui.behind>0) parts.push('WebUI: '+data.webui.behind); + if(data.agent&&data.agent.behind>0) parts.push('Agent: '+data.agent.behind); + if(parts.length){ + if(status){status.textContent=t('settings_updates_available').replace('{count}',parts.join(', '));status.style.color='var(--accent)';} + // Also trigger the update banner + if(typeof _showUpdateBanner==='function') _showUpdateBanner(data); + } else { + if(status){status.textContent=t('settings_up_to_date');status.style.color='var(--success)';} + } + } + } catch(e){ + if(status){status.textContent=t('failed_colon')+e.message;status.style.color='var(--error)';} + } finally { + btn.disabled=false; + if(spinner) spinner.style.display='none'; + if(label) label.textContent=t('settings_check_now'); + } +} + async function saveSettings(andClose){ const model=($('settingsModel')||{}).value; const modelChanged=(model||'')!==(_settingsHermesDefaultModelOnOpen||''); diff --git a/static/style.css b/static/style.css index 1cd8f064..e672406c 100644 --- a/static/style.css +++ b/static/style.css @@ -1550,6 +1550,12 @@ main.main.showing-profiles > #mainProfiles{display:flex;} .settings-section-title{font-size:18px;font-weight:600;letter-spacing:-.01em;color:var(--text);line-height:1.3;margin-bottom:4px;} .settings-section-meta{font-size:13px;color:var(--muted);line-height:1.55;} .settings-version-badge{display:inline-flex;align-items:center;padding:3px 8px;border-radius:999px;background:var(--surface);color:var(--muted);font-size:11px;font-weight:600;font-family:'SF Mono',ui-monospace,SFMono-Regular,Menlo,monospace;flex-shrink:0;align-self:flex-start;letter-spacing:.02em;} +#checkUpdatesBlock{display:inline-flex;align-items:center;gap:6px;font-size:12px;flex-shrink:0;align-self:flex-start;} +#checkUpdatesBlock .btn-tiny{padding:4px 10px;border-radius:8px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-size:11px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:border-color .15s,color .15s;} +#checkUpdatesBlock .btn-tiny:hover{border-color:var(--accent);color:var(--accent);} +#checkUpdatesBlock .btn-tiny:disabled{opacity:.5;cursor:default;} +#checkUpdatesBlock .btn-tiny .spinner-xs{width:12px;height:12px;border:2px solid var(--border);border-top-color:var(--text);border-radius:50%;animation:spin .6s linear infinite;display:none;} +#checkUpdatesStatus{font-size:11px;font-weight:500;white-space:nowrap;} /* Each logical form row is a card surface. Stack with comfortable gap. */ #mainSettings .settings-field{margin-bottom:12px;padding:16px;border:1px solid var(--border);border-radius:12px;background:var(--sidebar);}