pragma ComponentBehavior: Bound import QtQuick import QtQuick.Effects import M3Shapes import qs.Helpers import qs.Effects import qs.Components import qs.Services Item { id: root property color fallbackColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) property bool hadPrevious readonly property alias shape: shape layer.enabled: true Behavior on fallbackColor { CAnim { } } layer.effect: MultiEffect { blurMax: 1 shadowColor: Colors.palette.m3outline shadowEnabled: true shadowOpacity: 0.3 } Item { id: shapeWrapper anchors.fill: parent layer.enabled: true opacity: root.fallbackColor.a MaterialShape { id: shape color: Qt.alpha(root.fallbackColor, 1) implicitSize: root.width shape: MaterialShape.Cookie12Sided Anim on rotation { duration: 23500 easing.type: Easing.Linear from: 360 loops: Animation.Infinite paused: !Players.active?.isPlaying running: true to: 0 } } } MaterialIcon { anchors.centerIn: parent animate: true color: Colors.palette.m3onSurfaceVariant grade: 200 opacity: image.status === Image.Null || image.status === Image.Error ? 1 : 0 text: image.status === Image.Error ? "broken_image" : "art_track" Behavior on opacity { Anim { type: Anim.DefaultEffects } } } Loader { active: opacity > 0 anchors.centerIn: parent asynchronous: true opacity: image.status === Image.Loading ? 1 : 0 Behavior on opacity { Anim { type: Anim.DefaultEffects } } sourceComponent: LoadingIndicator { color: Colors.palette.m3primaryContainer implicitSize: root.width * 0.3 } } FadeImage { id: image anchors.fill: parent layer.enabled: true source: Players.getArtUrl(Players.active) layer.effect: Mask { maskSource: shapeWrapper } } }