nixos/modules/home/ags/app/widget/Volume.tsx

55 lines
1.6 KiB
TypeScript

import AstalWp from "gi://AstalWp"
import { Variable, bind } from "astal"
import Dropdown from "./Dropdown"
const speaker = AstalWp.get_default().audio.default_speaker!
const icon = Variable.derive(
[bind(speaker, "volume"), bind(speaker, "mute")],
(volume, mute) => {
if (mute || volume <= 0.01) return "audio-volume-muted-symbolic"
if (volume < 0.33) return "audio-volume-low-symbolic"
if (volume < 0.66) return "audio-volume-medium-symbolic"
return "audio-volume-high-symbolic"
}
)
export function VolumeWidget(gdkmonitor: Gdk.Monitor) {
const open = Variable(false)
const button = (
<button
className="volume"
onClicked={() => open.set(!open.get())}
onScroll={(_, e) => {
const volume = Math.min(1, Math.max(0, speaker.volume - e.delta_y * 0.02))
speaker.volume = volume
}}
>
<icon icon={icon()} />
</button>
)
const popup = (
<Dropdown
gdkmonitor={gdkmonitor}
target={button}
open={open}
width={240}
vertical={false}
>
<button className="mute" onClicked={() => (speaker.mute = !speaker.mute)}>
<icon icon={icon()} />
</button>
<slider
className="vol-slider"
hexpand
value={bind(speaker, "volume")}
onDragged={(self) => (speaker.volume = self.value)}
/>
</Dropdown>
)
return { button, popup }
}