diff --git a/src/engines/hermes/pages/chat.js b/src/engines/hermes/pages/chat.js index ac8811f..c5e2696 100644 --- a/src/engines/hermes/pages/chat.js +++ b/src/engines/hermes/pages/chat.js @@ -780,7 +780,7 @@ export function render() { if (hermesInstalled === false) { return `
- + ${escHtml(t('engine.chatHealthInstallMissing'))} ${escHtml(t('engine.chatHealthGoDashboard'))}
@@ -789,7 +789,7 @@ export function render() { if (!gwOnline) { return `
- + ${escHtml(t('engine.chatHealthGatewayDown'))} ${escHtml(t('engine.chatHealthGoDashboard'))}
diff --git a/src/engines/hermes/pages/env-editor.js b/src/engines/hermes/pages/env-editor.js index b369c19..91b1672 100644 --- a/src/engines/hermes/pages/env-editor.js +++ b/src/engines/hermes/pages/env-editor.js @@ -9,6 +9,7 @@ */ import { api } from '../../../lib/tauri-api.js' import { toast } from '../../../components/toast.js' +import { showConfirm } from '../../../components/modal.js' import { humanizeError } from '../../../lib/humanize-error.js' // NOTE: i18n keys for this page are not yet wired up in src/locales; using @@ -254,7 +255,12 @@ export function render() { } }) rowEl.querySelector('.env-delete-btn')?.addEventListener('click', async () => { - if (!confirm(`确定删除 ${row.key} 吗?`)) return + const ok = await showConfirm({ + message: `确定删除 ${row.key} 吗?`, + confirmText: '删除', + variant: 'danger', + }) + if (!ok) return try { await api.hermesEnvDelete(row.key) rows.splice(idx, 1) diff --git a/src/engines/hermes/pages/gateways.js b/src/engines/hermes/pages/gateways.js index 7ef1fbb..476c4bd 100644 --- a/src/engines/hermes/pages/gateways.js +++ b/src/engines/hermes/pages/gateways.js @@ -18,6 +18,7 @@ import { api } from '../../../lib/tauri-api.js' import { toast } from '../../../components/toast.js' import { showModal, showConfirm } from '../../../components/modal.js' import { humanizeError } from '../../../lib/humanize-error.js' +import { svgIcon } from '../lib/svg-icons.js' function escHtml(s) { return String(s ?? '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"') @@ -52,7 +53,7 @@ export function render() { ${error ? `
${escHtml(error)}
` : ''} ${(!loading && !error && !gateways.length) ? `
-
⚙️
+
${svgIcon('settings', { size: 32 })}
${escHtml(t('engine.hermesGatewaysEmpty'))}
${escHtml(t('engine.hermesGatewaysEmptyHint'))}
` : ''} @@ -123,7 +124,8 @@ export function render() { profiles = arr.map(p => (typeof p === 'string' ? p : (p.name || ''))).filter(Boolean) if (!profiles.includes('default')) profiles.unshift('default') } catch (e) { - error = String(e?.message || e) + // 保留 Error 对象、给 humanizeError 输出友好提示 + error = humanizeError(e, t('engine.hermesGatewaysLoadFailed') || 'Load failed') } finally { loading = false draw() diff --git a/src/engines/hermes/pages/memory.js b/src/engines/hermes/pages/memory.js index 656e635..45a2f1d 100644 --- a/src/engines/hermes/pages/memory.js +++ b/src/engines/hermes/pages/memory.js @@ -12,7 +12,7 @@ import { t } from '../../../lib/i18n.js' import { api } from '../../../lib/tauri-api.js' import { toast } from '../../../components/toast.js' -import { showContentModal } from '../../../components/modal.js' +import { showContentModal, showConfirm } from '../../../components/modal.js' import { humanizeError } from '../../../lib/humanize-error.js' function escHtml(s) { @@ -135,13 +135,20 @@ export function render() { const ta = overlay.querySelector('#hm-mem-modal-textarea') const cancelBtn = overlay.querySelector('[data-action="cancel"]') const saveBtn = overlay.querySelector('#hm-mem-modal-save') - const closeWithConfirm = () => { + const closeWithConfirm = async () => { if (!editing) { overlay.remove() return } const dirty = editing.buffer !== (data[editing.key] || '') - if (dirty && !confirm(t('engine.memoryUnsaved'))) return + if (dirty) { + const ok = await showConfirm({ + message: t('engine.memoryUnsaved'), + confirmText: t('common.confirm') || 'OK', + variant: 'danger', + }) + if (!ok) return + } editing = null overlay.remove() } @@ -183,10 +190,17 @@ export function render() { }) } - function cancelEdit() { + async function cancelEdit() { if (!editing) return const dirty = editing.buffer !== (data[editing.key] || '') - if (dirty && !confirm(t('engine.memoryUnsaved'))) return + if (dirty) { + const ok = await showConfirm({ + message: t('engine.memoryUnsaved'), + confirmText: t('common.confirm') || 'OK', + variant: 'danger', + }) + if (!ok) return + } editing = null document.querySelector('.hm-mem-modal-overlay')?.remove() draw() diff --git a/src/engines/hermes/pages/setup.js b/src/engines/hermes/pages/setup.js index 5ae91cd..a24e660 100644 --- a/src/engines/hermes/pages/setup.js +++ b/src/engines/hermes/pages/setup.js @@ -5,6 +5,7 @@ */ import { t } from '../../../lib/i18n.js' import { api, invalidate, isTauriRuntime } from '../../../lib/tauri-api.js' +import { toast } from '../../../components/toast.js' import { getActiveEngine } from '../../../lib/engine-manager.js' import { loadHermesProviders, @@ -611,7 +612,7 @@ export function render() { const provider = matched?.id || 'custom' if (!apiKey) { - alert('请输入 API Key') + toast(t('engine.installCustomEmpty') || '请输入 API Key', 'warning') return } try { @@ -619,7 +620,8 @@ export function render() { phase = 'gateway' await refreshHermes() } catch (e) { - alert(`配置保存失败: ${e}`) + const msg = String(e?.message || e).replace(/^Error:\s*/, '') + toast(`${t('engine.configSaveFailed') || '配置保存失败'}: ${msg}`, 'error') } } @@ -640,7 +642,7 @@ export function render() { errEl.textContent = msg || t('engine.gatewayStartFailed') errEl.style.display = 'block' } else { - alert(msg || t('engine.gatewayStartFailed')) + toast(msg || t('engine.gatewayStartFailed'), 'error') } } finally { gwStarting = false