feat(session-status): mobile session quick switch with running/unread indicators (#340)

* feat(session-status): implement server-authoritative session status tracking

- Add server-side session states and attention tracking with Map storage
- Implement SSE event broadcasting (openchamber:session-status)
- Add REST API endpoints for status/attention queries
- Replace client-side polling with HTTP polling + SSE push
- Track needsAttention based on user message + completion + unviewed
- Add MobileSessionStatusBar for mobile UI
- Handle session view/unview/message-sent state transitions
- Add 24h cleanup for old session states

* feat(session-status): add unread indicator to mobile session status bar

* refactor(session-status): extract SessionStatusHeader component

Extract the session status header into a reusable component and improve
layout structure in CollapsedView and ExpandedView.

* feat(session-status): optimize mobile session status bar UI

* refactor(session-status): remove interval polling, use snapshot sync on reconnect/visibility

- unifies session status/attention sync with existing SSE lifecycle, fixes no-op store churn bug, and drops duplicated client activity state while preserving mobile unread/running UX.

---------

Co-authored-by: Jovines <jovines@qq.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Jovines
2026-02-07 03:11:55 +02:00
committed by GitHub
co-authored by Jovines Bohdan Triapitsyn
parent aa85e31420
commit d5a2e49ae8
10 changed files with 1283 additions and 146 deletions
+7
View File
@@ -75,6 +75,7 @@ interface UIStore {
showTerminalQuickKeysOnDesktop: boolean;
persistChatDraft: boolean;
isMobileSessionStatusBarCollapsed: boolean;
setTheme: (theme: 'light' | 'dark' | 'system') => void;
toggleSidebar: () => void;
@@ -135,6 +136,7 @@ interface UIStore {
setShowTerminalQuickKeysOnDesktop: (value: boolean) => void;
setNotifyOnSubtasks: (value: boolean) => void;
setPersistChatDraft: (value: boolean) => void;
setIsMobileSessionStatusBarCollapsed: (value: boolean) => void;
openMultiRunLauncher: () => void;
openMultiRunLauncherWithPrompt: (prompt: string) => void;
}
@@ -199,6 +201,7 @@ export const useUIStore = create<UIStore>()(
showTerminalQuickKeysOnDesktop: false,
persistChatDraft: true,
isMobileSessionStatusBarCollapsed: false,
setTheme: (theme) => {
set({ theme });
@@ -688,6 +691,9 @@ export const useUIStore = create<UIStore>()(
setPersistChatDraft: (value) => {
set({ persistChatDraft: value });
},
setIsMobileSessionStatusBarCollapsed: (value) => {
set({ isMobileSessionStatusBarCollapsed: value });
},
}),
{
name: 'ui-store',
@@ -726,6 +732,7 @@ export const useUIStore = create<UIStore>()(
showTerminalQuickKeysOnDesktop: state.showTerminalQuickKeysOnDesktop,
notifyOnSubtasks: state.notifyOnSubtasks,
persistChatDraft: state.persistChatDraft,
isMobileSessionStatusBarCollapsed: state.isMobileSessionStatusBarCollapsed,
})
}
),