195 lines
7.4 KiB
Python
195 lines
7.4 KiB
Python
import gi
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
gi.require_version('NM', '1.0')
|
|
from fabric.utils import bulk_connect
|
|
from fabric.widgets.box import Box
|
|
from fabric.widgets.button import Button
|
|
from fabric.widgets.centerbox import CenterBox
|
|
from fabric.widgets.image import Image
|
|
from fabric.widgets.label import Label
|
|
from fabric.widgets.scrolledwindow import ScrolledWindow
|
|
from gi.repository import NM, GLib, Gtk
|
|
|
|
import modules.icons as icons
|
|
from services.network import NetworkClient
|
|
|
|
|
|
class WifiAccessPointSlot(CenterBox):
|
|
def __init__(self, ap_data: dict, network_service: NetworkClient, wifi_service, **kwargs):
|
|
super().__init__(name="wifi-ap-slot", **kwargs)
|
|
self.ap_data = ap_data
|
|
self.network_service = network_service
|
|
self.wifi_service = wifi_service
|
|
|
|
ssid = ap_data.get("ssid", "Unknown SSID")
|
|
icon_name = ap_data.get("icon-name", "network-wireless-signal-none-symbolic")
|
|
|
|
self.is_active = False
|
|
active_ap_details = ap_data.get("active-ap")
|
|
if active_ap_details and hasattr(active_ap_details, 'get_bssid') and active_ap_details.get_bssid() == ap_data.get("bssid"):
|
|
self.is_active = True
|
|
|
|
self.ap_icon = Image(icon_name=icon_name, size=24)
|
|
self.ap_label = Label(label=ssid, h_expand=True, h_align="start", ellipsization="end")
|
|
|
|
self.connect_button = Button(
|
|
name="wifi-connect-button",
|
|
label="Connected" if self.is_active else "Connect",
|
|
sensitive=not self.is_active,
|
|
on_clicked=self._on_connect_clicked,
|
|
style_classes=["connected"] if self.is_active else None,
|
|
)
|
|
|
|
self.set_start_children([
|
|
Box(spacing=8, h_expand=True, h_align="fill", children=[
|
|
self.ap_icon,
|
|
self.ap_label,
|
|
])
|
|
])
|
|
self.set_end_children([self.connect_button])
|
|
|
|
def _on_connect_clicked(self, _):
|
|
if not self.is_active and self.ap_data.get("bssid"):
|
|
self.connect_button.set_label("Connecting...")
|
|
self.connect_button.set_sensitive(False)
|
|
self.network_service.connect_wifi_bssid(self.ap_data["bssid"])
|
|
|
|
|
|
class NetworkConnections(Box):
|
|
def __init__(self, **kwargs):
|
|
super().__init__(
|
|
name="network-connections",
|
|
orientation="vertical",
|
|
spacing=4,
|
|
**kwargs,
|
|
)
|
|
self.widgets = kwargs.get("widgets")
|
|
self.network_client = NetworkClient()
|
|
|
|
self.status_label = Label(label="Initializing Wi-Fi...", h_expand=True, h_align="center")
|
|
|
|
self.back_button = Button(
|
|
name="network-back",
|
|
child=Label(name="network-back-label", markup=icons.chevron_left),
|
|
on_clicked=lambda *_: self.widgets.show_notif()
|
|
)
|
|
|
|
|
|
self.wifi_toggle_button_icon = Label(markup=icons.wifi_3)
|
|
self.wifi_toggle_button = Button(
|
|
name="wifi-toggle-button",
|
|
child=self.wifi_toggle_button_icon,
|
|
tooltip_text="Toggle Wi-Fi",
|
|
on_clicked=self._toggle_wifi
|
|
)
|
|
|
|
|
|
self.refresh_button_icon = Label(name="network-refresh-label", markup=icons.reload)
|
|
self.refresh_button = Button(
|
|
name="network-refresh",
|
|
child=self.refresh_button_icon,
|
|
tooltip_text="Scan for Wi-Fi networks",
|
|
on_clicked=self._refresh_access_points
|
|
)
|
|
|
|
header_box = CenterBox(
|
|
name="network-header",
|
|
start_children=[self.back_button],
|
|
center_children=[Label(name="network-title", label="Wi-Fi Networks")],
|
|
end_children=[Box(orientation="horizontal", spacing=4, children=[self.refresh_button])]
|
|
)
|
|
|
|
self.ap_list_box = Box(orientation="vertical", spacing=4)
|
|
scrolled_window = ScrolledWindow(
|
|
name="network-ap-scrolled-window",
|
|
child=self.ap_list_box,
|
|
h_expand=True,
|
|
v_expand=True,
|
|
propagate_width=False,
|
|
propagate_height=False,
|
|
)
|
|
|
|
self.add(header_box)
|
|
self.add(self.status_label)
|
|
self.add(scrolled_window)
|
|
|
|
self.network_client.connect("device-ready", self._on_device_ready)
|
|
self.wifi_toggle_button.set_sensitive(False)
|
|
self.refresh_button.set_sensitive(False)
|
|
|
|
def _on_device_ready(self, _client):
|
|
|
|
if self.network_client.wifi_device:
|
|
self.network_client.wifi_device.connect("changed", self._load_access_points)
|
|
self.network_client.wifi_device.connect("notify::enabled", self._update_wifi_status_ui)
|
|
self._update_wifi_status_ui()
|
|
if self.network_client.wifi_device.enabled:
|
|
self._load_access_points()
|
|
else:
|
|
self.status_label.set_label("Wi-Fi disabled.")
|
|
self.status_label.set_visible(True)
|
|
else:
|
|
self.status_label.set_label("Wi-Fi device not available.")
|
|
self.status_label.set_visible(True)
|
|
self.wifi_toggle_button.set_sensitive(False)
|
|
self.refresh_button.set_sensitive(False)
|
|
|
|
def _update_wifi_status_ui(self, *args):
|
|
if self.network_client.wifi_device:
|
|
enabled = self.network_client.wifi_device.enabled
|
|
self.wifi_toggle_button.set_sensitive(True)
|
|
self.refresh_button.set_sensitive(enabled)
|
|
|
|
if enabled:
|
|
self.wifi_toggle_button_icon.set_markup(icons.wifi_3)
|
|
else:
|
|
self.wifi_toggle_button_icon.set_markup(icons.wifi_off)
|
|
self.status_label.set_label("Wi-Fi disabled.")
|
|
self.status_label.set_visible(True)
|
|
self._clear_ap_list()
|
|
|
|
if enabled and not self.ap_list_box.get_children():
|
|
GLib.idle_add(self._refresh_access_points)
|
|
else:
|
|
self.wifi_toggle_button.set_sensitive(False)
|
|
self.refresh_button.set_sensitive(False)
|
|
|
|
def _toggle_wifi(self, _):
|
|
if self.network_client.wifi_device:
|
|
self.network_client.wifi_device.toggle_wifi()
|
|
|
|
def _refresh_access_points(self, _=None):
|
|
if self.network_client.wifi_device and self.network_client.wifi_device.enabled:
|
|
self.status_label.set_label("Scanning for Wi-Fi networks...")
|
|
self.status_label.set_visible(True)
|
|
self._clear_ap_list()
|
|
self.network_client.wifi_device.scan()
|
|
return False
|
|
|
|
def _clear_ap_list(self):
|
|
for child in self.ap_list_box.get_children():
|
|
child.destroy()
|
|
|
|
def _load_access_points(self, *args):
|
|
if not self.network_client.wifi_device or not self.network_client.wifi_device.enabled:
|
|
self._clear_ap_list()
|
|
self.status_label.set_label("Wi-Fi disabled.")
|
|
self.status_label.set_visible(True)
|
|
return
|
|
|
|
self._clear_ap_list()
|
|
|
|
access_points = self.network_client.wifi_device.access_points
|
|
|
|
if not access_points:
|
|
self.status_label.set_label("No Wi-Fi networks found.")
|
|
self.status_label.set_visible(True)
|
|
else:
|
|
self.status_label.set_visible(False)
|
|
sorted_aps = sorted(access_points, key=lambda x: x.get("strength", 0), reverse=True)
|
|
for ap_data in sorted_aps:
|
|
slot = WifiAccessPointSlot(ap_data, self.network_client, self.network_client.wifi_device)
|
|
self.ap_list_box.add(slot)
|
|
self.ap_list_box.show_all()
|