From 2d6cb0501512602d335d20ee00c1d30c79b851c3 Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Sun, 31 Aug 2025 15:48:14 -0400 Subject: [PATCH] fix mpris errors and create player selector --- components/MprisController.qml | 111 ++++++++++++------------ components/MprisPlayerSelector.qml | 46 ++++++++++ modules/drawers/dashboard/Dashboard.qml | 39 +-------- services/Mpris.qml | 2 +- 4 files changed, 105 insertions(+), 93 deletions(-) create mode 100644 components/MprisPlayerSelector.qml diff --git a/components/MprisController.qml b/components/MprisController.qml index 9303bed..9b92b0a 100644 --- a/components/MprisController.qml +++ b/components/MprisController.qml @@ -8,73 +8,76 @@ import QtQuick import QtQuick.Layouts import Quickshell.Services.Mpris -ColumnLayout { +Loader { id: root required property MprisPlayer player - spacing: 12 + active: player != null - implicitWidth: 800 + sourceComponent: ColumnLayout { + spacing: 12 + implicitWidth: 800 - StyledText { - id: text - Layout.alignment: Qt.AlignHCenter - text: `${root.player.trackTitle} - ${root.player.trackArtist}` - font.pixelSize: Dimensions.mpris.fontSize - } + StyledText { + id: text + Layout.alignment: Qt.AlignHCenter + text: `${root.player.trackTitle} - ${root.player.trackArtist}` + font.pixelSize: Dimensions.mpris.fontSize + } - RowLayout { - Layout.alignment: Qt.AlignHCenter - StyledIconButton { - id: backButton - text: Icons.skipBack - onClicked: { - root.player.previous(); + RowLayout { + Layout.alignment: Qt.AlignHCenter + StyledIconButton { + id: backButton + text: Icons.skipBack + onClicked: { + root.player.previous(); + } + } + StyledIconButton { + id: playPauseButton + text: root.player.isPlaying ? Icons.pause : Icons.play + onClicked: { + root.player.isPlaying = !root.player.isPlaying; + } + } + StyledIconButton { + id: forwardButton + text: Icons.skipForward + onClicked: { + root.player.next(); + } } } - StyledIconButton { - id: playPauseButton - text: root.player.isPlaying ? Icons.pause : Icons.play - onClicked: { - root.player.isPlaying = !root.player.isPlaying; - } - } - StyledIconButton { - id: forwardButton - text: Icons.skipForward - onClicked: { - root.player.next(); - } - } - } - StyledText { - Layout.alignment: Qt.AlignHCenter - text: { - function formatTime(num) { - return Math.floor(num).toString().padStart(2, "0"); + StyledText { + Layout.alignment: Qt.AlignHCenter + text: { + function formatTime(num) { + return Math.floor(num).toString().padStart(2, "0"); + } + return `${formatTime(root.player.position / 60)}:${formatTime(root.player.position % 60)} - ${formatTime(root.player.length / 60)}:${formatTime(root.player.length % 60)}`; } - return `${formatTime(root.player.position / 60)}:${formatTime(root.player.position % 60)} - ${formatTime(root.player.length / 60)}:${formatTime(root.player.length % 60)}`; - } - font.pixelSize: Dimensions.mpris.fontSize - } - - StyledSlider { - from: 0 - to: root.player.length ?? 0 - value: root.player.position - implicitHeight: 6 - Layout.fillWidth: true - onMoved: { - root.player.position = value; + font.pixelSize: Dimensions.mpris.fontSize } - Timer { - running: root.player.isPlaying - interval: 1000 - repeat: true - onTriggered: root.player.positionChanged() + StyledSlider { + from: 0 + to: root.player.length ?? 0 + value: root.player.position + implicitHeight: 6 + Layout.fillWidth: true + onMoved: { + root.player.position = value; + } + + Timer { + running: root.player.isPlaying + interval: 1000 + repeat: true + onTriggered: root.player.positionChanged() + } } } } diff --git a/components/MprisPlayerSelector.qml b/components/MprisPlayerSelector.qml new file mode 100644 index 0000000..da3196b --- /dev/null +++ b/components/MprisPlayerSelector.qml @@ -0,0 +1,46 @@ +import qs.components +import qs.constants +import qs.services +import qs.widgets +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 8 + + Layout.alignment: Qt.AlignHCenter + + StyledIconButton { + id: previousPlayerButton + + visible: Mpris.players.length > 1 + text: Icons.chevronLeft + + onClicked: { + Mpris.previousPlayer(); + } + } + + StyledText { + text: { + function parseName(name) { + const words = name.split("-"); + const capitalized = words.map(val => val.trim().charAt(0).toUpperCase() + val.trim().slice(1)); + return capitalized.join(" "); + } + return parseName(Mpris.active?.desktopEntry ?? Mpris.active?.dbusName ?? "unknown"); + } + font.pixelSize: 20 + } + + StyledIconButton { + id: nextPlayerButton + + visible: Mpris.players.length > 1 + text: Icons.chevronRight + + onClicked: { + Mpris.nextPlayer(); + } + } +} diff --git a/modules/drawers/dashboard/Dashboard.qml b/modules/drawers/dashboard/Dashboard.qml index 6bbaafe..b98647d 100644 --- a/modules/drawers/dashboard/Dashboard.qml +++ b/modules/drawers/dashboard/Dashboard.qml @@ -1,9 +1,7 @@ pragma ComponentBehavior: Bound import qs.components -import qs.constants import qs.services -import qs.widgets import QtQuick import QtQuick.Layouts @@ -16,44 +14,9 @@ StyledDrawer { margin: 32 ColumnLayout { spacing: 8 - RowLayout { - spacing: 8 + MprisPlayerSelector { Layout.alignment: Qt.AlignHCenter - - StyledIconButton { - id: previousPlayerButton - - visible: Mpris.players.length > 1 - text: Icons.chevronLeft - - onClicked: { - Mpris.previousPlayer(); - } - } - - StyledText { - text: { - if (Mpris.active?.identity) { - const words = Mpris.active?.identity.split("-"); - const capitalized = words.map(val => String(val).charAt(0).toUpperCase() + String(val).slice(1)); - return capitalized.join(" "); - } - return Mpris.active?.desktopEntry ?? Mpris.active?.dbusName ?? "unknown"; - } - font.pixelSize: 20 - } - - StyledButton { - id: nextPlayerButton - visible: Mpris.players.length > 1 - - text: Icons.chevronRight - - onClicked: { - Mpris.nextPlayer(); - } - } } MprisController { diff --git a/services/Mpris.qml b/services/Mpris.qml index 2abc69d..d95161f 100644 --- a/services/Mpris.qml +++ b/services/Mpris.qml @@ -8,7 +8,7 @@ Singleton { id: root property list players: Mpris.players.values - property MprisPlayer active: players[properties.currentIndex] + property MprisPlayer active: players[properties.currentIndex] ?? null PersistentProperties { id: properties