diff --git a/package-lock.json b/package-lock.json index 7d4c33f..8bf4895 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pinchchat", - "version": "1.59.0", + "version": "1.60.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pinchchat", - "version": "1.59.0", + "version": "1.60.0", "license": "MIT", "dependencies": { "@tailwindcss/vite": "^4.1.18", diff --git a/package.json b/package.json index f5ea818..33f0d33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pinchchat", - "version": "1.59.0", + "version": "1.60.0", "description": "A sleek, dark-themed webchat UI for OpenClaw — monitor sessions, stream responses, and inspect tool calls in real-time.", "type": "module", "repository": { diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index f8a187f..f742b51 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -466,7 +466,9 @@ export function Sidebar({ sessions, activeSession, onSwitch, onDelete, onSplit, )} {s.hasUnread && !isActive && ( - + + {(s.unreadCount || 1) > 99 ? '99+' : (s.unreadCount || 1)} + )}
diff --git a/src/hooks/useGateway.ts b/src/hooks/useGateway.ts index f7e18ce..845fe60 100644 --- a/src/hooks/useGateway.ts +++ b/src/hooks/useGateway.ts @@ -53,7 +53,7 @@ export function useGateway() { useEffect(() => { activeSessionRef.current = activeSession; }, [activeSession]); const currentRunIdRef = useRef(null); const [activeSessions, setActiveSessions] = useState>(new Set()); - const [unreadSessions, setUnreadSessions] = useState>(new Set()); + const [unreadSessions, setUnreadSessions] = useState>(new Map()); const [agentIdentity, setAgentIdentity] = useState(null); /** Map of runId → generation duration (ms), preserved across loadHistory reloads */ const generationTimesRef = useRef>(new Map()); @@ -337,9 +337,8 @@ export function useGateway() { // Mark non-active sessions as unread when they receive a final message if (state === 'final' && evtSession) { setUnreadSessions(prev => { - if (prev.has(evtSession)) return prev; - const next = new Set(prev); - next.add(evtSession); + const next = new Map(prev); + next.set(evtSession, (prev.get(evtSession) || 0) + 1); return next; }); } @@ -483,7 +482,7 @@ export function useGateway() { setMessages([]); setUnreadSessions(prev => { if (!prev.has(key)) return prev; - const next = new Set(prev); + const next = new Map(prev); next.delete(key); return next; }); @@ -538,6 +537,7 @@ export function useGateway() { ...s, isActive: activeSessions.has(s.key), hasUnread: unreadSessions.has(s.key), + unreadCount: unreadSessions.get(s.key) || 0, })); const getClient = useCallback(() => clientRef.current, []); diff --git a/src/types/index.ts b/src/types/index.ts index dee75c3..a63afb4 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -33,6 +33,7 @@ export interface Session { messageCount?: number; isActive?: boolean; hasUnread?: boolean; + unreadCount?: number; totalTokens?: number; contextTokens?: number; inputTokens?: number;