mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-18 09:14:01 -04:00
170 lines
5.1 KiB
QML
170 lines
5.1 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.DCommon.Widgets
|
|
import qs.Modules.DDash
|
|
|
|
DBottomSheet {
|
|
id: root
|
|
|
|
required property var player
|
|
property string displayedPanel: ""
|
|
readonly property string requestedPanel: player.panel
|
|
readonly property var sinks: root.active ? AudioService.getAvailableSinks() : []
|
|
readonly property var players: root.active ? (root.player.allPlayers || []).filter(p => p && (p === root.player.activePlayer || !MprisController.isIdle(p))) : []
|
|
|
|
opened: root.player.live && requestedPanel !== ""
|
|
initialFocusItem: panelLoader.item?.focusTarget ?? null
|
|
maximumWidth: DashMetrics.optionSheetWidth
|
|
title: {
|
|
switch (displayedPanel) {
|
|
case "volume":
|
|
return root.player.usePlayerVolume ? I18n.tr("Media volume") : I18n.tr("Volume");
|
|
case "devices":
|
|
return I18n.tr("Play on", "Audio output selection sheet title");
|
|
case "players":
|
|
return I18n.tr("Players", "Media player selection");
|
|
}
|
|
return "";
|
|
}
|
|
onRequestedPanelChanged: {
|
|
if (requestedPanel !== "")
|
|
displayedPanel = requestedPanel;
|
|
}
|
|
onDismissRequested: root.player.panel = ""
|
|
|
|
Keys.onPressed: event => {
|
|
if (displayedPanel !== "volume" || !root.player.volumeAvailable) {
|
|
event.accepted = handleKeyEvent(event);
|
|
return;
|
|
}
|
|
switch (event.key) {
|
|
case Qt.Key_K:
|
|
root.player.adjustVolume(AudioService.wheelVolumeStep);
|
|
break;
|
|
case Qt.Key_J:
|
|
root.player.adjustVolume(-AudioService.wheelVolumeStep);
|
|
break;
|
|
case Qt.Key_M:
|
|
root.player.toggleMute();
|
|
break;
|
|
default:
|
|
event.accepted = handleKeyEvent(event);
|
|
return;
|
|
}
|
|
event.accepted = true;
|
|
}
|
|
|
|
Loader {
|
|
id: panelLoader
|
|
width: parent.width
|
|
active: root.active
|
|
sourceComponent: {
|
|
switch (root.displayedPanel) {
|
|
case "volume":
|
|
return volumePanel;
|
|
case "devices":
|
|
return devicesPanel;
|
|
case "players":
|
|
return playersPanel;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: volumePanel
|
|
|
|
Column {
|
|
readonly property Item focusTarget: volumeSlider
|
|
spacing: Theme.spacingM
|
|
|
|
StyledText {
|
|
width: parent.width
|
|
text: root.player.usePlayerVolume ? root.player.activePlayer?.identity ?? "" : AudioService.displayName(AudioService.sink)
|
|
color: Theme.onSurfaceVariant
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
MediaVolumeSlider {
|
|
id: volumeSlider
|
|
width: parent.width
|
|
volume: root.player.currentVolume
|
|
muted: root.player.usePlayerVolume ? volume === 0 : AudioService.sinkSilent
|
|
maximumVolume: root.player.maxVolumePercent
|
|
enabled: root.player.volumeAvailable
|
|
onVolumeChangedByUser: volume => root.player.setVolume(volume)
|
|
onMuteRequested: root.player.toggleMute()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: devicesPanel
|
|
|
|
Column {
|
|
spacing: Theme.spacingM
|
|
|
|
Repeater {
|
|
model: root.sinks
|
|
|
|
MediaDeviceRow {
|
|
required property var modelData
|
|
|
|
width: parent.width
|
|
node: modelData
|
|
selected: modelData === AudioService.sink
|
|
playing: !!root.player.presentation?.playing
|
|
onActivated: AudioService.setSink(modelData)
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
width: parent.width
|
|
visible: root.sinks.length === 0
|
|
text: I18n.tr("No output devices found")
|
|
color: Theme.onSurfaceVariant
|
|
wrapMode: Text.Wrap
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: playersPanel
|
|
|
|
Column {
|
|
spacing: Theme.spacingS
|
|
|
|
Repeater {
|
|
model: root.players
|
|
|
|
MediaPanelRow {
|
|
required property var modelData
|
|
|
|
width: parent.width
|
|
accent: root.player.accent
|
|
iconName: "music_note"
|
|
title: modelData?.identity ?? ""
|
|
subtitle: [modelData?.trackTitle, modelData?.trackArtist].filter(Boolean).join(" · ")
|
|
selected: modelData === root.player.activePlayer
|
|
onActivated: {
|
|
MprisController.setActivePlayer(modelData);
|
|
root.player.panel = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
width: parent.width
|
|
visible: root.players.length === 0
|
|
text: I18n.tr("No Active Players")
|
|
color: Theme.onSurfaceVariant
|
|
wrapMode: Text.Wrap
|
|
}
|
|
}
|
|
}
|
|
}
|