- Scaling 16px base pour ultrawide 3440x1440 - Bar: CPU/RAM/GPU visible, media single player (skip playerctld), network tooltip LAN/WAN IPv4 - Volume: class module pour sizing cohérent - Battery: désactivé (PC fixe) - Clock: tooltip calendrier + uptime - BrainPower: panel enrichi (focus, session, intentions, todos, repos git, derniers commits) - App: BrainPower sur moniteur principal uniquement - Heartbeat: Layer.TOP pour compatibilité COSMIC
45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
import AstalWp from "gi://AstalWp"
|
|
import { createBinding } from "ags"
|
|
|
|
export default function Volume() {
|
|
const speaker = AstalWp.get_default()!.defaultSpeaker!
|
|
|
|
const volume = createBinding(speaker, "volume")
|
|
const mute = createBinding(speaker, "mute")
|
|
|
|
const text = volume((v: number) => {
|
|
const pct = Math.round(v * 100)
|
|
const muted = speaker.mute
|
|
let icon = ""
|
|
if (muted) icon = ""
|
|
else if (v > 0.66) icon = ""
|
|
else if (v > 0.33) icon = ""
|
|
else if (v > 0) icon = ""
|
|
else icon = ""
|
|
return `${icon} ${pct}%`
|
|
})
|
|
|
|
const cls = mute((m: boolean) =>
|
|
m ? "volume module muted" : "volume module"
|
|
)
|
|
|
|
return (
|
|
<button
|
|
class={cls}
|
|
onClicked={() => {
|
|
speaker.mute = !speaker.mute
|
|
}}
|
|
onScroll={(_self: any, event: any) => {
|
|
const delta = event.delta_y
|
|
if (delta < 0) {
|
|
speaker.volume = Math.min(speaker.volume + 0.05, 1.0)
|
|
} else {
|
|
speaker.volume = Math.max(speaker.volume - 0.05, 0.0)
|
|
}
|
|
}}
|
|
>
|
|
<label label={text} />
|
|
</button>
|
|
)
|
|
}
|