1import type { WorkspaceState } from "../../state/workspaceModel";
2
3export interface WorkspaceConnectionStatusPresentation {
4 readonly label: string;
5 readonly showsProgress: boolean;
6}
7
8function shouldShowWorkspaceConnectionStatus(state: WorkspaceState): boolean {
9 if (state.networkStatus === "offline") return true;
10 if (state.hasReadyEnvironment) return state.hasSyncingConnectedEnvironment;
11 return (
12 state.connectionError !== null ||
13 state.hasConnectingEnvironment ||
14 state.hasPendingShellSnapshot ||
15 (state.hasLoadedShellSnapshot && !state.hasReadyEnvironment)
16 );
17}
18
19function workspaceConnectionStatusLabel(state: WorkspaceState): string {
20 if (state.networkStatus === "offline") return "You are offline";
21 if (state.hasReadyEnvironment && state.hasSyncingConnectedEnvironment) {
22 return state.hasLoadedShellSnapshot ? "Syncing threads..." : "Loading threads...";
23 }
24 if (state.connectingEnvironments.length === 1) {
25 return `Reconnecting to ${state.connectingEnvironments[0]!.environmentLabel}`;
26 }
27 if (state.connectingEnvironments.length > 1) {
28 return `Reconnecting ${state.connectingEnvironments.length} environments`;
29 }
30 if (state.connectionError !== null) return state.connectionError;
31 if (state.hasPendingShellSnapshot) {
32 return state.hasLoadedShellSnapshot ? "Syncing threads..." : "Loading threads...";
33 }
34 return "Not connected";
35}
36
37export function workspaceConnectionStatusPresentation(
38 state: WorkspaceState,
39): WorkspaceConnectionStatusPresentation | null {
40 if (!shouldShowWorkspaceConnectionStatus(state)) return null;
41 return {
42 label: workspaceConnectionStatusLabel(state),
43 showsProgress:
44 state.networkStatus !== "offline" &&
45 (state.hasReadyEnvironment || state.connectionError === null) &&
46 (state.connectingEnvironments.length > 0 || state.hasPendingShellSnapshot),
47 };
48}