summaryrefslogtreecommitdiffstats
path: root/quickshell/modules/bar/Music.qml
diff options
context:
space:
mode:
Diffstat (limited to 'quickshell/modules/bar/Music.qml')
-rw-r--r--quickshell/modules/bar/Music.qml237
1 files changed, 237 insertions, 0 deletions
diff --git a/quickshell/modules/bar/Music.qml b/quickshell/modules/bar/Music.qml
new file mode 100644
index 0000000..50e1cf1
--- /dev/null
+++ b/quickshell/modules/bar/Music.qml
@@ -0,0 +1,237 @@
+import QtQuick
+import QtQuick.Layouts
+import Quickshell
+import Quickshell.Services.Mpris
+import "../../config.js" as Config
+
+Rectangle {
+ id: musicBlock
+
+ property var player: null
+ property var supportedPlayers: ["feishin", "fooyin"]
+
+ implicitWidth: visible
+ ? Math.min(textMetrics.width + Config.blockPadding + 8, 400)
+ : 0
+
+ implicitHeight: Config.blockHeight
+
+ radius: Config.blockRadius
+
+ visible: player !== null && player.isPlaying
+
+ function isSupported(p) {
+ var identity = (p.identity || "").toLowerCase()
+ var desktopEntry = (p.desktopEntry || "").toLowerCase()
+
+ for (var i = 0; i < supportedPlayers.length; i++) {
+ var name = supportedPlayers[i]
+
+ if (
+ identity === name ||
+ desktopEntry === name ||
+ desktopEntry.endsWith("." + name)
+ )
+ return true
+ }
+
+ return false
+ }
+
+ function findPlayer() {
+ var fallback = null
+
+ for (var i = 0; i < Mpris.players.values.length; i++) {
+ var p = Mpris.players.values[i]
+
+ console.log(
+ "MPRIS:",
+ "identity =", p.identity,
+ "desktopEntry =", p.desktopEntry
+ )
+
+ if (!isSupported(p))
+ continue
+
+ if (p.isPlaying) {
+ player = p
+ return
+ }
+
+ if (!fallback)
+ fallback = p
+ }
+
+ player = fallback
+ }
+
+ function cleanTitle(title) {
+ if (!title)
+ return ""
+
+ return title
+ .replace(/\s*[\(\[][^)\]]*\blive\b[^)\]]*[\)\]]/gi, "")
+ .replace(/\s*[-–—]\s*\blive\b.*$/i, "")
+ .trim()
+ }
+
+ Component.onCompleted: {
+ findPlayer()
+ }
+
+ Connections {
+ target: Mpris.players
+
+ function onValuesChanged() {
+ findPlayer()
+ }
+ }
+
+ gradient: Gradient {
+ GradientStop {
+ id: stop1
+ position: 0.0
+ color: Config.accentGreen
+ }
+
+ GradientStop {
+ id: stop2
+ position: 0.33
+ color: Config.accentYellow
+ }
+
+ GradientStop {
+ id: stop3
+ position: 0.66
+ color: Config.accentOrange
+ }
+
+ GradientStop {
+ id: stop4
+ position: 1.0
+ color: Config.accentRed
+ }
+ }
+
+ TextMetrics {
+ id: textMetrics
+
+ font.family: Config.fontFamily
+ font.pixelSize: Config.fontSize
+ font.bold: true
+
+ text: player
+ ? "󰎇 " + player.trackArtist + " — " + cleanTitle(player.trackTitle)
+ : ""
+ }
+
+ Text {
+ id: musicText
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+
+ leftPadding: Config.blockPadding / 2
+ rightPadding: Config.blockPadding / 2
+
+ text: player
+ ? "󰎇 " + player.trackArtist + " — " + cleanTitle(player.trackTitle)
+ : ""
+
+ color: Config.textDark
+
+ font.family: Config.fontFamily
+ font.pixelSize: Config.fontSize
+ font.bold: true
+
+ elide: Text.ElideRight
+ maximumLineCount: 1
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ cursorShape: Qt.PointingHandCursor
+
+ onClicked: {
+ if (player && player.canRaise)
+ player.raise()
+ }
+ }
+
+ SequentialAnimation {
+ running: true
+ loops: Animation.Infinite
+
+ ParallelAnimation {
+ ColorAnimation {
+ target: stop1
+ property: "color"
+ from: Config.accentGreen
+ to: Config.accentRed
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop2
+ property: "color"
+ from: Config.accentYellow
+ to: Config.accentGreen
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop3
+ property: "color"
+ from: Config.accentOrange
+ to: Config.accentYellow
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop4
+ property: "color"
+ from: Config.accentRed
+ to: Config.accentOrange
+ duration: Config.gradientAnimationDuration
+ }
+ }
+
+ ParallelAnimation {
+ ColorAnimation {
+ target: stop1
+ property: "color"
+ from: Config.accentRed
+ to: Config.accentGreen
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop2
+ property: "color"
+ from: Config.accentGreen
+ to: Config.accentYellow
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop3
+ property: "color"
+ from: Config.accentYellow
+ to: Config.accentOrange
+ duration: Config.gradientAnimationDuration
+ }
+
+ ColorAnimation {
+ target: stop4
+ property: "color"
+ from: Config.accentOrange
+ to: Config.accentRed
+ duration: Config.gradientAnimationDuration
+ }
+ }
+ }
+}