diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-01-17 14:55:50 +1100 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-01-17 14:55:50 +1100 |
| commit | 1f731072ac7e0bef369eedabfb396a41331e6ef2 (patch) | |
| tree | d555c97ad797901be6b62eb8d0c9173db98cd40c /src/modules/popdowns | |
| parent | bluetoothdevices: fallback icon (diff) | |
| download | caelestia-shell-1f731072ac7e0bef369eedabfb396a41331e6ef2.tar.gz caelestia-shell-1f731072ac7e0bef369eedabfb396a41331e6ef2.tar.bz2 caelestia-shell-1f731072ac7e0bef369eedabfb396a41331e6ef2.zip | |
networks: make popup window
Diffstat (limited to 'src/modules/popdowns')
| -rw-r--r-- | src/modules/popdowns/index.tsx | 2 | ||||
| -rw-r--r-- | src/modules/popdowns/networks.tsx | 97 |
2 files changed, 99 insertions, 0 deletions
diff --git a/src/modules/popdowns/index.tsx b/src/modules/popdowns/index.tsx index ee6208d..44668a8 100644 --- a/src/modules/popdowns/index.tsx +++ b/src/modules/popdowns/index.tsx @@ -1,4 +1,5 @@ import BluetoothDevices from "./bluetoothdevices"; +import Networks from "./networks"; import Notifications from "./notifications"; import Updates from "./updates"; @@ -6,6 +7,7 @@ export default () => { <Notifications />; <Updates />; <BluetoothDevices />; + <Networks />; return null; }; diff --git a/src/modules/popdowns/networks.tsx b/src/modules/popdowns/networks.tsx new file mode 100644 index 0000000..0e9fe2f --- /dev/null +++ b/src/modules/popdowns/networks.tsx @@ -0,0 +1,97 @@ +import { bind, execAsync, Variable } from "astal"; +import { Gtk } from "astal/gtk3"; +import AstalNetwork from "gi://AstalNetwork"; +import PopdownWindow from "../../widgets/popdownwindow"; + +const Network = (accessPoint: AstalNetwork.AccessPoint) => ( + <box className="network"> + <icon className="icon" icon={bind(accessPoint, "iconName")} /> + <label + truncate + xalign={0} + setup={self => { + const update = () => + (self.label = `${accessPoint.ssid}${` (${accessPoint.frequency > 5000 ? 5 : 2.4}GHz | ${ + accessPoint.strength + }/100)`}`); + self.hook(accessPoint, "notify::ssid", update); + self.hook(accessPoint, "notify::frequency", update); + self.hook(accessPoint, "notify::strength", update); + update(); + }} + /> + <box hexpand /> + <button + cursor="pointer" + onClicked={self => { + const cmd = + AstalNetwork.get_default().wifi.activeAccessPoint === accessPoint ? "c down id" : "d wifi connect"; + execAsync(`nmcli ${cmd} '${accessPoint.ssid}'`) + .then(() => (self.sensitive = true)) + .catch(console.error); + self.sensitive = false; + }} + label={bind(AstalNetwork.get_default().wifi, "activeAccessPoint").as(a => + a === accessPoint ? "Disconnect" : "Connect" + )} + /> + <button + cursor="pointer" + onClicked={() => execAsync(`nmcli c delete id '${accessPoint.ssid}'`).catch(() => {})} + label="Forget" + /> + </box> +); + +const List = () => { + const { wifi } = AstalNetwork.get_default(); + const children = Variable.derive([bind(wifi, "accessPoints"), bind(wifi, "activeAccessPoint")], (aps, ac) => + aps + .filter(a => a.ssid) + .sort((a, b) => (a === ac ? -1 : b.strength - a.strength)) + .map(Network) + ); + + return ( + <box vertical valign={Gtk.Align.START} className="list" onDestroy={() => children.drop()}> + {bind(children)} + </box> + ); +}; + +export default () => { + const network = AstalNetwork.get_default(); + const label = Variable(""); + + const update = () => { + if (network.primary === AstalNetwork.Primary.WIFI) label.set(network.wifi.ssid ?? "Disconnected"); + else if (network.primary === AstalNetwork.Primary.WIRED) label.set(`Ethernet (${network.wired.speed})`); + else label.set("No Wifi"); + }; + network.connect("notify::primary", update); + network.get_wifi()?.connect("notify::ssid", update); + network.get_wired()?.connect("notify::speed", update); + update(); + + return ( + <PopdownWindow + name="networks" + count={bind(network.wifi, "accessPoints").as(a => a.length)} + countLabel={bind(label)} + headerButtons={[ + { + label: bind(network.wifi, "enabled").as(p => (p ? "Disable" : "Enable")), + onClicked: () => (network.wifi.enabled = !network.wifi.enabled), + }, + { + label: "Scan", + onClicked: () => network.wifi.scan(), + enabled: bind(network.wifi, "scanning"), + }, + ]} + emptyIcon="wifi_off" + emptyLabel={bind(network.wifi, "enabled").as(p => (p ? "No available networks" : "Wifi is off"))} + list={<List />} + /> + ); +}; |