import { Ionicons } from "@expo/vector-icons"; import type React from "react"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Switch, TouchableOpacity, View } from "react-native"; import { toast } from "sonner-native"; import { useWifiSSID } from "@/hooks/useWifiSSID"; import { useServerUrl } from "@/providers/ServerUrlProvider"; import { storage } from "@/utils/mmkv"; import { getServerLocalConfig, type LocalNetworkConfig, updateServerLocalConfig, } from "@/utils/secureCredentials"; import { Button } from "../Button"; import { Input } from "../common/Input"; import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; import { ListItem } from "../list/ListItem"; const DEFAULT_CONFIG: LocalNetworkConfig = { localUrl: "", homeWifiSSIDs: [], enabled: false, }; interface StatusDisplayProps { currentSSID: string | null; isUsingLocalUrl: boolean; t: (key: string) => string; } function StatusDisplay({ currentSSID, isUsingLocalUrl, t, }: StatusDisplayProps): React.ReactElement { const wifiStatus = currentSSID ?? t("home.settings.network.not_connected"); const urlType = isUsingLocalUrl ? t("home.settings.network.local") : t("home.settings.network.remote"); const urlTypeColor = isUsingLocalUrl ? "text-green-500" : "text-blue-500"; return ( {t("home.settings.network.current_wifi")} {wifiStatus} {t("home.settings.network.using_url")} {urlType} ); } export function LocalNetworkSettings(): React.ReactElement | null { const { t } = useTranslation(); const { permissionStatus, requestPermission } = useWifiSSID(); const { isUsingLocalUrl, currentSSID, refreshUrlState } = useServerUrl(); const remoteUrl = storage.getString("serverUrl"); const [config, setConfig] = useState(DEFAULT_CONFIG); useEffect(() => { if (remoteUrl) { const existingConfig = getServerLocalConfig(remoteUrl); if (existingConfig) { setConfig(existingConfig); } } }, [remoteUrl]); const saveConfig = useCallback( (newConfig: LocalNetworkConfig) => { if (!remoteUrl) return; setConfig(newConfig); updateServerLocalConfig(remoteUrl, newConfig); // Trigger URL re-evaluation after config change refreshUrlState(); }, [remoteUrl, refreshUrlState], ); const handleToggleEnabled = useCallback( async (enabled: boolean) => { if (enabled && permissionStatus !== "granted") { const granted = await requestPermission(); if (!granted) { toast.error(t("home.settings.network.permission_denied")); return; } } saveConfig({ ...config, enabled }); }, [config, permissionStatus, requestPermission, saveConfig, t], ); const handleLocalUrlChange = useCallback( (localUrl: string) => { saveConfig({ ...config, localUrl }); }, [config, saveConfig], ); const handleAddCurrentNetwork = useCallback(() => { if (!currentSSID) { toast.error(t("home.settings.network.no_wifi_connected")); return; } if (config.homeWifiSSIDs.includes(currentSSID)) { toast.info(t("home.settings.network.network_already_added")); return; } saveConfig({ ...config, homeWifiSSIDs: [...config.homeWifiSSIDs, currentSSID], }); toast.success(t("home.settings.network.network_added")); }, [config, currentSSID, saveConfig, t]); const handleRemoveNetwork = useCallback( (ssidToRemove: string) => { saveConfig({ ...config, homeWifiSSIDs: config.homeWifiSSIDs.filter((s) => s !== ssidToRemove), }); }, [config, saveConfig], ); if (!remoteUrl) return null; const addNetworkButtonText = currentSSID ? t("home.settings.network.add_current_network", { ssid: currentSSID }) : t("home.settings.network.not_connected_to_wifi"); return ( {config.enabled && ( {t("home.settings.network.local_url_hint")} } > {config.homeWifiSSIDs.map((wifiSSID) => ( handleRemoveNetwork(wifiSSID)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > ))} {config.homeWifiSSIDs.length === 0 && ( )} )} {permissionStatus === "denied" && ( {t("home.settings.network.permission_denied_explanation")} )} ); }