diff --git a/devices/wim/config/ags/js/media-player/mpris.js b/devices/wim/config/ags/js/media-player/mpris.js index 07bbee43..bd215397 100644 --- a/devices/wim/config/ags/js/media-player/mpris.js +++ b/devices/wim/config/ags/js/media-player/mpris.js @@ -1,8 +1,9 @@ import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js'; import { Button, Icon, Label, Stack, Slider, CenterBox, Box } from 'resource:///com/github/Aylur/ags/widget.js'; -import { execAsync, lookUpIcon, readFileAsync } from 'resource:///com/github/Aylur/ags/utils.js'; +import { execAsync, lookUpIcon, interval, readFileAsync } from 'resource:///com/github/Aylur/ags/utils.js'; import Gdk from 'gi://Gdk'; +import GLib from 'gi://GLib'; const display = Gdk.Display.get_default(); import Separator from '../misc/separator.js'; @@ -33,13 +34,30 @@ export const CoverArt = (player, props) => CenterBox({ ...props, vertical: true, properties: [['bgStyle', '']], - connections: [[player, self => { - // Don't show players that don't have covers + setup: self => { + // Give temp cover art readFileAsync(player.coverPath).catch(() => { - if (!player.colors.value && !player.trackCoverUrl) - player.colors.value = 'delete'; - }); + if (!player.colors.value && !player.trackCoverUrl) { + player.colors.value = { + 'imageAccent': '#9d4141', + 'buttonAccent': '#ffdad6', + 'buttonText': '#400005', + 'hoverAccent': '#ffb3b0', + }; + self._bgStyle = ` + background: radial-gradient(circle, + rgba(0, 0, 0, 0.4) 30%, + ${player.colors.value.imageAccent}), + rgb(0, 0, 0); + background-size: cover; + background-position: center; + `; + self.setStyle(self._bgStyle); + } + }); + }, + connections: [[player, self => { execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] && coloryou "${player.coverPath}" | grep -v Warning`]) .then(out => { @@ -99,17 +117,15 @@ export const PlayerIcon = (player, { symbolic = true, ...props } = {}) => { const widget = Box({}); var overlay; - const interval = setInterval(() => { - if (player.colors.value === 'delete') { - interval.destroy(); - } - else if (player.colors.value && player.trackCoverUrl) { + const source = interval(100, () => { + if (player.colors.value) { overlay = widget.get_parent().get_parent().get_parent(); updateIcons(); - Mpris.connect('changed', updateIcons); - interval.destroy(); + overlay._mprisConnections.set(player.busName, Mpris.connect('changed', updateIcons)); + + GLib.source_remove(source); } - }, 100); + }); const updateIcons = () => { const overlays = overlay.list(); @@ -166,7 +182,7 @@ export const PositionSlider = (player, props) => EventBox({ [1000, s => s._update(s)], [player.colors, s => { const c = player.colors.value; - if (c && c != 'delete') { + if (player.colors.value) { s.setCss(`highlight { background-color: ${c.buttonAccent}; } slider { background-color: ${c.buttonAccent}; } slider:hover { background-color: ${c.hoverAccent}; } @@ -252,7 +268,7 @@ const PlayerButton = ({ player, items, onClick, prop }) => Button({ if (!Mpris.players.find(p => player === p)) return; - if (player.colors.value && player.colors.value != 'delete') { + if (player.colors.value) { if (prop == 'playBackStatus') { if (button._hovered) { items.forEach(item => { diff --git a/devices/wim/config/ags/js/media-player/player.js b/devices/wim/config/ags/js/media-player/player.js index 0e56a764..613e92ba 100644 --- a/devices/wim/config/ags/js/media-player/player.js +++ b/devices/wim/config/ags/js/media-player/player.js @@ -93,14 +93,15 @@ export default () => Box({ child: PlayerGesture({ properties: [ ['players', new Map()], + ['mprisConnections', new Map()], ['setup', false], - ['selected'], ], connections: [ [Mpris, (overlay, busName) => { if (overlay._players.has(busName)) return; + // Sometimes the signal doesn't give the busName if (!busName) { const player = Mpris.players.find(p => !overlay._players.has(p.busName)); if (player) @@ -109,23 +110,17 @@ export default () => Box({ return; } + // Get the one on top so it stays there + var previousFirst = overlay.get_children().at(-1); + for (const [key, value] of overlay._players.entries()) { + if (value === previousFirst) { + previousFirst = key; + break; + } + } + const player = Mpris.getPlayer(busName); player.colors = Variable(); - const id = player.colors.connect('changed', () => { - if (!overlay._players.has(busName)) - return; - if (player.colors.value === 'delete') { - overlay._players.delete(busName); - - const result = []; - overlay._players.forEach(widget => { - result.push(widget); - }); - - overlay.overlays = result; - } - player.colors.disconnect(id); - }); overlay._players.set(busName, PlayerBox(player)); @@ -139,13 +134,13 @@ export default () => Box({ // Select favorite player at startup if (!overlay._setup) { if (overlay._players.has(FAVE_PLAYER)) - overlay._selected = overlay._players.get(FAVE_PLAYER); + overlay.reorder_overlay(overlay._players.get(FAVE_PLAYER), -1); overlay._setup = true; } - - if (overlay._selected) - overlay.reorder_overlay(overlay._selected, -1); + else { + overlay.reorder_overlay(overlay._players.get(previousFirst), -1); + } }, 'player-added'], @@ -153,7 +148,18 @@ export default () => Box({ if (!busName || !overlay._players.has(busName)) return; + // Get the one on top so it stays there + var previousFirst = overlay.get_children().at(-1); + for (const [key, value] of overlay._players.entries()) { + if (value === previousFirst) { + previousFirst = key; + break; + } + } + overlay._players.delete(busName); + Mpris.disconnect(overlay._mprisConnections.get(busName)); + overlay._mprisConnections.delete(busName); const result = []; overlay._players.forEach(widget => { @@ -161,8 +167,9 @@ export default () => Box({ }); overlay.overlays = result; - if (overlay._selected) - overlay.reorder_overlay(overlay._selected, -1); + + if (overlay._players.has(previousFirst)) + overlay.reorder_overlay(overlay._players.get(previousFirst), -1); }, 'player-closed'], ], }),