66 lines
1.7 KiB
QML
66 lines
1.7 KiB
QML
pragma Singleton
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Services.Mpris
|
|
|
|
Singleton {
|
|
readonly property list<MprisPlayer> activePlayers: Mpris.players.values
|
|
readonly property var meaningfulPlayers: filterDuplicatePlayers(activePlayers)
|
|
readonly property bool hasPlayers: meaningfulPlayers.length > 0
|
|
property int playerIndex: 0
|
|
|
|
function activePlayer() {
|
|
if (!hasPlayers) {
|
|
return null;
|
|
}
|
|
assertIndex();
|
|
return meaningfulPlayers[playerIndex];
|
|
}
|
|
|
|
function shiftPlayer(shift) {
|
|
playerIndex = (playerIndex + shift + activePlayers.length) % activePlayers.length
|
|
}
|
|
|
|
function assertIndex() {
|
|
if (playerIndex < 0 || playerIndex >= meaningfulPlayers.length) {
|
|
playerIndex = (playerIndex + activePlayers.length) % activePlayers.length
|
|
}
|
|
}
|
|
|
|
function filterDuplicatePlayers(players) {
|
|
let filtered = [];
|
|
let used = new Set();
|
|
|
|
for (let i = 0; i < players.length; ++i) {
|
|
if (used.has(i)) {
|
|
continue;
|
|
}
|
|
let p1 = players[i];
|
|
let group = [i];
|
|
|
|
// find duplicates
|
|
for (let j = i + 1; j < players.length; ++j) {
|
|
let p2 = players[j];
|
|
if (p1.trackTitle && p2.trackTitle && (
|
|
p1.trackTitle.includes(p2.trackTitle) ||
|
|
p2.trackTitle.includes(p1.trackTitle) ||
|
|
(p1.position - p2.position <= 2 && p1.length - p2.length <= 2)
|
|
)) {
|
|
group.push(j);
|
|
}
|
|
}
|
|
|
|
// pick with non-empty trackArtUrl
|
|
|
|
let chosenIdx = group.find(idx => players[idx].trackArtUrl && players[idx].trackArtUrl.length > 0);
|
|
if (chosenIdx === undefined) {
|
|
chosenIdx = group[0];
|
|
}
|
|
|
|
filtered.push(players[chosenIdx]);
|
|
group.forEach(idx => used.add(idx));
|
|
}
|
|
return filtered;
|
|
}
|
|
} |