mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): localize toast messages and keep full session counts (#573)
Normalize hub toast text in the web client for i18n coverage (including Ready for input notifications) and stop deduplicating session rows by agentSessionId so outline/group counts reflect user-visible sessions. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+48
-3
@@ -239,14 +239,59 @@ function AppInner() {
|
||||
clearMessageWindow(event.sessionId)
|
||||
void fetchLatestMessages(api, event.sessionId)
|
||||
}, [api, selectedSessionId])
|
||||
const translateIncomingToast = useCallback((title: string, body: string): { title: string; body: string } => {
|
||||
const normalizedTitle = title.trim()
|
||||
const normalizedBody = body.trim()
|
||||
|
||||
if (normalizedTitle === 'Ready for input') {
|
||||
const waitingMatch = normalizedBody.match(/^(.+)\s+is waiting in\s+(.+)$/i)
|
||||
if (waitingMatch) {
|
||||
const agent = waitingMatch[1]?.trim() ?? ''
|
||||
const sessionName = waitingMatch[2]?.trim() ?? ''
|
||||
return {
|
||||
title: t('toast.ready.title'),
|
||||
body: t('toast.ready.body', { agent, session: sessionName })
|
||||
}
|
||||
}
|
||||
return {
|
||||
title: t('toast.ready.title'),
|
||||
body: normalizedBody
|
||||
}
|
||||
}
|
||||
|
||||
if (normalizedTitle === 'Permission Request') {
|
||||
return {
|
||||
title: t('toast.permission.title'),
|
||||
body: normalizedBody
|
||||
}
|
||||
}
|
||||
|
||||
if (normalizedTitle === 'Task completed') {
|
||||
return {
|
||||
title: t('toast.task.completed'),
|
||||
body: normalizedBody
|
||||
}
|
||||
}
|
||||
|
||||
if (normalizedTitle === 'Task failed') {
|
||||
return {
|
||||
title: t('toast.task.failed'),
|
||||
body: normalizedBody
|
||||
}
|
||||
}
|
||||
|
||||
return { title, body }
|
||||
}, [t])
|
||||
|
||||
const handleToast = useCallback((event: ToastEvent) => {
|
||||
const localized = translateIncomingToast(event.data.title, event.data.body)
|
||||
addToast({
|
||||
title: event.data.title,
|
||||
body: event.data.body,
|
||||
title: localized.title,
|
||||
body: localized.body,
|
||||
sessionId: event.data.sessionId,
|
||||
url: event.data.url
|
||||
})
|
||||
}, [addToast])
|
||||
}, [addToast, translateIncomingToast])
|
||||
|
||||
const eventSubscription = useMemo(() => {
|
||||
if (selectedSessionId) {
|
||||
|
||||
@@ -711,8 +711,8 @@ export function SessionList(props: {
|
||||
}
|
||||
|
||||
const allSessions = useMemo(
|
||||
() => deduplicateSessionsByAgentId(props.sessions, selectedSessionId),
|
||||
[props.sessions, selectedSessionId]
|
||||
() => props.sessions,
|
||||
[props.sessions]
|
||||
)
|
||||
const visibleSessions = useMemo(
|
||||
() => isSearching
|
||||
|
||||
@@ -274,6 +274,12 @@ export default {
|
||||
// Send blocked
|
||||
'send.blocked.title': 'Cannot send message',
|
||||
'send.blocked.noConnection': 'Not connected to server',
|
||||
'resume.failed.title': 'Resume failed',
|
||||
'toast.ready.title': 'Ready for input',
|
||||
'toast.ready.body': '{agent} is waiting in {session}',
|
||||
'toast.permission.title': 'Permission Request',
|
||||
'toast.task.completed': 'Task completed',
|
||||
'toast.task.failed': 'Task failed',
|
||||
|
||||
// Install prompt
|
||||
'install.title': 'Install HAPI',
|
||||
|
||||
@@ -276,6 +276,12 @@ export default {
|
||||
// Send blocked
|
||||
'send.blocked.title': '无法发送消息',
|
||||
'send.blocked.noConnection': '未连接到服务器',
|
||||
'resume.failed.title': '恢复会话失败',
|
||||
'toast.ready.title': '等待输入',
|
||||
'toast.ready.body': '{agent} 正在 {session} 等待你的输入',
|
||||
'toast.permission.title': '权限请求',
|
||||
'toast.task.completed': '任务完成',
|
||||
'toast.task.failed': '任务失败',
|
||||
|
||||
// Install prompt
|
||||
'install.title': '安装 HAPI',
|
||||
|
||||
+2
-2
@@ -276,9 +276,9 @@ function SessionPage() {
|
||||
try {
|
||||
return await api.resumeSession(currentSessionId, { permissionMode: session.permissionMode ?? undefined })
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Resume failed'
|
||||
const message = error instanceof Error ? error.message : t('dialog.error.default')
|
||||
addToast({
|
||||
title: 'Resume failed',
|
||||
title: t('resume.failed.title'),
|
||||
body: message,
|
||||
sessionId: currentSessionId,
|
||||
url: ''
|
||||
|
||||
Reference in New Issue
Block a user