nixos-configs/modules/ags/config/ts/quick-settings/network.ts

241 lines
8.3 KiB
TypeScript
Raw Normal View History

const Network = await Service.import('network');
2023-12-04 15:39:12 -05:00
const { Box, Icon, Label, ListBox, Overlay, Revealer, Scrollable } = Widget;
const { execAsync } = Utils;
2023-12-04 15:39:12 -05:00
import CursorBox from '../misc/cursorbox.ts';
2023-12-04 15:39:12 -05:00
const SCROLL_THRESH_H = 200;
const SCROLL_THRESH_N = 7;
2023-12-04 15:39:12 -05:00
2024-01-13 11:15:08 -05:00
// Types
2024-02-21 19:08:55 -05:00
import { APType, APBox, ScrollableGeneric } from 'global-types';
2024-01-22 10:23:32 -05:00
import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
2023-12-04 15:39:12 -05:00
2023-12-23 01:14:21 -05:00
2024-01-13 11:15:08 -05:00
const AccessPoint = (ap: APType) => {
2023-12-04 15:39:12 -05:00
const widget = Box({
2023-12-23 01:14:21 -05:00
class_name: 'menu-item',
attribute: {
ap: Variable(ap),
},
2023-12-04 15:39:12 -05:00
});
const child = Box({
hexpand: true,
children: [
2023-12-23 01:14:21 -05:00
Icon().hook(widget.attribute.ap, (self) => {
self.icon = widget.attribute.ap.value.iconName;
2023-12-04 15:39:12 -05:00
}),
2023-12-23 01:14:21 -05:00
Label().hook(widget.attribute.ap, (self) => {
self.label = widget.attribute.ap.value.ssid || '';
2023-12-04 15:39:12 -05:00
}),
Icon({
icon: 'object-select-symbolic',
hexpand: true,
hpack: 'end',
2023-12-23 01:14:21 -05:00
setup: (self) => {
self.hook(Network, () => {
self.setCss(
`opacity: ${
2023-12-23 01:14:21 -05:00
widget.attribute.ap.value.ssid ===
Network.wifi.ssid ?
'1' :
'0'
};
`,
);
});
},
2023-12-04 15:39:12 -05:00
}),
],
});
widget.add(Revealer({
2023-12-23 01:14:21 -05:00
reveal_child: true,
2023-12-04 15:39:12 -05:00
transition: 'slide_down',
2023-12-23 01:14:21 -05:00
child: CursorBox({
on_primary_click_release: () => {
2023-12-04 15:39:12 -05:00
execAsync(`nmcli device wifi connect
2023-12-23 01:14:21 -05:00
${widget.attribute.ap.value.bssid}`).catch(print);
2023-12-04 15:39:12 -05:00
},
child,
}),
}));
return widget;
};
export const NetworkMenu = () => {
const APList = new Map();
2023-12-23 01:14:21 -05:00
2023-12-04 15:39:12 -05:00
const topArrow = Revealer({
2023-12-04 17:48:56 -05:00
transition: 'slide_down',
2023-12-23 01:14:21 -05:00
2023-12-04 15:39:12 -05:00
child: Icon({
icon: `${App.configDir }/icons/down-large.svg`,
2023-12-23 01:14:21 -05:00
class_name: 'scrolled-indicator',
2023-12-04 15:39:12 -05:00
size: 16,
css: '-gtk-icon-transform: rotate(180deg);',
}),
});
const bottomArrow = Revealer({
2023-12-04 17:48:56 -05:00
transition: 'slide_up',
2023-12-23 01:14:21 -05:00
2023-12-04 15:39:12 -05:00
child: Icon({
icon: `${App.configDir }/icons/down-large.svg`,
2023-12-23 01:14:21 -05:00
class_name: 'scrolled-indicator',
2023-12-04 15:39:12 -05:00
size: 16,
}),
});
return Overlay({
pass_through: true,
2023-12-23 01:14:21 -05:00
2023-12-04 15:39:12 -05:00
overlays: [
Box({
vpack: 'start',
hpack: 'center',
css: 'margin-top: 12px',
children: [topArrow],
}),
Box({
vpack: 'end',
hpack: 'center',
css: 'margin-bottom: 12px',
children: [bottomArrow],
}),
],
child: Box({
2023-12-23 01:14:21 -05:00
class_name: 'menu',
2023-12-04 15:39:12 -05:00
child: Scrollable({
hscroll: 'never',
vscroll: 'never',
setup: (self) => {
self.on('edge-reached', (_, pos) => {
// Manage scroll indicators
if (pos === 2) {
2023-12-23 01:14:21 -05:00
topArrow.reveal_child = false;
bottomArrow.reveal_child = true;
}
else if (pos === 3) {
2023-12-23 01:14:21 -05:00
topArrow.reveal_child = true;
bottomArrow.reveal_child = false;
}
});
},
2023-12-04 15:39:12 -05:00
child: ListBox({
setup: (self) => {
2024-01-13 11:15:08 -05:00
self.set_sort_func((a, b) => {
2024-02-21 19:08:55 -05:00
const bState = (b.get_children()[0] as APBox)
2024-01-13 11:15:08 -05:00
.attribute.ap.value.strength;
2024-02-21 19:08:55 -05:00
const aState = (a.get_children()[0] as APBox)
2024-01-13 11:15:08 -05:00
.attribute.ap.value.strength;
return bState - aState;
});
2023-12-04 15:39:12 -05:00
self.hook(Network, () => {
// Add missing APs
2024-01-13 11:15:08 -05:00
const currentAPs = Network.wifi
?.access_points as Array<APType>;
currentAPs.forEach((ap) => {
if (ap.ssid !== 'Unknown') {
if (APList.has(ap.ssid)) {
const accesPoint = APList.get(ap.ssid)
2023-12-23 01:14:21 -05:00
.attribute.ap.value;
if (accesPoint.strength < ap.strength) {
2023-12-23 01:14:21 -05:00
APList.get(ap.ssid).attribute
2024-02-11 02:18:59 -05:00
.ap.setValue(ap);
}
2023-12-04 15:39:12 -05:00
}
else {
APList.set(ap.ssid, AccessPoint(ap));
2023-12-04 15:39:12 -05:00
self.add(APList.get(ap.ssid));
self.show_all();
}
2023-12-04 15:39:12 -05:00
}
});
2023-12-04 15:39:12 -05:00
// Delete ones that don't exist anymore
const difference = Array.from(APList.keys())
.filter((ssid) => !Network.wifi.access_points
.find((ap) => ap.ssid === ssid) &&
ssid !== 'Unknown');
2023-12-04 15:39:12 -05:00
difference.forEach((ssid) => {
const apWidget = APList.get(ssid);
2023-12-04 15:39:12 -05:00
if (apWidget) {
if (apWidget.toDestroy) {
apWidget.get_parent().destroy();
APList.delete(ssid);
}
else {
apWidget.children[0]
.reveal_child = false;
apWidget.toDestroy = true;
}
2023-12-04 15:39:12 -05:00
}
});
// Start scrolling after a specified height
// is reached by the children
const height = Math.max(
2023-12-23 01:14:21 -05:00
self.get_parent()?.get_allocated_height() || 0,
SCROLL_THRESH_H,
);
2024-01-13 11:15:08 -05:00
const scroll = (self.get_parent() as ListBoxRow)
2024-02-21 19:08:55 -05:00
?.get_parent() as ScrollableGeneric;
2023-12-23 01:14:21 -05:00
if (scroll) {
const n_child = self.get_children().length;
2023-12-23 01:14:21 -05:00
if (n_child > SCROLL_THRESH_N) {
scroll.vscroll = 'always';
scroll.setCss(`min-height: ${height}px;`);
2023-12-23 01:14:21 -05:00
// Make bottom scroll indicator appear only
// when first getting overflowing children
if (!(bottomArrow.reveal_child === true ||
topArrow.reveal_child === true)) {
bottomArrow.reveal_child = true;
}
}
else {
scroll.vscroll = 'never';
scroll.setCss('');
topArrow.reveal_child = false;
bottomArrow.reveal_child = false;
2023-12-04 15:39:12 -05:00
}
}
// Trigger sort_func
2024-01-13 11:15:08 -05:00
(self.get_children() as Array<ListBoxRow>)
.forEach((ch) => {
ch.changed();
});
2023-12-04 15:39:12 -05:00
});
},
2023-12-04 15:39:12 -05:00
}),
}),
}),
});
};