Files
dotfiles/home/natto/ags/windows/settings/audio.js
2024-06-01 18:10:31 +05:30

70 lines
2.1 KiB
JavaScript

const audio = await Service.import("audio");
export default () => {
const isSpeaker = Variable(true);
/** @param {'speaker' | 'microphone'} type */
const VolumeSlider = (type = "speaker") =>
Widget.Slider({
hexpand: true,
drawValue: false,
onChange: ({ value }) => (audio[type].volume = value),
value: audio[type].bind("volume"),
});
const speakerSlider = VolumeSlider("speaker");
const micSlider = VolumeSlider("microphone");
const speakerIndicator = Widget.Button({
on_clicked: () => (audio.speaker.is_muted = !audio.speaker.is_muted),
child: Widget.Icon().hook(audio.speaker, (self) => {
self.className = "volume-icon";
const vol = audio.speaker.volume * 100;
let icon = [
[101, "overamplified"],
[67, "high"],
[34, "medium"],
[1, "low"],
[0, "muted"],
].find(([threshold]) => threshold <= vol)?.[1];
if (audio.speaker.is_muted) icon = "muted";
self.icon = `audio-volume-${icon}-symbolic`;
self.tooltip_text = `Volume ${Math.floor(vol)}%`;
}),
});
const micIndicator = Widget.Button({
on_clicked: () => (audio.microphone.is_muted = !audio.microphone.is_muted),
child: Widget.Icon().hook(audio.microphone, (self) => {
self.className = "volume-icon";
const vol = audio.microphone.volume * 100;
let icon = [
[67, "high"],
[34, "medium"],
[1, "low"],
[0, "muted"],
].find(([threshold]) => threshold <= vol)?.[1];
if (audio.microphone.is_muted) icon = "muted";
self.icon = `microphone-sensitivity-${icon}-symbolic`;
self.tooltip_text = `Volume ${Math.floor(vol)}%`;
}),
});
return Widget.EventBox({
cursor: "pointer",
className: "volume",
onSecondaryClick: () => (isSpeaker.value = !isSpeaker.value),
child: Widget.Stack({
children: {
speaker: Widget.Box({}, speakerSlider, speakerIndicator),
microphone: Widget.Box({}, micSlider, micIndicator),
},
shown: isSpeaker.bind().as((s) => (s ? "speaker" : "microphone")),
}),
});
};