✨ feat(control-center/network): add provisory support for wireless connections
I call it "provisory" because I don't have a Wi-Fi card to test it, but in theory, everything should work
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import { exec, execAsync, Gio, GLib } from "astal";
|
||||
|
||||
export function getDecoded(text: (Uint8Array)): string {
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
return decoder.decode(text);
|
||||
}
|
||||
export const decoder = new TextDecoder("utf-8"),
|
||||
encoder = new TextEncoder();
|
||||
|
||||
export function getHyprlandInstanceSig(): (string|null) {
|
||||
return GLib.getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
|
||||
+20
-20
@@ -1,26 +1,26 @@
|
||||
// SCSS Variables
|
||||
// Generated by 'wal'
|
||||
$wallpaper: "/home/joaov/wallpapers/Frieren Blue.jpeg";
|
||||
$wallpaper: "/home/joaov/wallpapers/Frieren Rain.jpg";
|
||||
|
||||
// Special
|
||||
$background: #22303d;
|
||||
$foreground: #c7cbce;
|
||||
$cursor: #c7cbce;
|
||||
$background: #25301c;
|
||||
$foreground: #c8cbc6;
|
||||
$cursor: #c8cbc6;
|
||||
|
||||
// Colors
|
||||
$color0: #22303d;
|
||||
$color1: #9f847e;
|
||||
$color2: #aa9381;
|
||||
$color3: #7b8c92;
|
||||
$color4: #78999c;
|
||||
$color5: #76a3a9;
|
||||
$color6: #78a4aa;
|
||||
$color7: #9ca1a5;
|
||||
$color8: #6b7883;
|
||||
$color9: #D5B1A9;
|
||||
$color10: #E3C5AD;
|
||||
$color11: #A5BBC3;
|
||||
$color12: #A1CDD0;
|
||||
$color13: #9EDAE2;
|
||||
$color14: #A1DBE3;
|
||||
$color15: #c7cbce;
|
||||
$color0: #25301c;
|
||||
$color1: #6c8251;
|
||||
$color2: #7c9357;
|
||||
$color3: #78846e;
|
||||
$color4: #948a88;
|
||||
$color5: #899869;
|
||||
$color6: #98a27b;
|
||||
$color7: #9ba197;
|
||||
$color8: #707c66;
|
||||
$color9: #91AE6D;
|
||||
$color10: #A6C574;
|
||||
$color11: #A0B093;
|
||||
$color12: #C6B9B6;
|
||||
$color13: #B7CB8D;
|
||||
$color14: #CBD9A4;
|
||||
$color15: #c8cbc6;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import { Page, PageButton } from "./Page";
|
||||
import AstalNetwork from "gi://AstalNetwork";
|
||||
import { bind } from "astal";
|
||||
import { bind, GLib } from "astal";
|
||||
import NM from "gi://NM";
|
||||
import { Windows } from "../../../windows";
|
||||
import { tr } from "../../../i18n/intl";
|
||||
import { execApp } from "../../../scripts/apps";
|
||||
import { EntryPopup, EntryPopupProps } from "../../EntryPopup";
|
||||
import { Notifications } from "../../../scripts/notifications";
|
||||
import { AskPopup, AskPopupProps } from "../../AskPopup";
|
||||
import { encoder } from "../../../scripts/utils";
|
||||
|
||||
export const PageNetwork: (() => Page) = () => new Page({
|
||||
id: "network",
|
||||
@@ -77,30 +81,126 @@ export const PageNetwork: (() => Page) = () => new Page({
|
||||
visible: bind(AstalNetwork.get_default(), "primary").as((primary) => primary === AstalNetwork.Primary.WIFI),
|
||||
hexpand: true,
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
children: AstalNetwork.get_default().wifi ? bind(AstalNetwork.get_default().wifi.get_device(), "accessPoints").as((aps) =>
|
||||
aps.map(ap => new Widget.Button({
|
||||
hexpand: true,
|
||||
onClick: () => console.log("connect to " + ap.get_ssid().toArray().toString()), // TODO I don't have a WiFi board :(
|
||||
child: new Widget.Box({
|
||||
hexpand: true,
|
||||
children: [
|
||||
new Widget.Icon({
|
||||
halign: Gtk.Align.START,
|
||||
className: "icon",
|
||||
icon: "network-wireless-signal-excellent-symbolic"
|
||||
} as Widget.IconProps),
|
||||
new Widget.Label({
|
||||
className: "ssid",
|
||||
halign: Gtk.Align.START,
|
||||
label: (getDecoded(ap.ssid.get_data()) ?? ap.ssid.get_data().toString()) ?? "Wi-Fi"
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Label({
|
||||
className: "status",
|
||||
} as Widget.LabelProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
} as Widget.ButtonProps))) : [],
|
||||
children: AstalNetwork.get_default().wifi ? bind(AstalNetwork.get_default().wifi, "accessPoints").as((aps) => [
|
||||
new Widget.Label({
|
||||
className: "sub-header",
|
||||
label: "Wi-Fi"
|
||||
} as Widget.LabelProps),
|
||||
...aps.filter(ap => ap.ssid).map(ap => PageButton({
|
||||
className: bind(AstalNetwork.get_default().wifi, "activeAccessPoint").as(activeAP =>
|
||||
activeAP.ssid === ap.ssid ? "active" : ""),
|
||||
title: bind(ap, "ssid").as(ssid =>
|
||||
ssid ?? "Unknown SSID"),
|
||||
icon: bind(ap, "iconName"),
|
||||
endWidget: new Widget.Icon({
|
||||
icon: bind(ap, "flags").as(flags => flags & NM.__80211ApFlags.PRIVACY ?
|
||||
"channel-secure-symbolic"
|
||||
: "channel-insecure-symbolic"),
|
||||
css: "font-size: 18px;"
|
||||
} as Widget.IconProps),
|
||||
extraButtons: [
|
||||
new Widget.Button({
|
||||
image: new Widget.Icon({
|
||||
icon: "window-close-symbolic",
|
||||
css: "font-size: 18px;"
|
||||
} as Widget.IconProps)
|
||||
} as Widget.ButtonProps)
|
||||
],
|
||||
onClick: () => {
|
||||
const ssid: string = ap.ssid ?? "Unknown SSID",
|
||||
ssidBytes = GLib.Bytes.new(encoder.encode(ssid));
|
||||
|
||||
const connection = new NM.Connection();
|
||||
const setting = NM.SettingWireless.new();
|
||||
setting.ssid = ssidBytes;
|
||||
setting.bssid = ap.bssid;
|
||||
|
||||
connection.add_setting(setting);
|
||||
|
||||
// Check if access point has encryption(needs a password)
|
||||
if(ap.flags & NM.__80211ApFlags.PRIVACY) {
|
||||
const passwdPopup = EntryPopup({
|
||||
isPassword: true,
|
||||
title: `${tr("connect")}: ${ssid}`,
|
||||
acceptText: tr("connect"),
|
||||
closeOnAccept: false,
|
||||
text: `Input password for ${ssid}`,
|
||||
onAccept: (input) => {
|
||||
const pskSetting = NM.SettingWirelessSecurity.new();
|
||||
pskSetting.keyMgmt = "wpa-psk";
|
||||
if(ap.flags & NM.__80211ApSecurityFlags.KEY_MGMT_SAE)
|
||||
pskSetting.keyMgmt = "sae";
|
||||
|
||||
pskSetting.psk = input;
|
||||
|
||||
AstalNetwork.get_default().get_client().add_connection_async(
|
||||
connection, true, null, (client, asyncRes) => {
|
||||
const remoteConnection = client!.add_connection_finish(asyncRes);
|
||||
if(!remoteConnection) {
|
||||
notifyConnectionError(ssid);
|
||||
return;
|
||||
}
|
||||
|
||||
passwdPopup.close();
|
||||
saveToDisk(remoteConnection, ssid);
|
||||
}
|
||||
);
|
||||
},
|
||||
} as EntryPopupProps);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AstalNetwork.get_default().get_client().add_connection_async(connection, false, null, (_, asyncRes) => {
|
||||
const remoteConnection = AstalNetwork.get_default().get_client().add_connection_finish(asyncRes);
|
||||
|
||||
if(!remoteConnection) {
|
||||
notifyConnectionError(ssid);
|
||||
return;
|
||||
}
|
||||
|
||||
activateWirelessConnection(remoteConnection, ssid);
|
||||
});
|
||||
}
|
||||
}))
|
||||
]
|
||||
) : [],
|
||||
} as Widget.BoxProps)
|
||||
]
|
||||
});
|
||||
|
||||
function activateWirelessConnection(connection: NM.RemoteConnection, ssid: string): void {
|
||||
AstalNetwork.get_default().get_client().activate_connection_async(
|
||||
connection, AstalNetwork.get_default().wifi.get_device(), null, null, (_, asyncRes) => {
|
||||
const activeConnection = AstalNetwork.get_default().get_client().activate_connection_finish(asyncRes);
|
||||
if(!activeConnection) {
|
||||
Notifications.getDefault().sendNotification({
|
||||
appName: "network",
|
||||
summary: "Couldn't activate wireless connection",
|
||||
body: `An error occurred while activating the wireless connection "${ssid}"`
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function notifyConnectionError(ssid: string): void {
|
||||
Notifications.getDefault().sendNotification({
|
||||
appName: "network",
|
||||
summary: "Coudn't connect Wi-Fi",
|
||||
body: `An error occurred while trying to connect to the "${ssid}" access point. \nMaybe the password is invalid?`
|
||||
});
|
||||
}
|
||||
function saveToDisk(remoteConnection: NM.RemoteConnection, ssid: string): void {
|
||||
AskPopup({
|
||||
text: `Save password for connection "${ssid}"?`,
|
||||
acceptText: "Yes",
|
||||
onAccept: () => remoteConnection.commit_changes_async(true, null, (_, asyncRes) =>
|
||||
!remoteConnection.commit_changes_finish(asyncRes) && Notifications.getDefault().sendNotification({
|
||||
appName: "network",
|
||||
summary: "Couldn't save Wi-Fi password",
|
||||
body: `An error occurred while trying to write the password for "${ssid}" to disk`
|
||||
}))
|
||||
} as AskPopupProps);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user