networks: make popup window
This commit is contained in:
parent
10cb02793a
commit
1f731072ac
6 changed files with 146 additions and 3 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
@forward "notifications";
|
@forward "notifications";
|
||||||
@forward "updates";
|
@forward "updates";
|
||||||
@forward "bluetoothdevices";
|
@forward "bluetoothdevices";
|
||||||
|
@forward "networks";
|
||||||
|
|
|
||||||
43
scss/popdowns/networks.scss
Normal file
43
scss/popdowns/networks.scss
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
@use "sass:color";
|
||||||
|
@use "../scheme";
|
||||||
|
@use "../lib";
|
||||||
|
@use "../font";
|
||||||
|
|
||||||
|
$-accent: scheme.$rosewater;
|
||||||
|
|
||||||
|
.networks {
|
||||||
|
@include lib.popdown-window($-accent);
|
||||||
|
|
||||||
|
min-width: lib.s(500);
|
||||||
|
min-height: lib.s(400);
|
||||||
|
|
||||||
|
.list {
|
||||||
|
@include lib.spacing($vertical: true);
|
||||||
|
|
||||||
|
color: scheme.$text;
|
||||||
|
|
||||||
|
.network {
|
||||||
|
@include lib.spacing(8);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: lib.s(18);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
@include lib.rounded(5);
|
||||||
|
@include lib.element-decel;
|
||||||
|
|
||||||
|
padding: lib.s(3) lib.s(8);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: scheme.$surface0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: scheme.$surface1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -219,10 +219,10 @@ const Tray = () => <box className="module tray">{bind(AstalTray.get_default(), "
|
||||||
|
|
||||||
const Network = () => (
|
const Network = () => (
|
||||||
<button
|
<button
|
||||||
onClick={(_, event) => {
|
onClick={(self, event) => {
|
||||||
const network = AstalNetwork.get_default();
|
const network = AstalNetwork.get_default();
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) {
|
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||||
// TODO: networks panel
|
togglePopup(self, event, "networks");
|
||||||
} else if (event.button === Astal.MouseButton.SECONDARY) network.wifi.enabled = !network.wifi.enabled;
|
} else if (event.button === Astal.MouseButton.SECONDARY) network.wifi.enabled = !network.wifi.enabled;
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||||
execAsync("uwsm app -- gnome-control-center wifi").catch(() => {
|
execAsync("uwsm app -- gnome-control-center wifi").catch(() => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import BluetoothDevices from "./bluetoothdevices";
|
import BluetoothDevices from "./bluetoothdevices";
|
||||||
|
import Networks from "./networks";
|
||||||
import Notifications from "./notifications";
|
import Notifications from "./notifications";
|
||||||
import Updates from "./updates";
|
import Updates from "./updates";
|
||||||
|
|
||||||
|
|
@ -6,6 +7,7 @@ export default () => {
|
||||||
<Notifications />;
|
<Notifications />;
|
||||||
<Updates />;
|
<Updates />;
|
||||||
<BluetoothDevices />;
|
<BluetoothDevices />;
|
||||||
|
<Networks />;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
97
src/modules/popdowns/networks.tsx
Normal file
97
src/modules/popdowns/networks.tsx
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { bind, execAsync, Variable } from "astal";
|
||||||
|
import { Gtk } from "astal/gtk3";
|
||||||
|
import AstalNetwork from "gi://AstalNetwork";
|
||||||
|
import PopdownWindow from "../../widgets/popdownwindow";
|
||||||
|
|
||||||
|
const Network = (accessPoint: AstalNetwork.AccessPoint) => (
|
||||||
|
<box className="network">
|
||||||
|
<icon className="icon" icon={bind(accessPoint, "iconName")} />
|
||||||
|
<label
|
||||||
|
truncate
|
||||||
|
xalign={0}
|
||||||
|
setup={self => {
|
||||||
|
const update = () =>
|
||||||
|
(self.label = `${accessPoint.ssid}${` (${accessPoint.frequency > 5000 ? 5 : 2.4}GHz | ${
|
||||||
|
accessPoint.strength
|
||||||
|
}/100)`}`);
|
||||||
|
self.hook(accessPoint, "notify::ssid", update);
|
||||||
|
self.hook(accessPoint, "notify::frequency", update);
|
||||||
|
self.hook(accessPoint, "notify::strength", update);
|
||||||
|
update();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<box hexpand />
|
||||||
|
<button
|
||||||
|
cursor="pointer"
|
||||||
|
onClicked={self => {
|
||||||
|
const cmd =
|
||||||
|
AstalNetwork.get_default().wifi.activeAccessPoint === accessPoint ? "c down id" : "d wifi connect";
|
||||||
|
execAsync(`nmcli ${cmd} '${accessPoint.ssid}'`)
|
||||||
|
.then(() => (self.sensitive = true))
|
||||||
|
.catch(console.error);
|
||||||
|
self.sensitive = false;
|
||||||
|
}}
|
||||||
|
label={bind(AstalNetwork.get_default().wifi, "activeAccessPoint").as(a =>
|
||||||
|
a === accessPoint ? "Disconnect" : "Connect"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
cursor="pointer"
|
||||||
|
onClicked={() => execAsync(`nmcli c delete id '${accessPoint.ssid}'`).catch(() => {})}
|
||||||
|
label="Forget"
|
||||||
|
/>
|
||||||
|
</box>
|
||||||
|
);
|
||||||
|
|
||||||
|
const List = () => {
|
||||||
|
const { wifi } = AstalNetwork.get_default();
|
||||||
|
const children = Variable.derive([bind(wifi, "accessPoints"), bind(wifi, "activeAccessPoint")], (aps, ac) =>
|
||||||
|
aps
|
||||||
|
.filter(a => a.ssid)
|
||||||
|
.sort((a, b) => (a === ac ? -1 : b.strength - a.strength))
|
||||||
|
.map(Network)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<box vertical valign={Gtk.Align.START} className="list" onDestroy={() => children.drop()}>
|
||||||
|
{bind(children)}
|
||||||
|
</box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const network = AstalNetwork.get_default();
|
||||||
|
const label = Variable("");
|
||||||
|
|
||||||
|
const update = () => {
|
||||||
|
if (network.primary === AstalNetwork.Primary.WIFI) label.set(network.wifi.ssid ?? "Disconnected");
|
||||||
|
else if (network.primary === AstalNetwork.Primary.WIRED) label.set(`Ethernet (${network.wired.speed})`);
|
||||||
|
else label.set("No Wifi");
|
||||||
|
};
|
||||||
|
network.connect("notify::primary", update);
|
||||||
|
network.get_wifi()?.connect("notify::ssid", update);
|
||||||
|
network.get_wired()?.connect("notify::speed", update);
|
||||||
|
update();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopdownWindow
|
||||||
|
name="networks"
|
||||||
|
count={bind(network.wifi, "accessPoints").as(a => a.length)}
|
||||||
|
countLabel={bind(label)}
|
||||||
|
headerButtons={[
|
||||||
|
{
|
||||||
|
label: bind(network.wifi, "enabled").as(p => (p ? "Disable" : "Enable")),
|
||||||
|
onClicked: () => (network.wifi.enabled = !network.wifi.enabled),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Scan",
|
||||||
|
onClicked: () => network.wifi.scan(),
|
||||||
|
enabled: bind(network.wifi, "scanning"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
emptyIcon="wifi_off"
|
||||||
|
emptyLabel={bind(network.wifi, "enabled").as(p => (p ? "No available networks" : "Wifi is off"))}
|
||||||
|
list={<List />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -16,7 +16,7 @@ export default ({
|
||||||
countLabel?: Binding<string>;
|
countLabel?: Binding<string>;
|
||||||
headerButtons: { label: string | Binding<string>; onClicked: () => void; enabled?: Binding<boolean> }[];
|
headerButtons: { label: string | Binding<string>; onClicked: () => void; enabled?: Binding<boolean> }[];
|
||||||
emptyIcon: string;
|
emptyIcon: string;
|
||||||
emptyLabel: string;
|
emptyLabel: string | Binding<string>;
|
||||||
list: JSX.Element;
|
list: JSX.Element;
|
||||||
}) => (
|
}) => (
|
||||||
<PopupWindow name={name}>
|
<PopupWindow name={name}>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue