Bladeren bron

finished network widget

Johan Rong 3 maanden geleden
bovenliggende
commit
68212586fe

+ 18 - 0
home/features/desktop/sway/ui/eww/network/default.nix

@@ -18,6 +18,10 @@ in
         source = ./scripts/connected.py;
         executable = true;
       };
+      "${scripts}/devices.py" = {
+        source = ./scripts/devices.py;
+        executable = true;
+      };
 
       "${scripts}/connect_wifi.sh" = {
         source = ./scripts/connect_wifi.sh;
@@ -30,6 +34,20 @@ in
         '';
         executable = true;
       };
+      "${scripts}/device_up.sh" = {
+        text = ''
+          #!/usr/bin/env bash
+          nmcli device up "$1"
+        '';
+        executable = true;
+      };
+      "${scripts}/device_down.sh" = {
+        text = ''
+          #!/usr/bin/env bash
+          nmcli device down "$1"
+        '';
+        executable = true;
+      };
     };
   };
 }

+ 72 - 16
home/features/desktop/sway/ui/eww/network/network.scss

@@ -1,38 +1,94 @@
 .network-menu {
     background: #0A0101;
-    padding: 16px;
-    min-width: 320px;
+    padding: 20px;
+    min-width: 360px;
     transition: all 0.3s ease-in;
 }
 
 .title {
-    font-size: 22px;
-    margin-bottom: 12px;
+    font-size: 24px;
+    font-weight: 700;
+    margin-bottom: 8px;
+    color: #ffffff;
+}
+
+.subtitle {
+    font-size: 11px;
+    color: #999999;
+    margin-bottom: 16px;
+    font-weight: 500;
 }
 
 button {
-    background: #0A0101;
-    border-radius: 14px;
-    padding: 10px;
-    margin: 4px 0;
+    background: transparent;
+    border: none;
+    padding: 0;
+    margin: 0;
+    all: unset;
 }
 
 button:hover {
-    background: #190202;
-}   
+    opacity: 0.8;
+}
 
