🔧 chore(control-center/tiles): better implementation for the network tile

This commit is contained in:
retrozinndev
2025-10-17 20:02:01 -03:00
parent 6793a68bb8
commit 4861337067
5 changed files with 202 additions and 97 deletions
@@ -1,85 +1,153 @@
import { execAsync } from "ags/process";
import { Tile } from "./Tile";
import { execAsync } from "ags/process";
import { PageNetwork } from "../pages/Network";
import { tr } from "../../../../i18n/intl";
import { TilesPages } from "../tiles";
import { Gtk } from "ags/gtk4";
import { createBinding, createComputed, With } from "ags";
import { Accessor, createBinding, createComputed } from "ags";
import { secureBaseBinding } from "../../../../modules/utils";
import AstalNetwork from "gi://AstalNetwork";
import { Notifications } from "../../../../modules/notifications";
export const TileNetwork = () => <Gtk.Box>
<With value={createComputed([
createBinding(AstalNetwork.get_default(), "primary"),
createBinding(AstalNetwork.get_default(), "wired"),
createBinding(AstalNetwork.get_default(), "wifi")
])}>
const { WIFI, WIRED } = AstalNetwork.Primary,
{ CONNECTED, CONNECTING } = AstalNetwork.Internet;
{([primary, wired, wifi]: [AstalNetwork.Primary, AstalNetwork.Wired, AstalNetwork.Wifi]) => {
if(primary === AstalNetwork.Primary.WIFI) {
return <Tile title={tr("control_center.tiles.network.wireless")}
description={createComputed([
createBinding(wifi, "ssid"), createBinding(wifi, "internet")
], (ssid, internet) => ssid ? ssid : (() => {
switch(internet) {
case AstalNetwork.Internet.CONNECTED:
return tr("connected");
case AstalNetwork.Internet.DISCONNECTED:
return tr("disconnected");
case AstalNetwork.Internet.CONNECTING:
return tr("connecting") + "...";
}
})()
)} onEnabled={() => wifi.set_enabled(true)}
onDisabled={() => wifi.set_enabled(false)}
hasArrow onClicked={() => TilesPages?.toggle(PageNetwork)}
icon={"network-wireless-signal-excellent-symbolic"}
state={createBinding(wifi, "enabled")}
/>
const wiredInternet = secureBaseBinding<AstalNetwork.Wired>(
createBinding(AstalNetwork.get_default(), "wired"),
"internet",
AstalNetwork.Internet.DISCONNECTED
) as Accessor<AstalNetwork.Internet>;
} else if(primary === AstalNetwork.Primary.WIRED) {
return <Tile title={tr("control_center.tiles.network.wired")}
description={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) => {
switch(internet) {
case AstalNetwork.Internet.CONNECTED:
return tr("connected");
case AstalNetwork.Internet.DISCONNECTED:
return tr("disconnected");
case AstalNetwork.Internet.CONNECTING:
return tr("connecting") + "...";
}
})}
hasArrow onEnabled={() => execAsync("nmcli n on")}
onDisabled={() => execAsync("nmcli n off")}
onClicked={() => TilesPages?.toggle(PageNetwork)}
icon={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) => {
switch(internet) {
case AstalNetwork.Internet.CONNECTED:
return "network-wired-symbolic";
case AstalNetwork.Internet.DISCONNECTED:
return "network-wired-disconnected-symbolic";
}
const wifiInternet = secureBaseBinding<AstalNetwork.Wifi>(
createBinding(AstalNetwork.get_default(), "wifi"),
"internet",
AstalNetwork.Internet.DISCONNECTED
) as Accessor<AstalNetwork.Internet>;
return "network-wired-no-route-symbolic";
})}
state={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) =>
internet === AstalNetwork.Internet.CONNECTING
|| internet === AstalNetwork.Internet.CONNECTED
)}
/>
}
return <Tile
title={tr("control_center.tiles.network.network")}
description={tr("disconnected")}
onEnabled={() => execAsync("nmcli n on")}
onDisabled={() => execAsync("nmcli n off")}
hasArrow onClicked={() => TilesPages?.toggle(PageNetwork)}
icon={"network-wired-disconnected-symbolic"}
state={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) =>
internet === AstalNetwork.Internet.CONNECTING || internet === AstalNetwork.Internet.CONNECTED)}
/>
}}
</With>
</Gtk.Box>;
const wifiSSID = secureBaseBinding<AstalNetwork.Wifi>(
createBinding(AstalNetwork.get_default(), "wifi"),
"ssid",
"Unknown"
) as Accessor<string>;
const wifiIcon = secureBaseBinding<AstalNetwork.Wifi>(
createBinding(AstalNetwork.get_default(), "wifi"),
"iconName",
"network-wireless-symbolic"
);
const wiredIcon = secureBaseBinding<AstalNetwork.Wired>(
createBinding(AstalNetwork.get_default(), "wired"),
"iconName",
"network-wired-symbolic"
);
const primary = createBinding(AstalNetwork.get_default(), "primary");
export const TileNetwork = () =>
<Tile hasArrow title={createComputed([
primary,
wifiInternet,
wifiSSID
], (primary, wiInternet, wiSSID) => {
switch(primary) {
case WIFI:
if(wiInternet === CONNECTED)
return wiSSID;
return tr("control_center.tiles.network.wireless");
case WIRED:
return tr("control_center.tiles.network.wired");
}
return tr("control_center.tiles.network.network");
})}
onClicked={() => TilesPages?.toggle(PageNetwork)}
icon={createComputed([
primary,
wifiIcon,
wiredIcon
], (primary, wifiIcon, wiredIcon) => {
switch(primary) {
case WIFI:
return wifiIcon;
case WIRED:
return wiredIcon;
}
return "network-wired-no-route-symbolic";
})}
state={createComputed([
primary,
secureBaseBinding<AstalNetwork.Wifi>(
createBinding(AstalNetwork.get_default(), "wifi"),
"enabled",
false
),
wiredInternet.as(internet => internet === CONNECTED || internet === CONNECTING)
], (primary, wifiEnabled, wiredEnabled) => {
switch(primary) {
case WIFI:
return wifiEnabled;
case WIRED:
return wiredEnabled;
}
return false;
})}
description={createComputed([
primary,
wifiInternet,
wiredInternet
], (primary, wifiInternet, wiredInternet) => {
switch(primary) {
case WIFI:
return internetToTranslatedString(wifiInternet);
case WIRED:
return internetToTranslatedString(wiredInternet);
}
return tr("disconnected");
})}
onToggled={(self, state) => {
switch(AstalNetwork.get_default().primary) {
case WIFI:
AstalNetwork.get_default().wifi.set_enabled(state);
return;
case WIRED:
(state ?
execAsync("nmcli n off")
: execAsync("nmcli n on")
).catch(e => {
Notifications.getDefault().sendNotification({
appName: "network",
summary: "Couldn't turn off network",
body: `Turning off networking with nmcli failed: ${
e?.message ?? "(no error message)"}`
});
});
return;
}
// disable if no device available
self.state = false;
}}
/>;
function internetToTranslatedString(internet: AstalNetwork.Internet): string {
switch(internet) {
case AstalNetwork.Internet.CONNECTED:
return tr("connected");
case AstalNetwork.Internet.CONNECTING:
return tr("connecting") + "...";
}
return tr("disconnected");
}
@@ -30,7 +30,7 @@ export class Tile extends Gtk.Box {
public hasArrow: boolean = false;
declare $signals: Gtk.Box.SignalSignatures & {
"toggled": (_state: boolean) => void;
"toggled": (state: boolean) => void;
"enabled": () => void;
"disabled": () => void;
"clicked": () => void;
+16 -9
View File
@@ -16,34 +16,41 @@ export const FloatingNotifications = (mon: number) =>
generalConfig.bindProperty("notifications.position_h", "string"),
generalConfig.bindProperty("notifications.position_v", "string")
]).as(([posH, posV]) => {
let horizontal: Astal.WindowAnchor = Astal.WindowAnchor.RIGHT,
vertical: Astal.WindowAnchor = Astal.WindowAnchor.TOP;
const pos: Array<Astal.WindowAnchor> = [];
switch(posH) {
case "left":
horizontal = Astal.WindowAnchor.LEFT;
pos.push(Astal.WindowAnchor.LEFT);
break;
case "center":
horizontal = Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT;
pos.push(Astal.WindowAnchor.LEFT);
pos.push(Astal.WindowAnchor.RIGHT);
break;
case "right":
horizontal = Astal.WindowAnchor.RIGHT;
pos.push(Astal.WindowAnchor.RIGHT);
break;
}
switch(posV) {
case "top":
vertical = Astal.WindowAnchor.TOP;
pos.push(Astal.WindowAnchor.TOP);
break;
case "center":
vertical = Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM;
pos.push(Astal.WindowAnchor.TOP);
pos.push(Astal.WindowAnchor.BOTTOM);
break;
case "bottom":
vertical = Astal.WindowAnchor.BOTTOM;
pos.push(Astal.WindowAnchor.BOTTOM);
break;
}
return horizontal | vertical;
let finalPos: Astal.WindowAnchor;
pos.forEach(pos => finalPos = (finalPos !== undefined ?
finalPos | pos
: pos));
return finalPos!;
})} exclusivity={Astal.Exclusivity.NORMAL}
resizable={false} widthRequest={450}>