| 1 | import type { EnvironmentId } from "@t3tools/contracts"; |
| 2 | import type { ComponentProps } from "react"; |
| 3 | import { useAtomValue } from "@effect/atom-react"; |
| 4 | import { View } from "react-native"; |
| 5 | |
| 6 | import { SymbolView } from "../../components/AppSymbol"; |
| 7 | import { AppText as Text } from "../../components/AppText"; |
| 8 | import { ConnectionEnvironmentRow } from "./ConnectionEnvironmentRow"; |
| 9 | import { hubConnection } from "../../connection/hub"; |
| 10 | |
| 11 | type EnvironmentRowProps = ComponentProps<typeof ConnectionEnvironmentRow>; |
| 12 | |
| 13 | /** Shared list and empty state for environment management entry points. */ |
| 14 | export function LocalEnvironmentList({ |
| 15 | environments, |
| 16 | expandedId, |
| 17 | onToggle, |
| 18 | ...rowActions |
| 19 | }: Pick< |
| 20 | EnvironmentRowProps, |
| 21 | "onReconnect" | "onRemove" | "onSetEnabled" | "onUpdate" | "opensDetails" |
| 22 | > & { |
| 23 | readonly environments: ReadonlyArray<EnvironmentRowProps["environment"]>; |
| 24 | readonly expandedId: EnvironmentId | null; |
| 25 | readonly onToggle: (environmentId: EnvironmentId) => void; |
| 26 | }) { |
| 27 | const hub = useAtomValue(hubConnection.stateValueAtom); |
| 28 | |
| 29 | if (environments.length === 0) { |
| 30 | return ( |
| 31 | <View |
| 32 | collapsable={false} |
| 33 | className="items-center gap-3 rounded-[24px] bg-grouped-card px-6 py-8" |
| 34 | > |
| 35 | <View className="h-12 w-12 items-center justify-center rounded-[16px] bg-subtle"> |
| 36 | <SymbolView |
| 37 | name="point.3.connected.trianglepath.dotted" |
| 38 | size={20} |
| 39 | tintColorClassName="accent-icon-muted" |
| 40 | type="monochrome" |
| 41 | /> |
| 42 | </View> |
| 43 | <Text className="text-center text-sm leading-normal text-foreground-muted"> |
| 44 | {hub.connection ? ( |
| 45 | <>No machines connected.{"\n"}Join this server from a computer to add one.</> |
| 46 | ) : ( |
| 47 | <> |
| 48 | No environments connected yet.{"\n"}Tap{" "} |
| 49 | <Text className="font-t3-bold text-foreground">+</Text> to add one. |
| 50 | </> |
| 51 | )} |
| 52 | </Text> |
| 53 | </View> |
| 54 | ); |
| 55 | } |
| 56 | |
| 57 | return ( |
| 58 | <View collapsable={false} className="overflow-hidden rounded-[24px] bg-grouped-card"> |
| 59 | {environments.map((environment) => ( |
| 60 | <View key={environment.environmentId} collapsable={false}> |
| 61 | <ConnectionEnvironmentRow |
| 62 | environment={environment} |
| 63 | expanded={expandedId === environment.environmentId} |
| 64 | onToggle={() => onToggle(environment.environmentId)} |
| 65 | {...rowActions} |
| 66 | /> |
| 67 | </View> |
| 68 | ))} |
| 69 | </View> |
| 70 | ); |
| 71 | } |