mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 17:47:09 +00:00
309 lines
10 KiB
QML
Executable File
309 lines
10 KiB
QML
Executable File
pragma Singleton
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property list<Connection> connections: []
|
|
readonly property list<string> savedNetworks: []
|
|
readonly property Connection active: connections.find(c => c.active) ?? null
|
|
|
|
property bool wifiEnabled: true
|
|
readonly property bool scanning: rescanProc.running
|
|
|
|
property string lastNetworkAttempt: ""
|
|
property string lastErrorMessage: ""
|
|
property string message: ""
|
|
|
|
readonly property string icon: {
|
|
if (!active) return "signal_wifi_off";
|
|
if (active.type === "ethernet") return "settings_ethernet";
|
|
|
|
if (active.strength >= 75) return "network_wifi";
|
|
else if (active.strength >= 50) return "network_wifi_3_bar";
|
|
else if (active.strength >= 25) return "network_wifi_2_bar";
|
|
else return "network_wifi_1_bar";
|
|
}
|
|
|
|
readonly property string wifiLabel: {
|
|
const activeWifi = connections.find(c => c.active && c.type === "wifi");
|
|
if (activeWifi) return activeWifi.name;
|
|
return "Wi-Fi";
|
|
}
|
|
|
|
readonly property string wifiStatus: {
|
|
const activeWifi = connections.find(c => c.active && c.type === "wifi");
|
|
if (activeWifi) return "Connected";
|
|
if (wifiEnabled) return "On";
|
|
return "Off";
|
|
}
|
|
|
|
readonly property string label: {
|
|
if (active) return active.name;
|
|
if (wifiEnabled) return "Wi-Fi";
|
|
return "Wi-Fi";
|
|
}
|
|
|
|
readonly property string status: {
|
|
if (active) return "Connected";
|
|
if (wifiEnabled) return "On";
|
|
return "Off";
|
|
}
|
|
|
|
function enableWifi(enabled: bool): void {
|
|
enableWifiProc.exec(["nmcli", "radio", "wifi", enabled ? "on" : "off"]);
|
|
}
|
|
|
|
function toggleWifi(): void {
|
|
enableWifi(!wifiEnabled);
|
|
}
|
|
|
|
function rescan(): void {
|
|
rescanProc.running = true;
|
|
}
|
|
|
|
function connect(connection: Connection, password: string): void {
|
|
if (connection.type === "wifi") {
|
|
root.lastNetworkAttempt = connection.name;
|
|
root.lastErrorMessage = "";
|
|
root.message = "";
|
|
|
|
if (password && password.length > 0) {
|
|
connectProc.exec(["nmcli", "dev", "wifi", "connect", connection.name, "password", password]);
|
|
} else {
|
|
connectProc.exec(["nmcli", "dev", "wifi", "connect", connection.name]);
|
|
}
|
|
} else if (connection.type === "ethernet") {
|
|
ethConnectProc.exec(["nmcli", "connection", "up", connection.uuid]);
|
|
}
|
|
}
|
|
|
|
function disconnect(): void {
|
|
if (!active) return;
|
|
|
|
if (active.type === "wifi") {
|
|
disconnectProc.exec(["nmcli", "connection", "down", active.name]);
|
|
} else if (active.type === "ethernet") {
|
|
ethDisconnectProc.exec(["nmcli", "connection", "down", active.uuid]);
|
|
}
|
|
}
|
|
|
|
Process {
|
|
running: true
|
|
command: ["nmcli", "m"]
|
|
stdout: SplitParser {
|
|
onRead: {
|
|
getWifiStatus();
|
|
updateConnections();
|
|
}
|
|
}
|
|
}
|
|
|
|
function getWifiStatus(): void {
|
|
wifiStatusProc.running = true;
|
|
}
|
|
|
|
function updateConnections(): void {
|
|
getWifiNetworks.running = true;
|
|
getEthConnections.running = true;
|
|
getSavedNetworks.running = true;
|
|
}
|
|
|
|
Process {
|
|
id: wifiStatusProc
|
|
running: true
|
|
command: ["nmcli", "radio", "wifi"]
|
|
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
root.wifiEnabled = text.trim() === "enabled";
|
|
if (!root.wifiEnabled) {
|
|
root.lastErrorMessage = "";
|
|
root.message = "";
|
|
root.lastNetworkAttempt = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: enableWifiProc
|
|
onExited: updateConnections()
|
|
}
|
|
|
|
Process {
|
|
id: rescanProc
|
|
command: ["nmcli", "dev", "wifi", "list", "--rescan", "yes"]
|
|
onExited: updateConnections()
|
|
}
|
|
|
|
Process {
|
|
id: connectProc
|
|
stdout: StdioCollector { }
|
|
stderr: StdioCollector {
|
|
onStreamFinished: {
|
|
if (text.includes("Error") || text.includes("incorrect")) {
|
|
root.lastErrorMessage = "Incorrect password";
|
|
}
|
|
}
|
|
}
|
|
onExited: {
|
|
if (exitCode === 0) {
|
|
root.message = "ok";
|
|
root.lastErrorMessage = "";
|
|
} else {
|
|
root.message = root.lastErrorMessage !== "" ? root.lastErrorMessage : "Connection failed";
|
|
}
|
|
updateConnections();
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: disconnectProc
|
|
onExited: updateConnections()
|
|
}
|
|
|
|
Process {
|
|
id: ethConnectProc
|
|
onExited: updateConnections()
|
|
}
|
|
|
|
Process {
|
|
id: ethDisconnectProc
|
|
onExited: updateConnections()
|
|
}
|
|
|
|
Process {
|
|
id: getSavedNetworks
|
|
running: true
|
|
command: ["nmcli", "-g", "NAME,TYPE", "connection", "show"]
|
|
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const lines = text.trim().split("\n");
|
|
const wifiConnections = lines
|
|
.map(line => line.split(":"))
|
|
.filter(parts => parts[1] === "802-11-wireless")
|
|
.map(parts => parts[0]);
|
|
root.savedNetworks = wifiConnections;
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: getWifiNetworks
|
|
running: true
|
|
command: ["nmcli", "-g", "ACTIVE,SIGNAL,FREQ,SSID,BSSID,SECURITY", "d", "w"]
|
|
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const PLACEHOLDER = "STRINGWHICHHOPEFULLYWONTBEUSED";
|
|
const rep = new RegExp("\\\\:", "g");
|
|
const rep2 = new RegExp(PLACEHOLDER, "g");
|
|
|
|
const allNetworks = text.trim().split("\n").map(n => {
|
|
const net = n.replace(rep, PLACEHOLDER).split(":");
|
|
return {
|
|
type: "wifi",
|
|
active: net[0] === "yes",
|
|
strength: parseInt(net[1]),
|
|
frequency: parseInt(net[2]),
|
|
name: net[3]?.replace(rep2, ":") ?? "",
|
|
bssid: net[4]?.replace(rep2, ":") ?? "",
|
|
security: net[5] ?? "",
|
|
saved: root.savedNetworks.includes(net[3] ?? ""),
|
|
uuid: "",
|
|
device: ""
|
|
};
|
|
}).filter(n => n.name && n.name.length > 0);
|
|
|
|
const networkMap = new Map();
|
|
for (const network of allNetworks) {
|
|
const existing = networkMap.get(network.name);
|
|
if (!existing) {
|
|
networkMap.set(network.name, network);
|
|
} else {
|
|
if (network.active && !existing.active) {
|
|
networkMap.set(network.name, network);
|
|
} else if (!network.active && !existing.active && network.strength > existing.strength) {
|
|
networkMap.set(network.name, network);
|
|
}
|
|
}
|
|
}
|
|
|
|
mergeConnections(Array.from(networkMap.values()), "wifi");
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: getEthConnections
|
|
running: true
|
|
command: ["nmcli", "-g", "NAME,UUID,TYPE,DEVICE,STATE", "connection", "show"]
|
|
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const lines = text.trim().split("\n");
|
|
const ethConns = lines
|
|
.map(line => line.split(":"))
|
|
.filter(parts => parts[2] === "802-3-ethernet" || parts[2] === "gsm" || parts[2] === "bluetooth")
|
|
.map(parts => ({
|
|
type: "ethernet",
|
|
name: parts[0],
|
|
uuid: parts[1],
|
|
device: parts[3],
|
|
active: parts[4] === "activated",
|
|
strength: 100,
|
|
frequency: 0,
|
|
bssid: "",
|
|
security: "",
|
|
saved: true
|
|
}));
|
|
|
|
mergeConnections(ethConns, "ethernet");
|
|
}
|
|
}
|
|
}
|
|
|
|
function mergeConnections(newConns: var, connType: string): void {
|
|
const rConns = root.connections;
|
|
const destroyed = rConns.filter(rc => rc.type === connType && !newConns.find(nc =>
|
|
connType === "wifi" ? (nc.frequency === rc.frequency && nc.name === rc.name && nc.bssid === rc.bssid)
|
|
: nc.uuid === rc.uuid
|
|
));
|
|
|
|
for (const conn of destroyed)
|
|
rConns.splice(rConns.indexOf(conn), 1).forEach(c => c.destroy());
|
|
|
|
for (const conn of newConns) {
|
|
const match = rConns.find(c =>
|
|
connType === "wifi" ? (c.frequency === conn.frequency && c.name === conn.name && c.bssid === conn.bssid)
|
|
: c.uuid === conn.uuid
|
|
);
|
|
if (match) {
|
|
match.lastIpcObject = conn;
|
|
} else {
|
|
rConns.push(connComp.createObject(root, { lastIpcObject: conn }));
|
|
}
|
|
}
|
|
}
|
|
|
|
component Connection: QtObject {
|
|
required property var lastIpcObject
|
|
readonly property string type: lastIpcObject.type
|
|
readonly property string name: lastIpcObject.name
|
|
readonly property string uuid: lastIpcObject.uuid
|
|
readonly property string device: lastIpcObject.device
|
|
readonly property bool active: lastIpcObject.active
|
|
readonly property int strength: lastIpcObject.strength
|
|
readonly property int frequency: lastIpcObject.frequency
|
|
readonly property string bssid: lastIpcObject.bssid
|
|
readonly property string security: lastIpcObject.security
|
|
readonly property bool isSecure: security.length > 0
|
|
readonly property bool saved: lastIpcObject.saved
|
|
}
|
|
|
|
Component { id: connComp; Connection { } }
|
|
} |