Skip to content
Source
Sign inSign up
Open History to see the last commit

floating-working-status.ts

100 lines3.2 KB

1import type { EnvironmentConnectionPhase } from "@t3tools/client-runtime/connection";
2import type { EnvironmentId } from "@t3tools/contracts";
3​
4export interface FloatingStatusAction {
5 readonly label: string;
6 readonly accessibilityLabel: string;
7 readonly disabled: boolean;
8 readonly onPress: () => void;
9}
10​
11export type FloatingWorkingStatus =
12 | { readonly kind: "working"; readonly environmentId: EnvironmentId; readonly startedAt: string }
13 | { readonly kind: "compacting" }
14 | {
15 readonly kind: "child-input";
16 readonly label: string;
17 readonly accessibilityLabel: string;
18 readonly onPress: () => void;
19 }
20 | {
21 readonly kind: "background";
22 readonly label: string;
23 readonly accessibilityLabel: string;
24 readonly waiting: boolean;
25 readonly onPress: () => void;
26 readonly action: FloatingStatusAction;
27 }
28 | {
29 readonly kind: "lifecycle";
30 readonly state: "snoozed" | "settled" | "woke";
31 readonly label: string;
32 readonly action: FloatingStatusAction;
33 }
34 | {
35 readonly kind: "stop";
36 readonly label: string;
37 readonly unresponsive: boolean;
38 readonly action: FloatingStatusAction | null;
39 }
40 | { readonly kind: "goal"; readonly label: string; readonly accessibilityLabel: string }
41 | { readonly kind: "extension"; readonly label: string; readonly onPress: () => void }
42 | { readonly kind: "preparing"; readonly label: string }
43 | {
44 readonly kind: "connection";
45 readonly tone: "reconnecting" | "unavailable";
46 readonly label: string;
47 readonly onPress: () => void;
48 };
49​
50export function connectionFloatingStatus(input: {
51 readonly connectionError: string | null;
52 readonly connectionState: EnvironmentConnectionPhase;
53 readonly connectionAwaitingApproval?: boolean;
54 readonly environmentLabel: string | null;
55 readonly onReconnect: () => void;
56}): FloatingWorkingStatus | null {
57 const environmentLabel = input.environmentLabel ?? "Environment";
58 const unavailable = (label: string): FloatingWorkingStatus => ({
59 kind: "connection",
60 tone: "unavailable",
61 label,
62 onPress: input.onReconnect,
63 });
64​
65 if (input.connectionState === "reconnecting" && input.connectionAwaitingApproval) {
66 return {
67 kind: "connection",
68 tone: "reconnecting",
69 label: `Waiting for ${environmentLabel} to approve this device`,
70 onPress: input.onReconnect,
71 };
72 }
73 switch (input.connectionState) {
74 case "connecting":
75 case "reconnecting":
76 return {
77 kind: "connection",
78 tone: "reconnecting",
79 label:
80 input.connectionError === null
81 ? `Reconnecting to ${environmentLabel}...`
82 : `Failed to connect. Retrying ${environmentLabel}...`,
83 onPress: input.onReconnect,
84 };
85 case "offline":
86 return unavailable("You are offline");
87 case "unsupported":
88 return unavailable("Client not supported");
89 case "error":
90 return unavailable(
91 input.connectionError
92 ? `Failed to connect to ${environmentLabel}: ${input.connectionError}`
93 : `Failed to connect to ${environmentLabel}`,
94 );
95 case "available":
96 return unavailable(`${environmentLabel} is not connected`);
97 case "connected":
98 return null;
99 }