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, }) }