Files
hyprland/config/ags/apps/settings/bluetooth.ts
T
2024-07-06 06:07:24 +05:45

175 lines
5.7 KiB
TypeScript

import { type BluetoothDevice } from "types/service/bluetooth";
import Gtk from "gi://Gtk?version=3.0";
import { timeout } from "resource:///com/github/Aylur/ags/utils.js";
const bluetooth = await Service.import("bluetooth");
const HpackStartLabel = (label: string) =>
Widget.Label({
label: label,
hpack: "start"
});
const BluetoothToggle = () =>
Widget.EventBox({
class_name: "row",
child: Widget.Box({
class_name: "row",
children: [
Widget.Box({
vertical: true,
vpack: "center",
hexpand: true,
children: [
Widget.Label({
hpack: "start",
class_name: "title",
label: "Enabled"
})
// Widget.Label({
// hpack: "start",
// class_name: "description",
// label: "Idk"
// })
]
}),
Widget.Switch({
vexpand: false,
vpack: "center",
hpack: "end",
on_activate: (self) => {
if (self.state != bluetooth.enabled) bluetooth.enabled = self.state;
},
state: bluetooth.bind("enabled")
})
]
}),
on_primary_click_release: (self) => {
self.child.children[1]!.activate();
},
on_secondary_click_release: (self, event) => {
Widget.Menu({
children: [
Widget.MenuItem({
child: HpackStartLabel("Open blueman-manager"),
on_activate: () => {
Utils.execAsync("blueman-manager").catch(print);
}
})
]
}).popup_at_pointer(event);
}
});
const DeviceMenu = (device: BluetoothDevice) => {
if (device.connecting) {
return undefined;
}
return Widget.Menu({
children: [
!device.connected
? Widget.MenuItem({
child: HpackStartLabel("Connect"),
on_activate: () => {
device.setConnection(true);
}
})
: Widget.MenuItem({
child: HpackStartLabel("Disconnect"),
on_activate: () => {
device.setConnection(false);
}
}),
Widget.MenuItem({
child: HpackStartLabel("Copy Address"),
on_activate: () => {
Utils.execAsync(["wl-copy", device.address]);
}
})
]
});
};
const DeviceItem = (device: BluetoothDevice) =>
Widget.Button({
class_name: "row",
on_primary_click_release: () => {
device.setConnection(!device.connected);
},
on_secondary_click_release: (self, event) => {
DeviceMenu(device)?.popup_at_pointer(event);
},
child: Widget.Box({
class_name: "device_box",
children: [
Widget.Icon({
icon: `${device.icon_name}-symbolic`,
hpack: "center",
vpack: "center",
size: 20
}),
// @ts-ignore
Widget.Box({
vertical: true,
vpack: "center",
children: [
Widget.Label({
class_name: "title",
label: device.name.trim(),
hpack: "start"
}),
device.connecting
? Widget.Label({
class_name: "description",
label: device.connected ? "Disconnecting..." : "Connecting...",
hpack: "start"
})
: device.connected
? Widget.Label({
class_name: "description",
label: "Active",
hpack: "start"
})
: undefined
]
})
]
}),
setup: (self) => {
self.toggleClassName("active", device.connected);
}
});
function DeviceList() {
return Widget.Box({
vertical: true,
attribute: {
updateDeviceList: (self) => {
const devices = bluetooth.devices || [];
self.children = Object.values(devices)
.sort((a: BluetoothDevice, b: BluetoothDevice) => {
if (a.connected) return -1;
if (b.connected) return 1;
return 0;
})
.filter((n: BluetoothDevice) => n.device.name !== null)
.map((n: BluetoothDevice) => DeviceItem(n));
}
},
className: "device_list",
setup: (self) => self.hook(bluetooth, self.attribute.updateDeviceList)
});
}
export const Bluetooth = () =>
Widget.Scrollable({
hscroll: "never",
child: Widget.Box({
hexpand: true,
vexpand: true,
vertical: true,
children: [BluetoothToggle(), DeviceList()]
})
});