-button.active-wifi {
+.network-item {
     background: #140202;
+    border-radius: 20px;
+    padding: 12px 16px;
+    transition: all 0.2s ease;
 }
 
-button.active-wifi:hover {
+.network-item:hover {
     background: #190202;
 }
 
-button.inactive-wifi {
-    background: #0A0101;
+.network-item.active {
+    background: #3a0505;
+    border: 1px solid #1A0909;
+}
+
+.network-item.active:hover {
+    background: #450707;
+}
+
+.network-header {
+}
+
+.network-info {
+}
+
+.network-name {
+    font-size: 13px;
+    font-weight: 600;
+    color: #ffffff;
+}
+
+.network-subtext {
+    font-size: 11px;
+    color: #999999;
+}
+
+.network-signal {
+    font-size: 12px;
+    color: #aaaaaa;
+} 
+
+.network-icon {
+    font-size: 24px;
+    font-family: "Material Symbols Outlined";
+}
+
+.device-item {
+    padding: 12px 16px;
+    transition: all 0.2s ease;
+}
+
+.device-icon {
+    font-size: 20px;
+    font-family: "Material Symbols Outlined";
 }
 
-button.inactive-wifi:hover {
-    background: #261616;
+.device-subtext {
+    font-size: 11px;
+    color: #999999;
 }

+ 15 - 3
home/features/desktop/sway/ui/eww/network/network.yuck

@@ -3,8 +3,13 @@
     "~/.config/eww/widgets/network/scripts/available_wifi.py"
 )
 
+(defpoll devices
+    :interval "5s"
+    "~/.config/eww/widgets/network/scripts/devices.py"
+)
+
 (defwindow network
-    :monitor 0 ; fiks slik at den kommer på riktig skjerm
+    :monitor 0
     :geometry (geometry
         :width "300px"
         :height "500px"
@@ -18,6 +23,7 @@
     (box
         :orientation "v"
         :class "network-menu"
+        :space-evenly false
 
         (label
             :class "title"
@@ -26,9 +32,15 @@
             :yalign 0.2
         )
 
+        (literal :content devices)
+
         (scroll
-            :vexpand false
-            (literal :content available_networks)
+            :vexpand true
+            (box
+                :orientation "v"
+                :spacing 8
+                (literal :content available_networks)
+            )
         )
     )
 )

+ 0 - 38
home/features/desktop/sway/ui/eww/network/scripts/available_other.py

@@ -1,38 +0,0 @@
-def get_wired() -> list:
-    ret = []
-    cmd = r"""
-    nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device status | grep ethernet
-    """
-    eth = subprocess.run(
-        cmd,
-        shell = True,
-        text = True,
-        capture_output = True,
-        check = True,
-    )
-    if eth.check_returncode():
-        return
-    
-    for line in eth.stdout.strip().split("\n"):
-        parts = line.split(":")
-
-        device = parts[0]
-        if device == "":
-            continue
-        typ = parts[1]
-        if typ == "":
-            continue
-        state = parts[2]
-        if state == "" or state == "unavailable":
-            continue
-        connection = parts[3]
-        if connection == "":
-            continue
-        
-        ret.append({
-            "device": device,
-            "type": typ,
-            "state": state,
-            "name": connection,
-        })
-    return ret

+ 40 - 27
home/features/desktop/sway/ui/eww/network/scripts/available_wifi.py

@@ -57,49 +57,62 @@ def get_networks() -> list:
 
 def get_available() -> list:
     available_networks = get_networks()
-
     available_networks = sorted(available_networks, key=lambda x: (0 if x["active"] else 1, -x["signal"]))
-
     return available_networks
 
+def signal_to_bars(signal: int) -> str:
+    if signal > 83:
+        return "signal_wifi_4_bar"
+    if signal >= 66:
+        return "network_wifi"
+    elif signal >= 49:
+        return "network_wifi_3_bar"
+    elif signal >= 32:
+        return "network_wifi_2_bar"
+    elif signal >= 15:
+        return "network_wifi_1_bar"
+    else:
+        return "signal_wifi_0_bar"
+    
 def yuck() -> str:
     available = get_available()
-    ret = r"""(box :orientation "v" :spacing 2"""
+    ret = r"""(box :orientation "v" :spacing 8"""
 
     for connection in available:
-        icon = ""
-        if connection["type"] == "802-11-wireless":
-            icon = "w" # legg inn ikon etter signal strength
-        elif connection["type"] == "802-3-ethernet":
-            icon = "e"
-        elif connection["type"] == "vpn":
-            icon = "v"
-        else:
-            icon = "?"
-        
+        signal_icon = signal_to_bars(connection["signal"])
         safe_name = connection["name"].replace('"', r'\"')
-
-        if connection["active"] == True:
+        
+        if connection["active"]:
             ret += rf"""
             (button
-                :class "active-wifi"
-                :onclick "~/.config/eww/widgets/network/scripts/disconnect_wifi.sh"
+                :class "network-item active"
+                :onclick "~/.config/eww/widgets/network/scripts/disconnect_wifi.sh '{safe_name}'"
+                (box :orientation "h" :space-evenly false :spacing 16
+                    (label :class "network-icon" :text "{signal_icon}")
+                    (box :orientation "v" :space-evenly false :spacing 2
+                        (label :class "network-name" :text "{safe_name}" :xalign 0)
+                        (label :class "network-subtext" :text "Connected" :xalign 0)
+                    )
+                    (box :hexpand true)
+                )
+            )
             """
         else:
             ret += rf"""
             (button
-                :class "inactive-wifi"
-                :onclick "~/.config/eww/widgets/network/scripts/connect_wifi.sh"
-            """
-        ret += rf"""
-                (box :orientation "h" :height 32 :spacing 2
-                    (label :text "{icon}")
-                    (label :text "{safe_name}")
+                :class "network-item"
+                :onclick "~/.config/eww/widgets/network/scripts/connect_wifi.sh '{safe_name}'"
+                (box :orientation "h" :space-evenly false :spacing 16
+                    (label :class "network-icon" :text "{signal_icon}")
+                    (box :orientation "v" :space-evenly true :spacing 2
+                        (label :class "network-name" :text "{safe_name}" :xalign 0)
+                    )
+                    (box :hexpand true)
                 )
             )
-        """
+            """
+    
     return ret + ")"
 
 if __name__ == "__main__":
-    print(yuck())
-
+    print(yuck())

+ 103 - 0
home/features/desktop/sway/ui/eww/network/scripts/connected.py

@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+
+import subprocess
+
+IGNORED_DEVICES = {
+    "lo",
+    "docker0",
+}
+
+IGNORED_PREFIXES = (
+    "br-",
+    "veth",
+    "virbr",
+    "tun",
+    "tap",
+)
+
+IGNORED_TYPES = {
+    "loopback",
+    "bridge",
+}
+
+def devices() -> list:
+    result = subprocess.run(
+        [
+            "nmcli",
+            "-t",
+            "-f",
+            "DEVICE,TYPE,STATE,CONNECTION",
+            "device",
+            "status",
+        ],
+        text=True,
+        capture_output=True,
+        check=True,
+    )
+
+    devices = []
+
+    for line in result.stdout.strip().splitlines():
+        device, dev_type, state, connection = line.split(":", 3)
+
+        # filter ignored device names
+        if device in IGNORED_DEVICES:
+            continue
+
+        # filter virtual interface prefixes
+        if any(device.startswith(prefix) for prefix in IGNORED_PREFIXES):
+            continue
+
+        # filter unwanted interface types
+        if dev_type in IGNORED_TYPES:
+            continue
+
+        devices.append({
+            "device": device,
+            "type": dev_type,
+            "state": state,
+            "connection": None if connection == "--" else connection,
+        })
+    return devices
+
+def yuck() -> str:
+    ret = r"""(box :orientation "v" :spacing 8"""
+
+    for device in devices():
+        safe_name = device["device"].replace('"', r'\"')
+        signal_icon = "settings_input_antenna" if device["type"] == "wifi" else "lan"
+
+        if device["state"] == "connected":
+            ret += rf"""
+            (box :orientation "h" :space-evenly false :spacing 16 :class "device-item"
+                (label :class "device-icon" :text "{signal_icon}")
+                (box :orientation "v" :space-evenly false :spacing 2
+                    (label :class "device-name" :text "{safe_name}" :xalign 0)
+                    (label :class "device-subtext" :text "Active" :xalign 0)
+                )
+                (box :hexpand true)
+                (checkbox
+                    :checked true
+                    :onchecked "~/.config/eww/widgets/network/scripts/device_up.sh '{safe_name}'"
+                    :onunchecked "~/.config/eww/widgets/network/scripts/device_down.sh '{safe_name}'"
+                )
+            )
+            """
+        else:
+            ret += rf"""
+            (box :orientation "h" :space-evenly false :spacing 16 :class "device-item"
+                (label :class "device-icon" :text "{signal_icon}")
+                (box :orientation "v" :space-evenly true :spacing 2
+                    (label :class "device-name" :text "{safe_name}" :xalign 0)
+                )
+                (box :hexpand true)
+                (checkbox
+                    :checked false
+                    :onchecked "~/.config/eww/widgets/network/scripts/device_up.sh '{safe_name}'"
+                    :onunchecked "~/.config/eww/widgets/network/scripts/device_down.sh '{safe_name}'"
+                )
+            )
+            """
+    return ret + ")"
+
+print(yuck())

+ 2 - 2
home/features/desktop/sway/ui/waybar/default.nix

@@ -77,12 +77,12 @@
         network = {
           format-wifi = "{icon}";
           format-icons = [
-            "network_wifi_0_bar"
+            "signal_wifi_0_bar"
             "network_wifi_1_bar"
             "network_wifi_2_bar"
             "network_wifi_3_bar"
             "network_wifi"
-            "network_wifi_4_bar"
+            "signal_wifi_4_bar"
           ];
           format-ethernet = "lan";
           format-disconnected = "signal_wifi_off";