nosignal-shell/modules/lock/Media.qml
2026-05-07 17:13:53 +10:00

142 lines
3.8 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell
import Caelestia.Components
import Caelestia.Config
import qs.components
import qs.components.controls
import qs.components.effects
import qs.services
Item {
id: root
required property var lock
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: layout.implicitHeight
Image {
anchors.fill: parent
source: Players.getArtUrl(Players.active)
asynchronous: true
fillMode: Image.PreserveAspectCrop
sourceSize: {
const dpr = (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1;
return Qt.size(width * dpr, height * dpr);
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: mask
}
opacity: status === Image.Ready ? 1 : 0
Behavior on opacity {
Anim {
type: Anim.StandardExtraLarge
}
}
}
Rectangle {
id: mask
anchors.fill: parent
layer.enabled: true
visible: false
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
position: 0
color: Qt.rgba(0, 0, 0, 0.5)
}
GradientStop {
position: 0.4
color: Qt.rgba(0, 0, 0, 0.2)
}
GradientStop {
position: 0.8
color: Qt.rgba(0, 0, 0, 0)
}
}
}
ColumnLayout {
id: layout
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Tokens.padding.medium
StyledText {
Layout.topMargin: Tokens.padding.medium
Layout.bottomMargin: Tokens.spacing.large
text: qsTr("Now playing")
color: Colours.palette.m3onSurfaceVariant
font: Tokens.font.label.builders.medium.weight(Font.DemiBold).vaxis("slnt", -4).build()
}
StyledText {
Layout.fillWidth: true
animate: true
text: Players.active?.trackArtist ?? qsTr("No media")
color: Colours.palette.m3primary
horizontalAlignment: Text.AlignHCenter
font: Tokens.font.body.builders.large.weight(Font.DemiBold).build()
elide: Text.ElideRight
}
StyledText {
Layout.fillWidth: true
animate: true
text: Players.active?.trackTitle ?? qsTr("No media")
horizontalAlignment: Text.AlignHCenter
font: Tokens.font.title.medium
elide: Text.ElideRight
}
ButtonRow {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.medium
Layout.bottomMargin: Tokens.padding.extraLarge
spacing: Tokens.spacing.extraSmall
IconButton {
type: IconButton.Tonal
icon: "skip_previous"
isRound: true
shapeMorph: true
disabled: !Players.active?.canGoPrevious
onClicked: Players.active?.previous()
}
IconButton {
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
isRound: true
shapeMorph: true
checked: Players.active?.isPlaying ?? false
disabled: !Players.active?.canTogglePlaying
onClicked: Players.active?.togglePlaying()
implicitWidth: implicitHeight + Tokens.padding.large * 2
}
IconButton {
type: IconButton.Tonal
icon: "skip_next"
isRound: true
shapeMorph: true
disabled: !Players.active?.canGoNext
onClicked: Players.active?.next()
}
}
}
}