1
1
Fork 0
nixos/options/custom/programs/ags/config.js

179 lines
4.4 KiB
JavaScript
Raw Normal View History

const battery = await Service.import('battery')
const audio = await Service.import('audio')
const hyprland = await Service.import('hyprland')
const mpris = await Service.import('mpris')
const notifications = await Service.import('notifications')
const systemtray = await Service.import('systemtray')
/// WORKSPACES ///
const Workspaces = () => Widget.EventBox({
onScrollDown: () => hyprland.messageAsync(`dispatch workspace -1`),
onScrollUp: () => hyprland.messageAsync(`dispatch workspace +1`),
child: Widget.Box({
spacing: 8,
//?? Increase length if workspaces > 10
children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => Widget.Button({
onClicked: () => hyprland.messageAsync(`dispatch workspace ${i}`),
attribute: i,
label: `${i}`,
})),
// Initial button visibility
setup: self => self.hook(hyprland, () => self.children.forEach(btn => {
btn.visible = hyprland.workspaces.some(ws => ws.id === btn.attribute)
})),
}),
})
/// CLOCK ///
const Clock = () => Widget.Label({
class_name: 'clock',
setup: self => self.poll(1000, self =>
Utils.execAsync(['date', '+%a %b %d %I:%M %p'])
.then(date => self.label = date)),
})
/// NOTIFICATIONS ///
const Notification = () => Widget.Box({
class_name: 'notification',
visible: notifications.bind('popups').transform(p => p.length > 0),
children: [
Widget.Icon({
icon: 'preferences-system-notifications-symbolic',
}),
Widget.Label({
label: notifications.bind('popups').transform(p => p[0]?.summary || ''),
}),
],
})
/// PLAYER ///
const Media = () => Widget.Button({
class_name: 'media',
on_primary_click: () => mpris.getPlayer('')?.playPause(),
on_scroll_up: () => mpris.getPlayer('')?.next(),
on_scroll_down: () => mpris.getPlayer('')?.previous(),
child: Widget.Label('-').hook(mpris, self => {
if (mpris.players[0]) {
const { track_artists, track_title } = mpris.players[0]
self.label = `${track_artists.join(', ')} - ${track_title}`
} else {
self.label = 'Nothing is playing'
}
}, 'player-changed'),
})
/// VOLUME ///
console.log(audio.speaker)
const Volume = () => Widget.Button({
on_clicked: () => audio.speaker.is_muted = !audio.speaker.is_muted,
child: Widget.Icon().hook(audio.speaker, self => {
const icon = [
[101, 'overamplified'],
[67, 'high'],
[34, 'medium'],
[0, 'low'],
].find(([threshold]) => threshold <= audio.speaker.volume * 100)?.[1]
self.icon = `audio-volume-${icon}-symbolic`
self.tooltip_text = `Volume ${Math.floor(audio.speaker.volume * 100)}%`
}),
})
/// BATTERY ///
const Battery = () => Widget.Box({
spacing: 4,
class_name: battery.bind('charging').transform(c => c ? 'charging' : ''),
visible: battery.bind('available'),
children: [
// Battery icon
Widget.Icon({
icon: battery.bind('percent').transform(p => `battery-level-${Math.floor(p / 10) * 10}-symbolic`),
}),
// Battery discharge wattage
Widget.Label({
label: battery.bind('energy-rate').transform(e => `${Math.round(e)}W`),
}),
],
})
/// TRAY ///
const SysTray = () => Widget.Box({
children: systemtray.bind('items').transform(items => {
return items.map(item => Widget.Button({
child: Widget.Icon({ binds: [['icon', item, 'icon']] }),
on_primary_click: (_, event) => item.activate(event),
on_secondary_click: (_, event) => item.openMenu(event),
binds: [['tooltip-markup', item, 'tooltip-markup']],
}))
}),
})
/// LAYOUT ///
const Left = () => Widget.Box({
spacing: 8,
children: [
Workspaces(),
],
})
const Center = () => Widget.Box({
spacing: 8,
children: [
Clock(),
Notification(),
],
})
const Right = () => Widget.Box({
hpack: 'end',
spacing: 8,
children: [
Media(),
SysTray(),
Volume(),
Battery(),
],
})
const Bar = (monitor = 0) => Widget.Window({
monitor,
name: `bar${monitor}`,
class_name: 'bar',
anchor: ['top', 'left', 'right'],
exclusivity: 'exclusive',
child: Widget.EventBox({
on_scroll_up: () => audio['speaker'].volume = audio['speaker'].volume + 1,
on_scroll_down: () => audio['speaker'].volume = audio['speaker'].volume + 1,
child: Widget.CenterBox({
spacing: 8,
start_widget: Left(),
center_widget: Center(),
end_widget: Right(),
}),
})
})
/// EXPORTS ///
export default {
style: './style.css',
windows: [Bar()],
}