Fix network list flickering on refresh

This commit is contained in:
Jas Singh
2024-06-29 18:43:59 -07:00
parent da5d297b60
commit 47b3f1c74e
9 changed files with 29 additions and 495 deletions

View File

@@ -29,7 +29,7 @@ const Ethernet = () => {
hpack: "start",
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
class_name: `network-icon ethernet ${network.wired.state === "activated" ? "active" : ""}`,
tooltip_text: wired.internet,
icon: `${wired["icon_name"]}`,
}),

View File

@@ -1,483 +0,0 @@
const network = await Service.import("network");
import DropdownMenu from "../DropdownMenu.js";
export default () => {
const pendingAuth = Variable("");
return DropdownMenu({
name: "networkmenu",
transition: "crossfade",
child: Widget.Box({
class_name: "menu-items",
child: Widget.Box({
vertical: true,
hexpand: true,
class_name: "menu-items-container network",
children: [
Widget.Box({
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Connected Network",
}),
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
children: Utils.merge(
[
network.bind("wired"),
network.bind("wifi"),
network.bind("primary"),
pendingAuth.bind("value"),
],
(wired, wifi, primary) => {
let sortedNetworks = [];
if (wifi.access_points.length > 0) {
sortedNetworks = wifi.access_points
.filter((ap) => ap.ssid !== "Unknown")
.sort((a, b) => {
return b.strength - a.strength;
});
}
const localIfConnected = () => {
if (primary === "wired") {
return [
Widget.Box({
class_name: `network-element-item-ethernet ${sortedNetworks.length > 0 ? "multi" : ""}`,
child: Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name: "network-element-items-container",
children: [
Widget.Button({
class_name: "menu-button-icon network",
child: Widget.Icon({
tooltip_text: wired.internet,
icon: `${wired["icon_name"]}`,
}),
}),
Widget.Label({
class_name: "menu-button-name network",
truncate: "end",
wrap: true,
label: `Ethernet (${wired.speed / 1000} Gbps)`,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
wired.internet.charAt(0).toUpperCase() +
wired.internet.slice(1),
}),
],
}),
],
}),
}),
];
}
return [];
};
const wifiIfConnected = () => {
const getIdBySsid = (ssid, nmcliOutput) => {
const lines = nmcliOutput.trim().split("\n");
for (const line of lines) {
const columns = line.trim().split(/\s{2,}/);
if (columns[0].includes(ssid)) {
return columns[1];
}
}
return null;
};
if (wifi.ssid !== "") {
return [
Widget.Box({
class_name: `network-element-item-ethernet`,
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name: "menu-button-icon network",
child: Widget.Icon({
tooltip_text: wifi.state,
icon: `${wifi["icon_name"]}`,
}),
}),
Widget.Label({
class_name: "menu-button-name network",
truncate: "end",
wrap: true,
label: wifi.ssid,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
wifi.internet.charAt(0).toUpperCase() +
wifi.internet.slice(1),
}),
],
}),
],
}),
Widget.Box({
hexpand: true,
hpack: "end",
children: [
Widget.Button({
class_name:
"menu-icon-button network disconnect",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection down ${connectionId} "${wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while disconnecting from wifi "${wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label(""),
}),
Widget.Box({
hexpand: true,
child: Widget.Button({
class_name: "menu-icon-button network forget",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection delete ${connectionId} "${wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while forgetting "${wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label("󰆴"),
}),
}),
],
}),
],
}),
];
}
return [];
};
return [...localIfConnected(), ...wifiIfConnected()];
},
),
}),
Widget.Box({
children: [
Widget.Box({
hpack: "start",
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Available Networks",
}),
}),
Widget.Box({
hexpand: true,
hpack: "end",
child: Widget.Button({
class_name: "menu-icon-button refresh network",
on_primary_click: () => {
network.wifi.scan();
},
child: Widget.Icon("view-refresh-symbolic"),
}),
}),
],
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
children: [
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(pendingAuth, () => {
const accPoint = network.wifi.access_points.find(
(ap) => ap.bssid === pendingAuth.value,
);
if (
pendingAuth.value !== "" &&
accPoint !== undefined &&
network.wifi.ssid !== pendingAuth.value
) {
return (self.child = Widget.Box({
vertical: true,
children: [
Widget.Button({
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) => (v === accPoint.bssid ? true : false)),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Box({
child: Widget.Entry({
hpack: "start",
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
Utils.execAsync(
`nmcli dev wifi connect ${accPoint.bssid} password ${selfInp.text}`,
)
.catch((err) => {
pendingAuth.value = "";
console.error(
`Failed to connect to wifi: ${accPoint.ssid}... ${err}`,
);
})
.then(() => (pendingAuth.value = ""));
selfInp.text = "";
},
}),
}),
Widget.Box({
class_name:
"network-password-input-close-container",
hexpand: true,
child: Widget.Button({
class_name: "network-password-input-close",
on_primary_click: () =>
(pendingAuth.value = ""),
child: Widget.Label("󰅜 "),
}),
}),
],
}),
}),
],
}));
} else {
self.children = [];
}
});
},
}),
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(network, () => {
let sortedNetworks = [];
self.hook(pendingAuth, () => {
if (network.wifi.access_points.length > 0) {
sortedNetworks = network.wifi.access_points
.filter((ap) => {
return (
ap.ssid !== "Unknown" &&
ap.bssid !== pendingAuth.value &&
!ap.active &&
network.wifi.ssid !== ap.ssid
);
})
.sort((a, b) => {
return b.strength - a.strength;
});
}
if (sortedNetworks.length <= 0) {
return (self.children = [
Widget.Label({
class_name: "not-found-label dim",
expand: true,
hpack: "center",
vpack: "center",
label: "No Wifi Networks Found",
}),
]);
}
return (self.children = sortedNetworks.map((accPoint) => {
return Widget.Box({
vertical: true,
children: [
Widget.Button({
on_primary_click: () => {
Utils.execAsync(
`nmcli device wifi connect ${accPoint.bssid}`,
).catch((err) => {
if (
err
.toLowerCase()
.includes(
"secrets were required, but not provided",
)
) {
pendingAuth.value = accPoint.bssid;
}
});
},
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) =>
v === accPoint.bssid ? true : false,
),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Entry({
hexpand: true,
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
selfInp.text = "";
},
}),
],
}),
}),
],
});
}));
});
});
},
}),
],
}),
],
}),
}),
});
};

