import Gtk from "gi://Gtk?version=3.0" import AstalNetwork from "gi://AstalNetwork" import { type Binding, type Variable, Variable, bind } from "astal" import { ArrowToggleButton, Menu } from "./ToggleButton" const CONNECTING = [40, 50, 60, 70, 80, 90] const wifi = AstalNetwork.get_default().wifi function strongest(aps: AstalNetwork.AccessPoint[]) { const bySsid = new Map() for (const ap of aps) { const ssid = ap.ssid ?? "" const best = bySsid.get(ssid) if (!best || ap.strength > best.strength) bySsid.set(ssid, ap) } return [...bySsid.values()].sort((a, b) => b.strength - a.strength) } export const wifiIcon: Binding | null = wifi ? bind(wifi, "icon-name") : null function WifiRow( ap: AstalNetwork.AccessPoint, activeSsid: Binding, connect: (ap: AstalNetwork.AccessPoint) => void, ) { return ( ) } export function WifiSection({ open }: { open: Variable }) { if (!wifi) return null const expanded = Variable(false) const pendingAP = Variable(null) const failed = Variable("") const status = Variable.derive( [bind(wifi, "scanning"), bind(wifi, "state"), bind(wifi, "ssid"), failed], (scanning, state, ssid, fail) => { if (scanning) return "scanning…" if (CONNECTING.includes(state)) return `connecting to ${ssid ?? "network"}…` return fail }, ) const activeSsid = bind(wifi, "active-access-point").as((ap) => ap?.ssid ?? "") function connect(ap: AstalNetwork.AccessPoint) { if (ap.requires_password) { failed.set("") pendingAP.set(ap) } else { ap.activate() .then(() => failed.set("")) .catch(() => failed.set(`failed to connect to ${ap.ssid ?? "network"}`)) } } const passwordEntry = ( ap !== null)} placeholderText={pendingAP().as( (ap) => (ap ? `password for ${ap.ssid ?? "network"}` : ""), )} onActivate={(self) => { const ap = pendingAP.get() if (!ap || !self.text) return ap.activate(self.text) .then(() => { pendingAP.set(null) self.text = "" }) .catch(() => failed.set(`failed to connect to ${ap.ssid ?? "network"}`) ) }} /> ) open.subscribe((v) => { if (v) { wifi.scan() } else { expanded.set(false) pendingAP.set(null) failed.set("") passwordEntry.text = "" } }) const toggle = ( ssid || "Not Connected")} active={bind(wifi, "enabled")} onMainClick={() => { wifi.enabled = !wifi.enabled if (wifi.enabled) wifi.scan() }} onArrowClick={() => expanded.set(!expanded.get())} /> ) const menu = ( ) return { toggle, menu } }