Files
Olympus/home-manager/nathan/dotfiles/ags/media.js

142 lines
4.8 KiB
JavaScript
Executable File

const mpris = await Service.import("mpris")
export default function Media() {
const track = Utils.watch("", mpris, "player-changed", () => {
if (mpris.players[0]) {
const { track_artists, track_title } = mpris.players[0]
return `${track_artists.join(", ")} -${track_title}`
} else {
return "Nothing is playing"
}
})
return Widget.EventBox({
class_name: "media",
on_primary_click: () => mpris.getPlayer("")?.playPause(),
on_scroll_up: () => mpris.getPlayer("")?.next(),
on_scroll_down: () => mpris.getPlayer("")?.previous(),
child: Widget.Icon({icon: 'emblem-music-symbolic'}),
})
}
function PlayerImg(player) {
return Widget.Box({
hpack: "start",
width_request: 80,
height_request: 80,
css: player.bind("track_cover_url").transform(p => `
background-image: url('${p || player.cover_path || '/home/nathan/Pictures/symbols/audio.png'}');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
`),
})
}
function PlayerGUI(player) {
return Widget.Box({
class_name: "playerbox",
height_request: 200,
vexpand: false,
vertical: true,
children: [
Widget.Box({
vertical: false,
margin: 15,
hpack: "start",
spacing: 20,
children: [
PlayerImg(player),
Widget.Box({
vertical: true,
children: [
Widget.Label({
hpack: "start",
max_width_chars: 30,
truncate: "end",
label: player.bind('track-title').as(t => t)
}),
Widget.Label({
hpack: "start",
max_width_chars: 30,
truncate: "end",
label: player.bind("track_artists").transform(a => a.join(", ")),
wrap: true,
}),
Widget.Label({
hpack: "start",
max_width_chars: 30,
truncate: "end",
label: player.bind('track-album').as(t => t)
}),
]
})
],
}),
Widget.Slider({
class_name: "position",
draw_value: false,
on_change: ({ value }) => player.position = value * player.length,
visible: player.bind("length").as(l => l > 0),
setup: self => {
function update() {
const value = player.position / player.length
self.value = value > 0 ? value : 0
}
self.hook(player, update)
self.hook(player, update, "position")
self.poll(1000, update)
},
}),
Widget.Box({
vertical: false,
hpack: "center",
spacing: 20,
children: [
Widget.Button({
child: Widget.Icon({ icon: 'media-skip-backward-symbolic'}),
on_primary_click: () => player.previous()
}),
Widget.Button({
child: Widget.Icon({ icon: player.bind("play_back_status").transform(s => {
switch (s) {
case "Playing": return 'media-playback-pause-symbolic'
case "Paused":
case "Stopped": return 'media-playback-start-symbolic'
}
}),
}),
on_primary_click: () => player.playPause(),
}),
Widget.Button({
child: Widget.Icon({ icon: 'media-skip-forward-symbolic'}),
on_primary_click: () => player.next()
})
]
})
],
setup: self => {
},
})
}
export function Players() {
const plrs = mpris.bind('players')
.as(p => p.map((v) => PlayerGUI(v)))
return Widget.Box({
vertical: true,
children: plrs,
})
}