38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { onSSEStatus, type SSEStatus } from '../api/sse';
|
|
|
|
/**
|
|
* SSE 连接状态指示器。
|
|
*
|
|
* 实时性是 Agent 协作的核心体验:断线后用户以为系统正常,实际上通知已经停了。
|
|
* 一个小小的绿/黄/红点就能避免「Agent 没在动」的误判。
|
|
*
|
|
* 不做成弹窗或横幅 —— 那会打断正在进行的对话。一个点足够了:
|
|
* 会看它的人自然会看,不会看的人不需要被打扰。
|
|
*/
|
|
export function ConnectionIndicator() {
|
|
const [status, setStatus] = useState<SSEStatus>('connecting');
|
|
|
|
useEffect(() => {
|
|
const unsub = onSSEStatus(setStatus);
|
|
return unsub;
|
|
}, []);
|
|
|
|
const map: Record<SSEStatus, { color: string; title: string }> = {
|
|
connecting: { color: 'bg-yellow-400', title: '正在连接…' },
|
|
connected: { color: 'bg-green-500', title: '已连接' },
|
|
reconnecting: { color: 'bg-orange-400', title: '重连中…' },
|
|
disconnected: { color: 'bg-red-400', title: '已断开' },
|
|
};
|
|
|
|
const { color, title } = map[status] || map.disconnected;
|
|
|
|
return (
|
|
<div
|
|
className={`w-2 h-2 rounded-full ${color} shrink-0 transition-colors duration-300`}
|
|
title={title}
|
|
aria-label={title}
|
|
/>
|
|
);
|
|
}
|