Compare commits
2 commits
dddbb82984
...
191222aa31
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
191222aa31 | ||
|
|
2d6cb05015 |
4 changed files with 111 additions and 93 deletions
|
|
@ -8,73 +8,76 @@ import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell.Services.Mpris
|
import Quickshell.Services.Mpris
|
||||||
|
|
||||||
ColumnLayout {
|
Loader {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property MprisPlayer player
|
required property MprisPlayer player
|
||||||
|
|
||||||
spacing: 12
|
active: player != null
|
||||||
|
|
||||||
implicitWidth: 800
|
sourceComponent: ColumnLayout {
|
||||||
|
spacing: 12
|
||||||
|
implicitWidth: 800
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: text
|
id: text
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: `${root.player.trackTitle} - ${root.player.trackArtist}`
|
text: `${root.player.trackTitle} - ${root.player.trackArtist}`
|
||||||
font.pixelSize: Dimensions.mpris.fontSize
|
font.pixelSize: Dimensions.mpris.fontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
StyledIconButton {
|
StyledIconButton {
|
||||||
id: backButton
|
id: backButton
|
||||||
text: Icons.skipBack
|
text: Icons.skipBack
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.player.previous();
|
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 {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: {
|
text: {
|
||||||
function formatTime(num) {
|
function formatTime(num) {
|
||||||
return Math.floor(num).toString().padStart(2, "0");
|
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
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
StyledSlider {
|
||||||
running: root.player.isPlaying
|
from: 0
|
||||||
interval: 1000
|
to: root.player.length ?? 0
|
||||||
repeat: true
|
value: root.player.position
|
||||||
onTriggered: root.player.positionChanged()
|
implicitHeight: 6
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onMoved: {
|
||||||
|
root.player.position = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: root.player.isPlaying
|
||||||
|
interval: 1000
|
||||||
|
repeat: true
|
||||||
|
onTriggered: root.player.positionChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
52
components/MprisPlayerSelector.qml
Normal file
52
components/MprisPlayerSelector.qml
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
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: {
|
||||||
|
if (!Mpris.active) {
|
||||||
|
return "inactive";
|
||||||
|
}
|
||||||
|
const player = Mpris.active;
|
||||||
|
const displayName = player.identity ?? player.desktopEntry ?? player.dbusName ?? "unknown";
|
||||||
|
if (displayName.toLowerCase().includes('tidal')) {
|
||||||
|
return "Tidal";
|
||||||
|
}
|
||||||
|
if (displayName.toLowerCase().includes('zen')) {
|
||||||
|
return "Zen";
|
||||||
|
}
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
font.pixelSize: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledIconButton {
|
||||||
|
id: nextPlayerButton
|
||||||
|
|
||||||
|
visible: Mpris.players.length > 1
|
||||||
|
text: Icons.chevronRight
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Mpris.nextPlayer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.constants
|
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.widgets
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
|
@ -16,44 +14,9 @@ StyledDrawer {
|
||||||
margin: 32
|
margin: 32
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
RowLayout {
|
|
||||||
spacing: 8
|
|
||||||
|
|
||||||
|
MprisPlayerSelector {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
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 {
|
MprisController {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property list<MprisPlayer> players: Mpris.players.values
|
property list<MprisPlayer> players: Mpris.players.values
|
||||||
property MprisPlayer active: players[properties.currentIndex]
|
property MprisPlayer active: players[properties.currentIndex] ?? null
|
||||||
|
|
||||||
PersistentProperties {
|
PersistentProperties {
|
||||||
id: properties
|
id: properties
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue