mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-28 22:17:48 -04:00
media: rebrand to Bento
popouts: instantly set empty input region on exit
This commit is contained in:
1 parent
4eb163538c
commit
17d52d3c88
18 files changed
+133
-93
No files matched your search
@@ -194,8 +194,6 @@ Singleton {
|
||||
readonly property real mediaCardMargin: Theme.spacingL
|
||||
readonly property real mediaArtSize: 150
|
||||
readonly property real mediaArtSizeDash: 336
|
||||
readonly property real mediaArtLowResRatio: 0.5
|
||||
readonly property real mediaArtLowResScale: 0.85
|
||||
readonly property real mediaArtSizeMaterial: 200
|
||||
readonly property real mediaArtRadius: Theme.cornerRadiusXL
|
||||
readonly property real mediaArtSoftRadiusRatio: 0.3
|
||||
@@ -204,12 +202,15 @@ Singleton {
|
||||
readonly property real mediaPlayWidthRatio: 1.5
|
||||
readonly property real mediaPlayWidthStep: 0.75
|
||||
readonly property real mediaTransportPressScale: 1.2
|
||||
readonly property real mediaDeviceNameWidthRatio: 0.42
|
||||
readonly property real accentSelectedAlpha: 0.2
|
||||
readonly property real groupIdleAlpha: 0.1
|
||||
readonly property int mediaPositionPollInterval: 1000
|
||||
readonly property int mediaVolumeEchoTimeout: 1500
|
||||
readonly property int mediaTransitionGraceInterval: 3000
|
||||
readonly property int mediaPlayerLossGraceInterval: 1500
|
||||
readonly property real mediaTextScrollSpeed: 40
|
||||
readonly property int mediaTextScrollStep: 30
|
||||
readonly property int mediaLyricsRequestTimeout: 16000
|
||||
readonly property int mediaLyricsLoadingDelay: 300
|
||||
readonly property real mediaLyricsPositionTolerance: 0.05
|
||||
|
||||
@@ -122,7 +122,7 @@ Singleton {
|
||||
"value": "slanted",
|
||||
"text": I18n.tr("Slanted", "Album artwork shape")
|
||||
}
|
||||
]), choice("titleFont", I18n.tr("Title font"), MediaOptions.defaultTitleFont, Theme.fontChoices), toggle("seekbar", I18n.tr("Show seekbar"), MediaOptions.defaults.seekbar), toggle("waveProgress", I18n.tr("Wave progress bars"), MediaOptions.defaults.waveProgress), toggle("albumArtBackdrop", I18n.tr("Album art backdrop"), MediaOptions.defaults.albumArtBackdrop), toggle("albumArtAccent", I18n.tr("Use album art accent"), MediaOptions.defaults.albumArtAccent), toggle("animatedArt", I18n.tr("Apple Music animated covers"), MediaOptions.defaults.animatedArt, I18n.tr("Sends the playing artist and album name to Apple")), toggle("lyrics", I18n.tr("Lyrics", "Media player lyrics button"), MediaOptions.defaults.lyrics, I18n.tr("Sends the playing track, artist and album name to enabled lyrics providers"))]
|
||||
]), choice("titleFont", I18n.tr("Title font"), MediaOptions.defaultTitleFont, Theme.fontChoices), toggle("deviceName", I18n.tr("Show device name", "Media player option that puts the audio output device name on its button"), MediaOptions.defaults.deviceName), toggle("seekbar", I18n.tr("Show seekbar"), MediaOptions.defaults.seekbar), toggle("waveProgress", I18n.tr("Wave progress bars"), MediaOptions.defaults.waveProgress), toggle("albumArtBackdrop", I18n.tr("Album art backdrop"), MediaOptions.defaults.albumArtBackdrop), toggle("albumArtAccent", I18n.tr("Use album art accent"), MediaOptions.defaults.albumArtAccent), toggle("animatedArt", I18n.tr("Apple Music animated covers"), MediaOptions.defaults.animatedArt, I18n.tr("Sends the playing artist and album name to Apple")), toggle("lyrics", I18n.tr("Lyrics", "Media player lyrics button"), MediaOptions.defaults.lyrics, I18n.tr("Sends the playing track, artist and album name to enabled lyrics providers"))]
|
||||
},
|
||||
{
|
||||
"id": "wallpaper",
|
||||
|
||||
+14
-11
@@ -12,27 +12,25 @@ MediaChromeBase {
|
||||
|
||||
readonly property bool compact: width < Theme.smallBreakpoint || halfWidth < headerHeight + controls.implicitHeight
|
||||
readonly property real halfWidth: Math.max(0, (width - padding * 2 - Theme.spacingXL) / 2)
|
||||
readonly property real bodyHeight: Math.max(0, height - padding * 2)
|
||||
// !TODO: expose this variant? playerPaneOpen false gives art beside lyrics, or art alone with hover transport
|
||||
readonly property bool playerPane: root.player.playerPaneOpen
|
||||
readonly property bool controlsColumn: playerPane
|
||||
readonly property bool lyricsColumn: root.player.lyricsOpen && !playerPane
|
||||
readonly property bool splitPanes: controlsColumn || lyricsColumn
|
||||
readonly property bool artTransport: !playerPane && !!root.presentation
|
||||
readonly property real naturalArtSize: Math.max(0, Math.min(artSize, compact ? width / 2 : halfWidth))
|
||||
readonly property real artworkSize: compact ? naturalArtSize : Math.max(naturalArtSize, Math.min(halfWidth, bodyHeight))
|
||||
readonly property real naturalArtSize: Math.round(Math.max(0, Math.min(artSize, compact ? width / 2 : halfWidth)))
|
||||
// Sized from the controls column, never from this item's own height: reading back the height
|
||||
// the artwork itself sets makes the split settle wherever the current track happened to put it.
|
||||
readonly property real artworkSize: Math.round(compact ? naturalArtSize : Math.min(halfWidth, Math.max(naturalArtSize, headerHeight + controls.implicitHeight)))
|
||||
readonly property real columnHeight: compact ? artworkSize : Math.max(artworkSize, paneHeight)
|
||||
readonly property real paneHeight: Math.max(artworkSize, headerHeight + controls.implicitHeight)
|
||||
readonly property real paneMinHeight: Math.max(naturalArtSize, headerHeight + controls.implicitHeight)
|
||||
readonly property real headerHeight: sourceRow.height + Theme.spacingS
|
||||
readonly property real renderScale: Window.window?.devicePixelRatio ?? Screen.devicePixelRatio
|
||||
readonly property int artSide: TrackArtService.resolvedArtSide
|
||||
readonly property bool lowResArt: artSide > 0 && artSide < artworkSize * renderScale * DashMetrics.mediaArtLowResRatio
|
||||
|
||||
artSize: DashMetrics.mediaArtSizeDash
|
||||
surfaceColor: Theme.foregroundColor(Theme.hostSurface)
|
||||
baseHeight: Math.max(DashMetrics.tabMinHeight, padding * 2 + (compact ? naturalArtSize + Theme.spacingXL + paneMinHeight : Math.max(naturalArtSize, paneMinHeight)))
|
||||
focusTargets: (viewToggle.visible ? [viewToggle] : []).concat(artTransportLoader.item?.focusTargets ?? [], [playerButton], sourceGroup.focusTargets, transport.focusTargets, seekbar.canSeek && seekBlock.visible ? [seekbar] : [])
|
||||
focusTargets: (viewToggle.visible ? [viewToggle] : []).concat(artTransportLoader.item?.focusTargets ?? [], [playerButton], sourceGroup.focusTargets, transport.focusTargets, seekbar.canSeek && root.hasSeekbar ? [seekbar] : [])
|
||||
panelButtons: [playerButton].concat(sourceGroup.panelButtons)
|
||||
inlineVolume: true
|
||||
|
||||
@@ -56,10 +54,8 @@ MediaChromeBase {
|
||||
Item {
|
||||
id: art
|
||||
|
||||
readonly property real scaledSize: root.artworkSize * (root.lowResArt ? DashMetrics.mediaArtLowResScale : 1)
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: root.compact ? scaledSize : Math.min(root.artworkSize, Math.max(scaledSize, root.headerHeight + controls.implicitHeight))
|
||||
width: root.artworkSize
|
||||
height: width
|
||||
|
||||
HoverHandler {
|
||||
@@ -282,6 +278,7 @@ MediaChromeBase {
|
||||
loop: true
|
||||
fadeEdges: true
|
||||
pxPerMs: DashMetrics.mediaTextScrollSpeed / 1000
|
||||
stepInterval: DashMetrics.mediaTextScrollStep
|
||||
}
|
||||
|
||||
ScrollingText {
|
||||
@@ -294,6 +291,7 @@ MediaChromeBase {
|
||||
loop: true
|
||||
fadeEdges: true
|
||||
pxPerMs: DashMetrics.mediaTextScrollSpeed / 1000
|
||||
stepInterval: DashMetrics.mediaTextScrollStep
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,11 +325,13 @@ MediaChromeBase {
|
||||
visible: hasControls
|
||||
}
|
||||
|
||||
// Kept in the column for a length-less stream so the pane, and with it the
|
||||
// artwork it sizes, does not resize when one comes up in the queue.
|
||||
Item {
|
||||
id: seekBlock
|
||||
width: parent.width
|
||||
height: Theme.buttonHeightXS
|
||||
visible: root.hasSeekbar
|
||||
visible: root.seekbarEnabled && !!root.presentation
|
||||
LayoutMirroring.enabled: false
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
@@ -339,6 +339,7 @@ MediaChromeBase {
|
||||
id: elapsed
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: root.hasSeekbar
|
||||
text: Format.formatDuration(seekbar.value * (root.presentation?.length ?? 0))
|
||||
reserveText: duration.text.replace(/\d/g, "8")
|
||||
}
|
||||
@@ -349,6 +350,7 @@ MediaChromeBase {
|
||||
anchors.right: duration.left
|
||||
anchors.margins: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: root.hasSeekbar
|
||||
player: root.player
|
||||
}
|
||||
|
||||
@@ -356,6 +358,7 @@ MediaChromeBase {
|
||||
id: duration
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: root.hasSeekbar
|
||||
text: Format.formatDuration(root.presentation?.length ?? 0)
|
||||
reserveText: text.replace(/\d/g, "8")
|
||||
}
|
||||
@@ -39,7 +39,7 @@ Row {
|
||||
panelId: "volume"
|
||||
iconName: root.player.getVolumeIcon()
|
||||
enabled: root.player.volumeAvailable
|
||||
tooltipText: I18n.tr("Volume") + ": " + Math.round(root.player.currentVolume * 100) + "%"
|
||||
tooltipText: (root.player.usePlayerVolume ? I18n.tr("Media volume") : I18n.tr("Volume")) + ": " + Math.round(root.player.currentVolume * 100) + "%"
|
||||
|
||||
MediaVolumeWheel {
|
||||
player: root.player
|
||||
@@ -50,7 +50,7 @@ Row {
|
||||
GroupButton {
|
||||
id: devicesButton
|
||||
panelId: "devices"
|
||||
tooltipText: I18n.tr("Devices", "Media player output device picker")
|
||||
tooltipText: I18n.tr("Devices", "Media player output device picker") + ": " + AudioService.displayName(AudioService.sink)
|
||||
iconName: AudioService.sinkIcon(AudioService.sink)
|
||||
|
||||
MediaSinkWheel {}
|
||||
|
||||
@@ -151,7 +151,7 @@ DankBottomSheet {
|
||||
subtitle: [modelData?.trackTitle, modelData?.trackArtist].filter(Boolean).join(" · ")
|
||||
selected: modelData === root.player.activePlayer
|
||||
onActivated: {
|
||||
MprisController.switchActivePlayer(modelData);
|
||||
MprisController.setActivePlayer(modelData);
|
||||
root.player.panel = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.DankDash
|
||||
import "../../../DankCommon/Common/FocusNavigation.js" as FocusNavigation
|
||||
|
||||
Item {
|
||||
@@ -11,26 +12,13 @@ Item {
|
||||
|
||||
required property var player
|
||||
|
||||
readonly property var focusTargets: [volumeButton, devicesButton]
|
||||
readonly property var panelButtons: [volumeButton, devicesButton]
|
||||
readonly property var focusTargets: [volumeButton, deviceChip, deviceIcon]
|
||||
readonly property var panelButtons: [volumeButton, deviceChip, deviceIcon]
|
||||
readonly property string devicesLabel: I18n.tr("Devices", "Media player output device picker")
|
||||
readonly property string sinkName: AudioService.displayName(AudioService.sink)
|
||||
readonly property string fittedSinkName: {
|
||||
const room = devicesButton.maximumLabelWidth;
|
||||
// advanceWidth() is not reactive, this read re-evaluates once the font resolves
|
||||
if (labelMetrics.averageCharacterWidth <= 0)
|
||||
return "";
|
||||
if (Math.ceil(labelMetrics.advanceWidth(sinkName)) <= room)
|
||||
return sinkName;
|
||||
const words = sinkName.split(/\s+/);
|
||||
while (words.length > 1) {
|
||||
words.pop();
|
||||
const shortened = words.join(" ");
|
||||
if (Math.ceil(labelMetrics.advanceWidth(shortened)) <= room)
|
||||
return shortened;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
readonly property string deviceTooltip: devicesLabel + ": " + sinkName
|
||||
readonly property bool showSinkName: root.player.options?.deviceName ?? MediaOptions.defaults.deviceName
|
||||
readonly property string volumeLabel: root.player.usePlayerVolume ? I18n.tr("Media volume") : I18n.tr("Volume")
|
||||
readonly property bool muted: player.usePlayerVolume ? player.currentVolume === 0 : AudioService.sinkSilent
|
||||
readonly property real volumeRatio: player.maxVolumePercent > 0 ? player.currentVolume * 100 / player.maxVolumePercent : 0
|
||||
|
||||
@@ -38,13 +26,6 @@ Item {
|
||||
|
||||
Keys.onPressed: event => event.accepted = FocusNavigation.handleHorizontalKey(event, focusTargets, I18n.isRtl)
|
||||
|
||||
FontMetrics {
|
||||
id: labelMetrics
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Theme.fontWeightMedium
|
||||
}
|
||||
|
||||
DankRingGauge {
|
||||
id: volumeRing
|
||||
|
||||
@@ -72,7 +53,7 @@ Item {
|
||||
iconName: root.player.getVolumeIcon()
|
||||
iconColor: root.muted ? Theme.onSurfaceVariant : Theme.onSurface
|
||||
enabled: root.player.volumeAvailable
|
||||
tooltipText: I18n.tr("Volume") + ": " + Math.round(root.player.currentVolume * 100) + "%"
|
||||
tooltipText: root.volumeLabel + ": " + Math.round(root.player.currentVolume * 100) + "%"
|
||||
onClicked: root.player.togglePanel(panelId)
|
||||
|
||||
MediaVolumeWheel {
|
||||
@@ -83,22 +64,41 @@ Item {
|
||||
}
|
||||
|
||||
DankButton {
|
||||
id: devicesButton
|
||||
id: deviceChip
|
||||
|
||||
readonly property string panelId: "devices"
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
maximumWidth: Math.max(0, root.width - volumeRing.width - Theme.spacingXS)
|
||||
text: root.fittedSinkName || root.devicesLabel
|
||||
visible: root.showSinkName
|
||||
maximumWidth: Math.round(root.width * DashMetrics.mediaDeviceNameWidthRatio)
|
||||
text: root.sinkName
|
||||
iconName: AudioService.sinkIcon(AudioService.sink)
|
||||
tooltipText: root.fittedSinkName === root.sinkName ? root.devicesLabel : root.sinkName
|
||||
Accessible.name: root.devicesLabel + ": " + root.sinkName
|
||||
tooltipText: root.deviceTooltip
|
||||
Accessible.name: root.deviceTooltip
|
||||
buttonHeight: Theme.buttonHeightXS
|
||||
backgroundColor: MediaAccentService.accentSecondaryContainer
|
||||
textColor: MediaAccentService.onAccentSecondaryContainer
|
||||
horizontalPadding: Theme.spacingM
|
||||
onClicked: root.player.togglePanel("devices")
|
||||
onClicked: root.player.togglePanel(panelId)
|
||||
|
||||
MediaSinkWheel {}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: deviceIcon
|
||||
|
||||
readonly property string panelId: "devices"
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: !root.showSinkName
|
||||
buttonSize: volumeRing.width
|
||||
iconName: AudioService.sinkIcon(AudioService.sink)
|
||||
iconColor: MediaAccentService.onAccentSecondaryContainer
|
||||
backgroundColor: MediaAccentService.accentSecondaryContainer
|
||||
tooltipText: root.deviceTooltip
|
||||
onClicked: root.player.togglePanel(panelId)
|
||||
|
||||
MediaSinkWheel {}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,22 @@ Item {
|
||||
}
|
||||
readonly property bool volumeAvailable: !!((activePlayer && activePlayer.volumeSupported && !__isChromeBrowser) || (AudioService.sink && AudioService.sink.audio))
|
||||
readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported && !__isChromeBrowser
|
||||
readonly property real currentVolume: usePlayerVolume ? activePlayer.volume : (AudioService.sink?.audio?.volume ?? 0)
|
||||
readonly property real reportedVolume: usePlayerVolume ? activePlayer.volume : (AudioService.sink?.audio?.volume ?? 0)
|
||||
readonly property real currentVolume: pendingVolume >= 0 ? pendingVolume : reportedVolume
|
||||
readonly property real maxVolumePercent: usePlayerVolume ? 100 : AudioService.sinkMaxVolume
|
||||
|
||||
// MPRIS volume round-trips through the player, so successive steps would each read a stale
|
||||
// activePlayer.volume and collapse into one. Drive them from the value we last asked for.
|
||||
property real pendingVolume: -1
|
||||
|
||||
onReportedVolumeChanged: {
|
||||
if (pendingVolume >= 0 && Math.abs(reportedVolume - pendingVolume) < 0.005)
|
||||
clearPendingVolume();
|
||||
}
|
||||
|
||||
onUsePlayerVolumeChanged: clearPendingVolume()
|
||||
onActivePlayerChanged: clearPendingVolume()
|
||||
|
||||
implicitWidth: DashMetrics.contentWidthFor(SettingsData.showWeekNumber, DashMetrics.panelColumnsFor(entryId))
|
||||
implicitHeight: mediaChrome.item?.implicitHeight ?? DashMetrics.tabMinHeight
|
||||
|
||||
@@ -93,6 +106,12 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: pendingVolumeTimer
|
||||
interval: DashMetrics.mediaVolumeEchoTimeout
|
||||
onTriggered: root.pendingVolume = -1
|
||||
}
|
||||
|
||||
MediaPresentation {
|
||||
id: mediaPresentation
|
||||
player: root
|
||||
@@ -155,12 +174,19 @@ Item {
|
||||
return AudioService.sinkVolumeIconName;
|
||||
}
|
||||
|
||||
function clearPendingVolume() {
|
||||
pendingVolume = -1;
|
||||
pendingVolumeTimer.stop();
|
||||
}
|
||||
|
||||
function setVolume(ratio) {
|
||||
if (!volumeAvailable)
|
||||
return;
|
||||
const clamped = Math.min(maxVolumePercent / 100, Math.max(0, ratio));
|
||||
SessionData.suppressOSDTemporarily();
|
||||
if (usePlayerVolume) {
|
||||
pendingVolume = clamped;
|
||||
pendingVolumeTimer.restart();
|
||||
activePlayer.volume = clamped;
|
||||
return;
|
||||
}
|
||||
@@ -281,12 +307,12 @@ Item {
|
||||
Loader {
|
||||
id: mediaChrome
|
||||
anchors.fill: parent
|
||||
sourceComponent: root.playerStyle === "material" ? materialChrome : zurvanChrome
|
||||
sourceComponent: root.playerStyle === "material" ? materialChrome : bentoChrome
|
||||
}
|
||||
|
||||
Component {
|
||||
id: zurvanChrome
|
||||
ZurvanChrome {
|
||||
id: bentoChrome
|
||||
BentoChrome {
|
||||
player: root
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ CcSheetDialog {
|
||||
iconName: "settings"
|
||||
onClicked: {
|
||||
root.dismiss();
|
||||
PopoutService.closeDankDash();
|
||||
PopoutService.openSettingsWithTab(root.entryId === "media" ? "media_player" : "weather");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ Card {
|
||||
readonly property string artUrl: TrackArtService.resolvedArtUrl
|
||||
readonly property color accent: MediaAccentService.accent
|
||||
readonly property bool showSeekbar: options.seekbar !== false && !tiny
|
||||
readonly property bool zurvan: options.playerStyle === "zurvan"
|
||||
readonly property bool bento: options.playerStyle === "bento"
|
||||
readonly property bool inlineMetadata: compact && titleLabel.implicitHeight + artistLabel.implicitHeight + trackText.spacing > transport.y - Theme.spacingXS
|
||||
readonly property var playbackFocusTargets: [playButton, previousButton, nextButton].concat(seekbar.canSeek ? [seekbar] : [])
|
||||
|
||||
@@ -167,7 +167,7 @@ Card {
|
||||
id: transport
|
||||
|
||||
readonly property bool stacked: root.narrow && !root.tiny
|
||||
readonly property bool centered: root.zurvan && !stacked && !root.tiny
|
||||
readonly property bool centered: root.bento && !stacked && !root.tiny
|
||||
readonly property bool medium: !root.compact && width >= Theme.buttonHeightM * 4
|
||||
readonly property real buttonHeight: medium ? Theme.buttonHeightM : Theme.buttonHeightS
|
||||
readonly property real spacing: root.compact || stacked ? Theme.spacingXS : Theme.spacingS
|
||||
@@ -194,7 +194,7 @@ Card {
|
||||
checkable: true
|
||||
checked: root.playing
|
||||
iconFilled: false
|
||||
radius: Theme.buttonRadius(width, height, buttonSize, pressed, !root.zurvan && checked)
|
||||
radius: Theme.buttonRadius(width, height, buttonSize, pressed, !root.bento && checked)
|
||||
iconName: root.playing ? "pause" : "play_arrow"
|
||||
Accessible.name: root.playing ? I18n.tr("Pause") : I18n.tr("Play")
|
||||
enabled: !!root.activePlayer?.canTogglePlaying
|
||||
@@ -209,11 +209,11 @@ Card {
|
||||
anchors.bottom: parent.bottom
|
||||
size: transport.medium ? "m" : "s"
|
||||
width: transport.stacked ? (parent.width - transport.spacing) / 2 : (parent.width - playButton.width - transport.spacing * 2) / 2
|
||||
variant: root.zurvan ? "tonal" : "standard"
|
||||
round: !root.zurvan
|
||||
variant: root.bento ? "tonal" : "standard"
|
||||
round: !root.bento
|
||||
radius: Theme.buttonRadius(width, height, buttonSize, pressed, round)
|
||||
containerColor: MediaAccentService.accentSecondaryContainer
|
||||
contentColor: root.zurvan ? MediaAccentService.onAccentSecondaryContainer : Theme.onSecondaryContainer
|
||||
contentColor: root.bento ? MediaAccentService.onAccentSecondaryContainer : Theme.onSecondaryContainer
|
||||
iconName: "skip_previous"
|
||||
Accessible.name: I18n.tr("Previous")
|
||||
enabled: !!root.activePlayer?.canGoPrevious || (!!root.activePlayer?.canSeek && root.activePlayer.position > 8)
|
||||
|
||||
@@ -279,7 +279,10 @@ Item {
|
||||
DankButton {
|
||||
text: I18n.tr("Settings")
|
||||
iconName: "settings"
|
||||
onClicked: PopoutService.openSettingsWithTab("weather")
|
||||
onClicked: {
|
||||
PopoutService.closeDankDash();
|
||||
PopoutService.openSettingsWithTab("weather");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user