import { Ionicons } from "@expo/vector-icons"; import { useEffect, useState } from "react"; import { Pressable, StyleSheet, Text, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { Input } from "@/components/ui/Input"; import { fonts, spacing } from "@/constants/theme"; import { useAccounts } from "@/contexts/AccountsContext"; import { useAppTheme } from "@/contexts/ThemeContext"; import { hasConfiguredInstanceUrl } from "@/lib/accounts"; type CollapsibleServerFieldProps = { defaultExpanded?: boolean; }; function formatServerLabel(url: string) { try { return new URL(url).host; } catch { return url.replace(/^https?:\/\//, ""); } } export function CollapsibleServerField({ defaultExpanded = false }: CollapsibleServerFieldProps) { const { colors } = useAppTheme(); const insets = useSafeAreaInsets(); const { apiUrl, setInstanceUrl } = useAccounts(); const [expanded, setExpanded] = useState(defaultExpanded); const [value, setValue] = useState(apiUrl); const [error, setError] = useState(null); useEffect(() => { hasConfiguredInstanceUrl().then((configured) => { if (!configured) setExpanded(true); }); }, []); useEffect(() => { setValue(apiUrl); }, [apiUrl]); async function commit() { const trimmed = value.trim(); if (!trimmed || trimmed === apiUrl) { setError(null); setExpanded(false); return; } try { const saved = await setInstanceUrl(trimmed); setValue(saved); setError(null); setExpanded(false); } catch (err) { setError(err instanceof Error ? err.message : "Could not save server URL"); } } return ( setExpanded((open) => !open)} hitSlop={8} style={({ pressed }) => [styles.trigger, pressed && styles.pressed]} > Server ยท{" "} {formatServerLabel(apiUrl)} {expanded ? ( Use your Mac's LAN IP on a physical device. ) : null} ); } const styles = StyleSheet.create({ wrapper: { flexDirection: "column-reverse", gap: spacing.sm, paddingHorizontal: spacing.md, }, trigger: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: spacing.xs, minHeight: 36, }, pressed: { opacity: 0.7, }, triggerText: { fontSize: 13, fontFamily: fonts.body, }, host: { fontFamily: fonts.mono, fontSize: 13, }, panel: { borderWidth: 1, borderRadius: 14, padding: spacing.md, gap: spacing.sm, }, hint: { fontSize: 12, fontFamily: fonts.body, lineHeight: 16, }, });