harbour-allradio/qml/pages/RadioPlayerPage.qml
2025-06-02 18:52:15 +02:00

315 lines
12 KiB
QML

import QtQuick 2.0
import QtGraphicalEffects 1.0
import Sailfish.Silica 1.0
import "../delegates"
import "../items"
import "../helpers/jsFunctions.js" as JSfunctions
Page {
id: page
property bool keepScreenOn: Qt.application.active && radioPlayer.isPlaying ? true : false
allowedOrientations: radioPlayer.isPlaying && radioPlayer.radioVideo ? Orientation.All : Orientation.Portrait
backNavigation: orientation === Orientation.Portrait ? true : false//radioPlayer.isPlaying && radioPlayer.radioVideo && Orientation.Portrait ? false : true
ScreenBlank {
id: screenBlank
enabled: keepScreenOn
}
VideoPlayer {
id: videoPlayer
z:97
anchors.top: orientation === Orientation.Portrait ? radioName.top : page.top
anchors.bottom: orientation === Orientation.Portrait ? radioName.bottom : page.bottom
anchors.left: orientation === Orientation.Portrait ? radioName.left : page.left
anchors.right: orientation === Orientation.Portrait ? radioName.right : page.right
anchors.margins: orientation === Orientation.Portrait ? radioName.border.width : 0
visible: radioPlayer.radioVideo && !radioPlayer.isPaused ? true : false
onVisibleChanged: visible ? enabled=true : enabled = false
videoSource: radioPlayer
}
PageHeader {
id: pheader
z: orientation === Orientation.Portrait || !screenTimer.running ? 98 : 0
visible: orientation !== Orientation.LandscapeMask
Column {
id: headerCol
visible: orientation === Orientation.Portrait
anchors.top: parent.top
anchors.topMargin: Theme.paddingLarge
anchors.verticalCenter: parent.verticalCenter
width: parent.width
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
anchors.left: parent.left
anchors.leftMargin: Theme.paddingLarge
spacing: Theme.paddingSmall
Row {
spacing: Theme.paddingMedium
anchors.right: parent.right
Text{
id: countryName
font.pixelSize: Theme.fontSizeLarge
color: Theme.highlightColor
horizontalAlignment: Text.AlignRight
text: radioPlayer.radioCountryName
}
Image {
anchors.bottom: countryName.bottom
height: countryName.height * 0.9
fillMode: Image.PreserveAspectFit
smooth: false
source: radioPlayer._countrycode === "" ? "../images/bycountry_t.png" : "../flags/"+radioPlayer._countrycode.toLowerCase()+".png"
}
}
Label {
anchors.right: parent.right
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraSmall
text: JSfunctions.getAll(radioPlayer._hls,radioPlayer._codec,radioPlayer._bitrate)
}
}
}
Rectangle {
id: radioName
anchors.top: pheader.bottom
anchors.topMargin: Theme.paddingLarge
anchors.bottom: artistSongName.top
anchors.bottomMargin: Theme.paddingLarge
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
radius: 20
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - (Theme.paddingLarge * 2)
Behavior on opacity {
FadeAnimator {}
}
Label {
id: nameLabel
z:99
anchors.top: parent.top
anchors.topMargin: Theme.paddingLarge * 2
anchors.leftMargin: Theme.paddingLarge
anchors.rightMargin: Theme.paddingLarge
anchors.horizontalCenter: parent.horizontalCenter
font.bold: false
color: Theme.secondaryColor
wrapMode: Text.WordWrap
font.pixelSize: Theme.fontSizeLarge
fontSizeMode: Text.Fit
maximumLineCount: 2
width: parent.width - (Theme.paddingLarge * 2)
height: Theme.itemSizeExtraSmall
elide: Text.ElideLeft
horizontalAlignment: Text.AlignHCenter
text: radioPlayer._name
}
RadioImage {
anchors.top: nameLabel.bottom
anchors.bottom: parent.bottom
anchors.topMargin: Theme.paddingLarge
anchors.bottomMargin: Theme.paddingLarge * 2
id: radioImage
width: height
stationBorder: false
anchors.horizontalCenter: parent.horizontalCenter
stationImage: radioPlayer._favicon ? radioPlayer._favicon : ""
stationLabel: radioPlayer._name
flag: false
onWidthChanged: if (width > radioName.width - (Theme.paddingLarge * 2)) width = radioName.width - (Theme.paddingLarge * 2)
}
}
Rectangle {
id: artistSongName
anchors.bottom: playerControls.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Theme.paddingLarge
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
radius: 20
width: parent.width
height: radioname.height + radiocountry.height + (Theme.paddingMedium * 3)
opacity: radioname.text !== "" ? 1.0 : 0.0
Behavior on opacity {
FadeAnimator {}
}
Column {
width: parent.width
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Theme.paddingSmall
Label {
id: radioname
color: Theme.secondaryColor
wrapMode: Text.WordWrap
font.pixelSize: Theme.fontSizeLarge
fontSizeMode: Text.Fit
maximumLineCount: 5
width: parent.width - (Theme.paddingMedium * 2)
elide: Text.ElideLeft
horizontalAlignment: Text.AlignHCenter
visible: text.length > 0
text: radioPlayer.radioVideo && !radioPlayer.isPaused ? radioPlayer._name : radioPlayer.radioArtist // radioPlayer._name
}
Label {
id: radiocountry
color: Theme.secondaryColor
wrapMode: Text.WordWrap
font.pixelSize: Theme.fontSizeLarge
fontSizeMode: Text.Fit
maximumLineCount: 5
width: parent.width - (Theme.paddingMedium * 2)
elide: Text.ElideLeft
horizontalAlignment: Text.AlignHCenter
visible: text.length > 0
text: radioPlayer.radioSong
}
}
}
// Radio player controls
Item {
id: playerControls
visible: orientation === Orientation.Portrait
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.paddingMedium
anchors.horizontalCenter: parent.horizontalCenter
height: Theme.itemSizeLarge
width: parent.width
Rectangle {
width: row.width + (Theme.paddingMedium * 3)
height: play.height + (Theme.paddingMedium * 2)
radius: 90
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
border.width: 0
anchors.left: parent.left
anchors.leftMargin: Theme.paddingLarge
Row {
id: row
anchors.centerIn: parent
spacing: Theme.paddingMedium
Image {
id: playprev
enabled: radioPlayer.playlistIndex > 0
opacity: enabled ? 1.0 : 0.4
source: "image://theme/icon-m-previous"
height: play.height
width: height
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: play.verticalCenter
MouseArea {
anchors.fill: parent
onClicked: {
radioPlayer.playPrev()
}
}
}
Image {
id: play
source: radioPlayer.isPlaying ? "image://theme/icon-l-pause" : "image://theme/icon-l-play"
height: Theme.itemSizeSmall * 0.75
width: height
MouseArea {
anchors.fill: parent
onClicked: radioPlayer.isPlaying ? radioPlayer.pauseStream() : radioPlayer.resumeStream()//icon.source == "image://theme/icon-l-play" ? icon.source = "image://theme/icon-l-pause" : icon.source = "image://theme/icon-l-play"
}
}
Image {
id: playDLNA
enabled: radioPlayer.playlistIndex < radioPlayer.playlist.count -1
opacity: enabled ? 1.0 : 0.4
source: "image://theme/icon-m-next"
height: play.height
width: height
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: play.verticalCenter
MouseArea {
anchors.fill: parent
onClicked: {
radioPlayer.playNext()
}
}
}
Image {
id: sleeptimer
source: "image://theme/icon-s-timer"
height: play.height
width: height
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: play.verticalCenter
MouseArea {
anchors.fill: parent
onClicked: {
pageStack.push("SleepTimerPage.qml")
}
}
}
}
}
Rectangle {
visible: orientation === Orientation.Portrait
width: upvote.width + favorite.width + (Theme.paddingMedium * 4)
height: upvote.height + (Theme.paddingMedium * 2)
radius: 90
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
border.width: 0
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
Row {
anchors.centerIn: parent
spacing: Theme.paddingMedium
Image {
id: favorite
source: radioPlayer._favorite ? "image://theme/icon-m-favorite-selected" : "image://theme/icon-m-favorite"
height: Theme.itemSizeSmall * 0.75
width: height
MouseArea {
anchors.fill: parent
onClicked: {
radioPlayer._favorite ? radioPlayer._favorite = false : radioPlayer._favorite = true
radioPlayer.setStationFavorite(radioPlayer._stationuuid,radioPlayer._name,radioPlayer._countrycode,radioPlayer._homepage,radioPlayer._url_resolved,radioPlayer._favicon,radioPlayer._tags,radioPlayer._codec,radioPlayer._bitrate,radioPlayer._hls,radioPlayer._favorite)
}
}
}
Image {
id: upvote
property bool returnValue: false
source: returnValue ? "image://theme/icon-m-like" : "image://theme/icon-m-outline-like"
height: favorite.height
width: height
fillMode: Image.PreserveAspectFit
onReturnValueChanged: console.log(" RETURN VALUE: "+upvote.returnValue)
MouseArea {
anchors.fill: parent
onClicked: {radioBrowser.upVote(radioPlayer._stationuuid,upvote.returnValue)}
}
}
}
}
}
Component.onCompleted: {
mediaPlayerPanel.open=false
radioPlayer.playerPageOpen=true
}
Component.onDestruction: {
if (radioPlayer.radioVideo) radioPlayer.pauseStream()
radioPlayer.playerPageOpen=false
mediaPlayerPanel.open=true
}
}