View File

@@ -1,7 +1,7 @@
const network = await Service.import("network");
import DropdownMenu from "../DropdownMenu.js";
import { Ethernet } from "./Ethernet.js";
import { Wifi } from "./Wifi/index.js";
import { Ethernet } from "./ethernet/index.js";
import { Wifi } from "./wifi/index.js";
export default () => {
return DropdownMenu({

View File

@@ -1,5 +1,6 @@
const renderWapStaging = (self, network, staging, connecting) => {
Utils.merge([network.bind("wifi"), staging.bind("value")], () => {
console.log(JSON.stringify(network, null, 2));
if (!Object.keys(staging.value).length) {
return (self.child = Widget.Box());
}
@@ -13,7 +14,7 @@ const renderWapStaging = (self, network, staging, connecting) => {
hexpand: true,
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
class_name: `network-icon wifi `,
icon: `${staging.value.iconName}`,
}),
Widget.Box({

View File

@@ -72,7 +72,7 @@ const renderWAPs = (self, network, staging, connecting) => {
on_primary_click: () => {
connecting.value = ap.bssid;
Utils.execAsync(`nmcli device wifi connect ${ap.bssid}`)
.then((res) => {
.then(() => {
connecting.value = "";
staging.value = {};
})
@@ -96,7 +96,7 @@ const renderWAPs = (self, network, staging, connecting) => {
hexpand: true,
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
class_name: `network-icon wifi ${ap.ssid === network.wifi.ssid ? "active" : ""}`,
icon: `${ap["iconName"]}`,
}),
Widget.Box({

View File

@@ -1,6 +1,7 @@
@import "../colors";
.menu-items-container.network {
font-size: 1.3em;
.menu-items-section {
padding-bottom: 1.5em;
}
@@ -8,10 +9,17 @@
color: $mauve;
}
.network-ethernet-icon {
.network-icon {
font-size: 1.3em;
min-width: 1em;
min-height: 1em;
color: $overlay1;
&.active {
color: $mauve;
}
}
.connection-container {
margin-left: 1em;
@@ -21,7 +29,7 @@
}
.menu-section-container.wifi {
.menu-items-section {
min-height: 5em;
min-height: 3em;
}
}

View File

@@ -826,14 +826,22 @@ window#powermenu .powermenu.box {
color: #eba0ac;
}
.menu-items-container.network {
font-size: 1.3em;
}
.menu-items-container.network .menu-items-section {
padding-bottom: 1.5em;
}
.menu-items-container.network .menu-label {
color: #cba6f7;
}
.menu-items-container.network .network-ethernet-icon {
.menu-items-container.network .network-icon {
font-size: 1.3em;
min-width: 1em;
min-height: 1em;
color: #7f849c;
}
.menu-items-container.network .network-icon.active {
color: #cba6f7;
}
.menu-items-container.network .connection-container {
@@ -843,7 +851,7 @@ window#powermenu .powermenu.box {
font-size: 0.9em;
}
.menu-items-container.network .menu-section-container.wifi .menu-items-section {
min-height: 5em;
min-height: 3em;
}
.menu-items-container.network .network-element-item:not(:last-child) {
margin-bottom: 0.5em;

File diff suppressed because one or more lines are too long