import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DnsIcon from '@mui/icons-material/Dns'; import GiteIcon from '@mui/icons-material/Gite'; import RouterIcon from '@mui/icons-material/Router'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputComponentIcon from '@mui/icons-material/SettingsInputComponent'; import WifiIcon from '@mui/icons-material/Wifi'; import { Avatar, Box, Divider, List, ListItem, ListItemAvatar, ListItemText, Typography, useTheme } from '@mui/material'; import type { Theme } from '@mui/material'; import * as NetworkApi from 'api/network'; import { useRequest } from 'alova/client'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { NetworkStatusType } from 'types'; import { NetworkConnectionStatus } from 'types'; import { useInterval } from 'utils'; // Utility functions const isConnected = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED || status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; export const isWiFi = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; export const isEthernet = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; const networkStatusHighlight = ({ status }: NetworkStatusType, theme: Theme) => { switch (status) { case NetworkConnectionStatus.WIFI_STATUS_IDLE: case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED: case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD: return theme.palette.info.main; case NetworkConnectionStatus.WIFI_STATUS_CONNECTED: case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED: return theme.palette.success.main; case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED: case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST: return theme.palette.error.main; default: return theme.palette.warning.main; } }; const networkQualityHighlight = ({ rssi }: NetworkStatusType, theme: Theme) => { if (rssi <= -85) { return theme.palette.error.main; } else if (rssi <= -75) { return theme.palette.warning.main; } return theme.palette.success.main; }; // one address per line, with an optional dimmed note such as the IPv6 scope const AddressList = ({ addresses }: { addresses: { value: string; note?: string }[]; }) => { if (addresses.length === 0) { return 'none'; } return addresses.map(({ value, note }) => ( {value} {note && ( ({note}) )} )); }; const isSet = (ip?: string): ip is string => !!ip && ip !== '0.0.0.0' && ip !== '::'; const ipAddresses = ({ local_ip, ipv6 }: NetworkStatusType) => [ ...(isSet(local_ip) ? [{ value: local_ip }] : []), ...(ipv6 ?? []).map(({ address, scope }) => ({ value: address, note: scope })) ]; const gateways = ({ gateway_ip, gateway_ipv6 }: NetworkStatusType) => [ ...(isSet(gateway_ip) ? [{ value: gateway_ip }] : []), ...(gateway_ipv6 ?? []).filter(isSet).map((value) => ({ value })) ]; const dnsServers = ({ dns }: NetworkStatusType) => (dns ?? []).filter(isSet).map((value) => ({ value })); const getNetworkStatusText = ( status: NetworkConnectionStatus, reconnectCount: number, LL: ReturnType['LL'] ) => { switch (status) { case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED: return LL.CONNECTED(0) + ' (Ethernet)'; case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD: return LL.INACTIVE(1); case NetworkConnectionStatus.WIFI_STATUS_IDLE: return LL.IDLE(); case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL: return 'No SSID Available'; case NetworkConnectionStatus.WIFI_STATUS_CONNECTED: return LL.CONNECTED(0) + ' (WiFi) (' + reconnectCount + ')'; case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED: return LL.CONNECTED(1) + ' ' + LL.FAILED(0) + ' (' + reconnectCount + ')'; case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST: return LL.CONNECTED(1) + ' ' + LL.LOST() + ' (' + reconnectCount + ')'; case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED: return LL.DISCONNECTED(); default: return LL.UNKNOWN(); } }; const NetworkStatus = () => { const { data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus); useInterval(() => { void loadData(); }); const { LL } = useI18nContext(); useLayoutTitle(LL.NETWORK(1)); const theme = useTheme(); if (!data) { return ( ); } const statusText = getNetworkStatusText(data.status, data.reconnect_count, LL); const statusColor = networkStatusHighlight(data, theme); const qualityColor = networkQualityHighlight(data, theme); return ( {isWiFi(data) && } {isEthernet(data) && } {isWiFi(data) && ( <> )} {isConnected(data) && ( <> IP } /> # } /> } /> )} ); }; export default NetworkStatus;