aboutsummaryrefslogtreecommitdiff
path: root/modules/system/quickshell/Media.qml
diff options
context:
space:
mode:
Diffstat (limited to 'modules/system/quickshell/Media.qml')
-rw-r--r--modules/system/quickshell/Media.qml119
1 files changed, 119 insertions, 0 deletions
diff --git a/modules/system/quickshell/Media.qml b/modules/system/quickshell/Media.qml
new file mode 100644
index 0000000..ee5bf42
--- /dev/null
+++ b/modules/system/quickshell/Media.qml
@@ -0,0 +1,119 @@
+import QtQuick
+import QtQuick.Layouts
+import Quickshell
+import Quickshell.Services.Mpris
+
+Item {
+ id: root
+
+ property QtObject manualExpandedPlayer: null
+
+ readonly property var activePlayers: Mpris.players?.values || []
+
+ readonly property var expandedPlayer: {
+ if (root.manualExpandedPlayer !== null && root.activePlayers.includes(root.manualExpandedPlayer)) {
+ return root.manualExpandedPlayer;
+ }
+ for (const player of root.activePlayers) {
+ if (player.playbackState === MprisPlaybackState.Playing) {
+ return player;
+ }
+ }
+ if (root.activePlayers.length > 0) {
+ return root.activePlayers[0];
+ }
+ return null;
+ }
+
+ width: childrenRect.width
+ height: parent.height
+
+ Row {
+ anchors.verticalCenter: parent.verticalCenter
+
+ MusicVisualizer {
+ active: root.expandedPlayer?.playbackState === MprisPlaybackState.Playing
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: GlobalState.toggle("Media")
+ }
+
+ PopupWindow {
+ id: popup
+ visible: GlobalState.activePopup === "Media"
+ grabFocus: true
+ implicitWidth: card.width
+ implicitHeight: card.height
+
+ anchor {
+ window: barWindow
+ item: root
+ edges: Edges.Bottom
+ gravity: Edges.Bottom
+ margins.top: Theme.popupGap
+ }
+
+ color: Theme.transparent
+
+ PopupCard {
+ id: card
+ width: 320
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 0
+ Layout.margins: 8
+
+ Repeater {
+ model: root.activePlayers.length > 0 ? root.activePlayers : [null]
+
+ delegate: Item {
+ id: playerDelegate
+ Layout.fillWidth: true
+ implicitHeight: mediaCard.implicitHeight + (separator.visible ? separator.height + 16 : 0)
+
+ required property var modelData
+ required property int index
+
+ readonly property bool isEmpty: modelData === null
+ readonly property bool isExpanded: root.expandedPlayer === modelData && !isEmpty
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 16
+
+ MediaCard {
+ id: mediaCard
+ Layout.fillWidth: true
+ player: playerDelegate.modelData
+ isExpanded: playerDelegate.isExpanded
+
+ onClicked: {
+ if (!playerDelegate.isEmpty) {
+ root.manualExpandedPlayer = playerDelegate.modelData;
+ } else {
+ Quickshell.execDetached(["spotify"]);
+ }
+ }
+ }
+
+ Rectangle {
+ id: separator
+ Layout.fillWidth: true
+ height: 1
+ color: Theme.border
+ opacity: 0.3
+ visible: !playerDelegate.isEmpty && playerDelegate.index < root.activePlayers.length - 1
+ Layout.topMargin: 4
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}