154 lines
5.2 KiB
TypeScript

import { bind } from "astal";
import { Gtk } from "astal/gtk4";
import AstalBluetooth from "gi://AstalBluetooth";
import BTDevice from "./Device";
const bt = AstalBluetooth.get_default();
const BluetoothModule = () => {
return (
<box>
<button
cssClasses={bind(bt.adapter, "powered").as(powered =>
powered
? ["bt-toggle-button", "bt-on"]
: ["bt-toggle-button"],
)}
onClicked={() =>
bt.adapter.set_powered(!bt.adapter.get_powered())
}
child={
<box vertical>
<label
cssClasses={["button-title"]}
label={"Bluetooth"}
></label>
<box>
<label
visible={bind(bt.adapter, "powered").as(
p => !p,
)}
label="Disabled"
></label>
<label
visible={bind(bt.adapter, "powered")}
label={bind(bt, "devices").as(devices => {
let count = 0;
devices.forEach(device => {
if (device.connected) {
count++;
}
});
return `On (${count} ${count === 1 ? "client" : "clients"} connected)`;
})}
></label>
</box>
<label></label>
</box>
}
></button>
<button
cssClasses={["bt-devices-button"]}
visible={bind(bt.adapter, "powered")}
child={
<box>
<image iconName={"arrow-right-symbolic"}></image>
{picker}
</box>
}
onClicked={() => openBTPicker()}
></button>
</box>
);
};
const openBTPicker = () => {
picker.popup();
try {
bt.adapter.start_discovery();
} catch (_) {}
};
const BluetoothPickerList = () => {
return (
<box vertical onDestroy={() => bt.adapter.stop_discovery()}>
<label label={"Connected devices"} cssClasses={["title-2"]}></label>
<Gtk.Separator marginTop={3} marginBottom={5}></Gtk.Separator>
<box vertical cssClasses={["bt-conn-list"]}>
{bind(bt, "devices").as(devices => {
return devices
.filter(device => {
if (device.get_connected()) {
return device;
}
})
.map(device => {
return <BTDevice device={device}></BTDevice>;
});
})}
</box>
<label
visible={bind(bt, "devices").as(devices => {
return (
devices.filter(device => {
if (device.get_connected()) {
return device;
}
}).length === 0
);
})}
label={"No connected devices"}
cssClasses={["bt-no-found", "bt-conn-list"]}
></label>
<label
label={"Discovered bluetooth devices"}
cssClasses={["title-2"]}
></label>
<Gtk.Separator marginBottom={5} marginTop={3}></Gtk.Separator>
<box vertical>
{bind(bt, "devices").as(devices => {
return devices
.filter(data => {
if (!data.get_connected()) {
return data;
}
})
.map(device => {
return <BTDevice device={device}></BTDevice>;
});
})}
</box>
<label
visible={bind(bt, "devices").as(devices => {
return (
devices.filter(device => {
if (!device.get_connected()) {
return device;
}
}).length === 0
);
})}
label={"No discovered devices"}
cssClasses={["bt-no-found"]}
></label>
</box>
);
};
const BluetoothPicker = () => {
const popover = new Gtk.Popover();
popover.set_child(BluetoothPickerList());
popover.connect( 'closed', () => bt.adapter.stop_discovery() );
return popover;
};
const picker = BluetoothPicker();
export default {
BluetoothModule,
};