From 1f731072ac7e0bef369eedabfb396a41331e6ef2 Mon Sep 17 00:00:00 2001
From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
Date: Fri, 17 Jan 2025 14:55:50 +1100
Subject: networks: make popup window

---
 src/modules/popdowns/networks.tsx | 97 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 src/modules/popdowns/networks.tsx

(limited to 'src/modules/popdowns/networks.tsx')

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 />}
+        />
+    );
+};
-- 
cgit v1.2.3-freya

