1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
import { bind, Variable } from "astal";
import { Astal, Gtk } from "astal/gtk3";
import AstalBluetooth from "gi://AstalBluetooth";
import PopdownWindow from "../../widgets/popdownwindow";
const BluetoothDevice = (device: AstalBluetooth.Device) => (
<box className="device">
<icon
className="icon"
icon={bind(device, "icon").as(i =>
Astal.Icon.lookup_icon(`${i}-symbolic`) ? `${i}-symbolic` : "bluetooth-symbolic"
)}
/>
<label
truncate
xalign={0}
setup={self => {
const update = () =>
(self.label = `${device.alias}${
device.connected || device.paired ? ` (${device.connected ? "Connected" : "Paired"})` : ""
}`);
self.hook(device, "notify::alias", update);
self.hook(device, "notify::connected", update);
self.hook(device, "notify::paired", update);
update();
}}
/>
<box hexpand />
<button
cursor="pointer"
onClicked={self => {
if (device.connected)
device.disconnect_device((_, res) => {
self.sensitive = true;
device.disconnect_device_finish(res);
});
else
device.connect_device((_, res) => {
self.sensitive = true;
device.connect_device_finish(res);
});
self.sensitive = false;
}}
label={bind(device, "connected").as(c => (c ? "Disconnect" : "Connect"))}
/>
<button
cursor="pointer"
onClicked={() => AstalBluetooth.get_default().adapter.remove_device(device)}
label="Remove"
/>
</box>
);
const List = () => (
<box vertical valign={Gtk.Align.START} className="list">
{bind(AstalBluetooth.get_default(), "devices").as(d => d.map(BluetoothDevice))}
</box>
);
export default () => {
const bluetooth = AstalBluetooth.get_default();
const label = Variable("");
const update = () => {
const devices = bluetooth.get_devices();
const connected = devices.filter(d => d.connected).length;
label.set(`${connected} connected device${connected === 1 ? "" : "s"} (${devices.length} available)`);
};
bluetooth.get_devices().forEach(d => d.connect("notify::connected", update));
bluetooth.connect("device-added", (_, device) => device.connect("notify::connected", update));
bluetooth.connect("notify::devices", update);
update();
return (
<PopdownWindow
name="bluetooth-devices"
count={bind(bluetooth, "devices").as(n => n.length)}
countLabel={bind(label)}
headerButtons={[
{
label: bind(bluetooth, "isPowered").as(p => (p ? "Disable" : "Enable")),
onClicked: () => bluetooth.toggle(),
},
{
label: "Discovery",
onClicked: () => {
if (bluetooth.adapter.discovering) bluetooth.adapter.start_discovery();
else bluetooth.adapter.stop_discovery();
},
enabled: bind(bluetooth.adapter, "discovering"),
},
]}
emptyIcon="bluetooth_disabled"
emptyLabel="No Bluetooth devices"
list={<List />}
/>
);
};
|