import { NativeHeaderToolbar } from "../../native/StackHeader";import { useNavigation } from "@react-navigation/native";import { SymbolView } from "expo-symbols";import type { EnvironmentId } from "@t3tools/contracts";import { useCallback, useState } from "react";import { ScrollView, View } from "react-native";import { useSafeAreaInsets } from "react-native-safe-area-context";import { useThemeColor } from "../../lib/useThemeColor"; import { AppText as Text } from "../../components/AppText";import { cn } from "../../lib/cn";import { useRemoteConnections } from "../../state/use-remote-environment-registry";import { ConnectionEnvironmentRow } from "./ConnectionEnvironmentRow"; export function ConnectionsRouteScreen() { const { connectedEnvironments, onReconnectEnvironment, onRemoveEnvironmentPress, onUpdateEnvironment, } = useRemoteConnections(); const navigation = useNavigation(); const insets = useSafeAreaInsets(); const hasEnvironments = connectedEnvironments.length > 0; const [expandedId, setExpandedId] = useState<EnvironmentId | null>(null); const accentColor = useThemeColor("--color-icon-muted"); const handleToggle = useCallback((environmentId: EnvironmentId) => { setExpandedId((prev) => (prev === environmentId ? null : environmentId)); }, []); return ( <View collapsable={false} className="flex-1 bg-sheet"> <NativeHeaderToolbar placement="right"> <NativeHeaderToolbar.Button icon="plus" onPress={() => navigation.navigate("ConnectionsNew")} separateBackground /> </NativeHeaderToolbar> <ScrollView contentInsetAdjustmentBehavior="automatic" showsVerticalScrollIndicator={false} style={{ flex: 1 }} contentInset={{ bottom: Math.max(insets.bottom, 18) + 18 }} contentContainerStyle={{ paddingHorizontal: 20, paddingTop: 16, }} > {hasEnvironments ? ( <View collapsable={false} className="overflow-hidden rounded-[24px] bg-card"> {connectedEnvironments.map((environment, index) => ( <View key={environment.environmentId} collapsable={false} style={{ borderTopWidth: index === 0 ? 0 : 1, }} className={cn(index !== 0 && "border-border")} > <ConnectionEnvironmentRow environment={environment} expanded={expandedId === environment.environmentId} onToggle={() => handleToggle(environment.environmentId)} onReconnect={onReconnectEnvironment} onRemove={onRemoveEnvironmentPress} onUpdate={onUpdateEnvironment} /> </View> ))} </View> ) : ( <View collapsable={false} className="items-center gap-3 rounded-[24px] bg-card px-6 py-8"> <View className="h-12 w-12 items-center justify-center rounded-[16px] bg-subtle"> <SymbolView name="point.3.connected.trianglepath.dotted" size={20} tintColor={accentColor} type="monochrome" /> </View> <Text className="text-center text-sm leading-normal text-foreground-muted"> No environments connected yet.{"\n"}Tap{" "} <Text className="font-t3-bold text-foreground">+</Text> to add one. </Text> </View> )} </ScrollView> </View> );}
import { NativeHeaderToolbar } from "../../native/StackHeader";
import { useNavigation } from "@react-navigation/native";
import { SymbolView } from "expo-symbols";
import type { EnvironmentId } from "@t3tools/contracts";
import { useCallback, useState } from "react";
import { ScrollView, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useThemeColor } from "../../lib/useThemeColor";
import { AppText as Text } from "../../components/AppText";
import { cn } from "../../lib/cn";
import { useRemoteConnections } from "../../state/use-remote-environment-registry";
import { ConnectionEnvironmentRow } from "./ConnectionEnvironmentRow";
export function ConnectionsRouteScreen() {
const {
connectedEnvironments,
onReconnectEnvironment,
onRemoveEnvironmentPress,
onUpdateEnvironment,
} = useRemoteConnections();
const navigation = useNavigation();
const insets = useSafeAreaInsets();
const hasEnvironments = connectedEnvironments.length > 0;
const [expandedId, setExpandedId] = useState<EnvironmentId | null>(null);
const accentColor = useThemeColor("--color-icon-muted");
const handleToggle = useCallback((environmentId: EnvironmentId) => {
setExpandedId((prev) => (prev === environmentId ? null : environmentId));
}, []);
return (
<View collapsable={false} className="flex-1 bg-sheet">
<NativeHeaderToolbar placement="right">
<NativeHeaderToolbar.Button
icon="plus"
onPress={() => navigation.navigate("ConnectionsNew")}
separateBackground
/>
</NativeHeaderToolbar>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
showsVerticalScrollIndicator={false}
style={{ flex: 1 }}
contentInset={{ bottom: Math.max(insets.bottom, 18) + 18 }}
contentContainerStyle={{
paddingHorizontal: 20,
paddingTop: 16,
}}
>
{hasEnvironments ? (
<View collapsable={false} className="overflow-hidden rounded-[24px] bg-card">
{connectedEnvironments.map((environment, index) => (
<View
key={environment.environmentId}
collapsable={false}
style={{
borderTopWidth: index === 0 ? 0 : 1,
}}
className={cn(index !== 0 && "border-border")}
>
<ConnectionEnvironmentRow
environment={environment}
expanded={expandedId === environment.environmentId}
onToggle={() => handleToggle(environment.environmentId)}
onReconnect={onReconnectEnvironment}
onRemove={onRemoveEnvironmentPress}
onUpdate={onUpdateEnvironment}
/>
</View>
))}
</View>
) : (
<View collapsable={false} className="items-center gap-3 rounded-[24px] bg-card px-6 py-8">
<View className="h-12 w-12 items-center justify-center rounded-[16px] bg-subtle">
<SymbolView
name="point.3.connected.trianglepath.dotted"
size={20}
tintColor={accentColor}
type="monochrome"
/>
</View>
<Text className="text-center text-sm leading-normal text-foreground-muted">
No environments connected yet.{"\n"}Tap{" "}
<Text className="font-t3-bold text-foreground">+</Text> to add one.
</Text>
</View>
)}
</ScrollView>
</View>
);
}