mirror of
https://github.com/xsghetti/HyprCrux.git
synced 2025-07-04 06:10:40 -04:00
141 lines
3.5 KiB
JavaScript
141 lines
3.5 KiB
JavaScript
import { Arrow, Menu } from "../ToggleButton.js"
|
|
import { dependencies, icon, sh } from "../../../lib/utils.js"
|
|
import icons from "../../../lib/icons.js"
|
|
const audio = await Service.import("audio")
|
|
|
|
const VolumeIndicator = (type = "speaker") => Widget.Button({
|
|
vpack: "center",
|
|
on_clicked: () => audio[type].is_muted = !audio[type].is_muted,
|
|
child: Widget.Icon({
|
|
icon: audio[type].bind("icon_name")
|
|
.as(i => icon(i || "", icons.audio.mic.high)),
|
|
tooltipText: audio[type].bind("volume")
|
|
.as(vol => `Volume: ${Math.floor(vol * 100)}%`),
|
|
}),
|
|
})
|
|
|
|
const VolumeSlider = (type = "speaker") => Widget.Slider({
|
|
hexpand: true,
|
|
draw_value: false,
|
|
on_change: ({ value, dragging }) => dragging && (audio[type].volume = value),
|
|
value: audio[type].bind("volume"),
|
|
})
|
|
|
|
export const Volume = () => Widget.Box({
|
|
class_name: "volume",
|
|
children: [
|
|
VolumeIndicator("speaker"),
|
|
VolumeSlider("speaker"),
|
|
Widget.Box({
|
|
vpack: "center",
|
|
child: Arrow("sink-selector"),
|
|
}),
|
|
Widget.Box({
|
|
vpack: "center",
|
|
child: Arrow("app-mixer"),
|
|
visible: audio.bind("apps").as(a => a.length > 0),
|
|
}),
|
|
],
|
|
})
|
|
|
|
export const Microhone = () => Widget.Box({
|
|
class_name: "slider horizontal",
|
|
visible: audio.bind("recorders").as(a => a.length > 0),
|
|
children: [
|
|
VolumeIndicator("microphone"),
|
|
VolumeSlider("microphone"),
|
|
],
|
|
})
|
|
|
|
const MixerItem = (stream) => Widget.Box(
|
|
{
|
|
hexpand: true,
|
|
class_name: "mixer-item horizontal",
|
|
},
|
|
Widget.Icon({
|
|
tooltip_text: stream.bind("name").as(n => n || ""),
|
|
icon: stream.bind("name").as(n => {
|
|
return Utils.lookUpIcon(n || "")
|
|
? (n || "")
|
|
: icons.fallback.audio
|
|
}),
|
|
}),
|
|
Widget.Box(
|
|
{ vertical: true },
|
|
Widget.Label({
|
|
xalign: 0,
|
|
truncate: "end",
|
|
max_width_chars: 28,
|
|
label: stream.bind("description").as(d => d || ""),
|
|
}),
|
|
Widget.Slider({
|
|
hexpand: true,
|
|
draw_value: false,
|
|
value: stream.bind("volume"),
|
|
on_change: ({ value }) => stream.volume = value,
|
|
}),
|
|
),
|
|
)
|
|
|
|
const SinkItem = (stream) => Widget.Button({
|
|
hexpand: true,
|
|
on_clicked: () => audio.speaker = stream,
|
|
child: Widget.Box({
|
|
children: [
|
|
Widget.Icon({
|
|
icon: icon(stream.icon_name || "", icons.fallback.audio),
|
|
tooltip_text: stream.icon_name || "",
|
|
}),
|
|
Widget.Label((stream.description || "").split(" ").slice(0, 4).join(" ")),
|
|
Widget.Icon({
|
|
icon: icons.ui.tick,
|
|
hexpand: true,
|
|
hpack: "end",
|
|
visible: audio.speaker.bind("stream").as(s => s === stream.stream),
|
|
}),
|
|
],
|
|
}),
|
|
})
|
|
|
|
const SettingsButton = () => Widget.Button({
|
|
on_clicked: () => {
|
|
if (dependencies("pavucontrol"))
|
|
sh("pavucontrol")
|
|
},
|
|
hexpand: true,
|
|
child: Widget.Box({
|
|
children: [
|
|
Widget.Icon(icons.ui.settings),
|
|
Widget.Label("Settings"),
|
|
],
|
|
}),
|
|
})
|
|
|
|
export const AppMixer = () => Menu({
|
|
name: "app-mixer",
|
|
icon: icons.audio.mixer,
|
|
title: "App Mixer",
|
|
content: [
|
|
Widget.Box({
|
|
vertical: true,
|
|
class_name: "vertical mixer-item-box",
|
|
children: audio.bind("apps").as(a => a.map(MixerItem)),
|
|
}),
|
|
Widget.Separator(),
|
|
SettingsButton(),
|
|
],
|
|
})
|
|
|
|
export const SinkSelector = () => Menu({
|
|
name: "sink-selector",
|
|
icon: icons.audio.type.headset,
|
|
title: "Sink Selector",
|
|
content: [
|
|
Widget.Box({
|
|
vertical: true,
|
|
children: audio.bind("speakers").as(a => a.map(SinkItem)),
|
|
}),
|
|
Widget.Separator(),
|
|
SettingsButton(),
|
|
],
|
|
})
|