Add bluetooth selector

This commit is contained in:
2024-07-07 18:38:13 +07:00
parent 0b3658fe71
commit 7db26e31eb
6 changed files with 123 additions and 107 deletions
+4 -19
View File
@@ -1,8 +1,8 @@
import Gtk from "gi://Gtk?version=3.0";
import * as audio from "../modules/audio.js";
import * as brightness from "../modules/brightness.js";
import * as network from "../modules/network.js";
// import * as bluetooth from "../modules/bluetooth.js";
import * as network from "../modules/network.js";
import * as bluetooth from "../modules/bluetooth.js";
// import * as darkmode from "../modules/darkmode.js";
// import * as nightmode from "../modules/nightmode.js";
import * as mpris from "../modules/mpris.js";
@@ -42,24 +42,9 @@ export const Quicksettings = () =>
),
brightness.Brightness({}),
Row(
[network.Toggle({}), network.Toggle({})],
[network.Selection({})],
[network.Toggle({}), bluetooth.Toggle({})],
[network.Selection({}), bluetooth.Selection({})],
),
// Widget.Box({
// children: [network.Toggle({}), bluetooth.Toggle({})],
// }),
// Submenu({
// menuName: "network",
// icon: "network-wireless-symbolic",
// title: "Network",
// contentType: network.Selection,
// }),
// Submenu({
// menuName: "bluetooth",
// icon: "bluetooth-symbolic",
// title: "Bluetooth",
// contentType: bluetooth.Devices,
// }),
// Box({
// children: [darkmode.DarkToggle(), nightmode.NightToggle()],
// }),
+10 -8
View File
@@ -14,13 +14,14 @@ export const Padding = (
name,
{ css = "", hexpand = true, vexpand = true } = {},
) =>
Widget.EventBox({
hexpand,
vexpand,
can_focus: false,
child: Widget.Box({ css }),
setup: (w) => w.on("button-press-event", () => App.toggleWindow(name)),
});
Widget.Box({});
// Widget.EventBox({
// hexpand,
// vexpand,
// can_focus: false,
// child: Widget.Box({ css }),
// setup: (w) => w.on("button-press-event", () => App.toggleWindow(name)),
// });
/**
* @param {string} name
* @param {Child} child
@@ -189,7 +190,8 @@ export default ({
keymode: "on-demand",
exclusivity,
layer: "top",
anchor: ["top", "bottom", "right", "left"],
anchor: ["top", "right"],
// anchor: ["top", "bottom", "right", "left"],
child: Layout(name, child, transition, duration)[layout](),
...props,
});
+75 -76
View File
@@ -1,5 +1,4 @@
// import { Spinner, Separator } from "../misc.js";
// import { ArrowToggle } from "../services/quicksettings.js";
import { ArrowToggleButton, Menu, SettingsButton } from "../misc/menu.js";
const bluetooth = await Service.import("bluetooth");
@@ -9,84 +8,84 @@ const connected = Utils.merge(
);
/** @param {{hideIfDisabled?: boolean} & import("types/widgets/icon").IconProps} props */
export const Indicator = ({ hideIfDisabled, ...props } = {}) =>
export const Indicator = ({ hideIfDisabled = false, ...props } = {}) =>
Widget.Icon({
icon: connected.as(
(x) => `bluetooth-${x ? "active" : "disabled"}-symbolic`,
),
visible: connected.as(x => x || !hideIfDisabled),
visible: connected.as((x) => x || !hideIfDisabled),
...props,
});
// export const Toggle = (props) =>
// ArrowToggle({
// ...props,
// name: "bluetooth",
// icon: Indicator(),
// label: ConnectedLabel(),
// toggle: () => (Bluetooth.enabled = !Bluetooth.enabled),
// expand: () => (Bluetooth.enabled = true),
// connections: [[Bluetooth, (button) => button.toggleClassName("accent", Bluetooth.enabled)]],
// });
//
// export const ConnectedLabel = (props) =>
// Label({
// truncate: "end",
// ...props,
// connections: [
// [
// Bluetooth,
// (label) => {
// if (!Bluetooth.enabled) return (label.label = "Disabled");
//
// if (Bluetooth.connectedDevices.length === 0) return (label.label = "Not Connected");
//
// if (Bluetooth.connectedDevices.length === 1)
// return (label.label = Bluetooth.connectedDevices[0].alias);
//
// label.label = `${Bluetooth.connectedDevices.length} Connected`;
// },
// ],
// ],
// });
//
// export const Devices = (props) =>
// Box({
// ...props,
// vertical: true,
// connections: [
// [
// Bluetooth,
// (box) => {
// box.children = Bluetooth.devices
// .map((device) =>
// Button({
// onClicked: () => device.setConnection(!device.connected),
// hexpand: false,
// child: Box({
// children: [
// Icon(device.iconName + "-symbolic"),
// Label(device.name),
// Box({ hexpand: true }),
// device._connecting ? Spinner() : Label(device.connected ? "Disconnect" : "Connect"),
// ],
// }),
// })
// )
// .concat([
// Separator(),
// Button({
// onClicked: () => {
// execAsync("blueberry").catch(print);
// App.closeWindow("quicksettings");
// },
// child: Label({
// label: "Settings",
// xalign: 0,
// }),
// }),
// ]);
// },
// ],
// ],
// });
/** @param {import("types/widgets/label").LabelProps} props */
export const ConnectedLabel = (props) =>
Widget.Label(props).hook(bluetooth, (self) => {
if (!bluetooth.enabled) self.label = "Disabled";
if (bluetooth.connected_devices.length === 0) self.label = "Disconnected";
else if (bluetooth.connected_devices.length === 1)
self.label = bluetooth.connected_devices[0].alias;
else self.label = `${bluetooth.connected_devices.length} Connected`;
});
/** @param {Partial<import("misc/menu").ArrowToggleButtonProps>} props */
export const Toggle = (props) =>
ArrowToggleButton({
name: "bluetooth",
icon: Indicator({ className: "qs-icon" }),
label: ConnectedLabel({
max_width_chars: 20,
}),
activate: () => {
bluetooth.enabled = true;
},
deactivate: () => {
bluetooth.enabled = false;
},
connection: [bluetooth, () => bluetooth.enabled],
...props,
});
/** @param {Partial<import("../misc/menu.js").MenuProps>} props */
export const Selection = (props) =>
Menu({
name: "bluetooth",
icon: Indicator({}),
title: "Bluetooth",
content: [
Widget.Box({
vertical: true,
className: "qs-sub-sub-content",
children: bluetooth.bind("devices").as((x) => x.map(DeviceItem)),
}),
Widget.Separator({ className: "accent" }),
SettingsButton({ type: "bluetooth" }),
],
...props,
});
/** @param {import("types/service/bluetooth.js").BluetoothDevice} device */
const DeviceItem = (device) =>
Widget.Box({
children: [
Widget.Icon(`${device.icon_name}-symbolic`),
Widget.Label(device.name),
Widget.Label({
label: `${device.battery_percentage}%`,
visible: device.bind("battery_percentage").as((x) => x > 0),
}),
Widget.Box({ hexpand: true }),
Widget.Spinner({
active: device.bind("connecting"),
visible: device.bind("connecting"),
}),
Widget.Switch({
active: device.connected,
visible: device.bind("connecting").as((p) => !p),
setup: (self) =>
self.on("notify::active", () => {
device.setConnection(self.active);
}),
}),
],
});
+1 -1
View File
@@ -81,7 +81,7 @@ export const Selection = (props) =>
const Wired = () =>
Widget.Button({
// onClicked:
visible: network.wired.bind("state").as(x => (console.log(x), true)),
// visible: network.wired.bind("state").as(x => (console.log(x), true)),
child: Widget.Box({
children: [
Widget.Icon({ icon: network.wired.bind("icon_name") }),
+24 -2
View File
@@ -1,10 +1,13 @@
* {
all: unset;
font-family: monospace;
padding: 0;
margin: 0;
}
button {
all: unset;
}
/* Colors */
.transparent {
background-color: rgba(0, 0, 0, 0.6);
@@ -87,7 +90,7 @@ trough {
background-color: #000;
border-radius: 100px;
}
highlight, progress {
highlight, fill {
background-color: #94e2d5;
border-radius: 100px;
}
@@ -97,6 +100,25 @@ mark {
min-height: 3px;
}
switch {
background-color: #000;
border-radius: 100px;
}
switch slider {
all: unset;
transition: 200ms;
background-color: #94e2d5;
border-radius: 100px;
min-width: 1rem;
min-height: 1rem;
}
switch image {
all: unset;
color: transparent;
}
/* Bar */
.module {
padding: 1px 10px;
+9 -1
View File
@@ -17,7 +17,15 @@
networking.networkmanager.enable = true;
hardware.pulseaudio.enable = false;
hardware.bluetooth.enable = true;
hardware.bluetooth = {
enable = true;
settings = {
General = {
# enable battery reporting
Experimental = true;
};
};
};
services.pipewire = {
enable = true;
alsa.enable = true;