import { NETWORK_INTERFACES } from "@/settings.json"; import { toHumanReadable } from "@/lib/utils"; import Network from "gi://AstalNetwork"; import { bind, Variable } from "astal"; type IpOutput = Array<{ ifname: string; stats64: { rx: { bytes: number }; tx: { bytes: number }; }; }>; type Usage = { initialRx: number | null; initialTx: number | null; totalRx: number; totalTx: number; }; const getConnection = (instance?: Network.Wifi | Network.Wired) => { if (!instance) return null; const addresses = (instance instanceof Network.Wifi ? instance?.activeConnection : instance?.connection) ?.ip4Config?.get_addresses(); return addresses.map(addr => addr.get_address()).join(", "); } export default function NetworkInfo() { const net = Network.get_default(); const wiredConn = bind(net, "wired"); const wifiConn = bind(net, "wifi"); const currentConn = Variable.derive([ wiredConn, wifiConn ], (wired, wifi) => { switch (net.primary) { case Network.Primary.WIFI: return wifi; case Network.Primary.WIRED: return wired; default: return; } }) const networkInterface = net.primary == 1 ? NETWORK_INTERFACES.wired : NETWORK_INTERFACES.wifi; const networkUsage = Variable({ initialRx: null, initialTx: null, totalRx: 0, totalTx: 0, }).poll( 5000, ['ip', '-s', '-j', 'link', 'show', networkInterface], (out, prev) => { const ipOutput = JSON.parse(out) as IpOutput; const totalRx = ipOutput?.reduce((prev, item) => prev + item.stats64.rx.bytes, 0); const totalTx = ipOutput?.reduce((prev, item) => prev + item.stats64.tx.bytes, 0); return { initialRx: prev.initialRx ?? totalRx, initialTx: prev.initialTx ?? totalTx, totalTx, totalRx, }; } ); const dataBinding = bind(networkUsage); const binding = bind(currentConn); return binding.as(Boolean) ? <> {binding.as(getConnection).as(data => data &&