mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2025-09-04 01:42:44 +00:00
sailfish: add LiveTvChannels page
This ocmmit adds a LiveTvChannels page for displaying the programs that are now playing. The section Live TV Channels on the main page now shows the TV channel list in order of the channel number. Additionally, it fixes an issue in ApiModel, where it would not reload when a new loader was assigned. This is now fixed and some code on pages that worked around this fix has been removed.
This commit is contained in:
parent
edcd3a93af
commit
57b67292fd
23 changed files with 344 additions and 54 deletions
|
@ -56,10 +56,12 @@ set(sailfin_QML_SOURCES
|
|||
qml/pages/itemdetails/CollectionPage.qml
|
||||
qml/pages/itemdetails/EpisodePage.qml
|
||||
qml/pages/itemdetails/FilmPage.qml
|
||||
qml/pages/itemdetails/MusicAlbumPage.qml
|
||||
qml/pages/itemdetails/LiveTvChannelPage.qml
|
||||
qml/pages/itemdetails/LiveTvChannelsPage.qml
|
||||
qml/pages/itemdetails/MusicAlbumPage.qml
|
||||
qml/pages/itemdetails/MusicArtistPage.qml
|
||||
qml/pages/itemdetails/MusicLibraryPage.qml
|
||||
qml/pages/itemdetails/PhotoPage.qml
|
||||
qml/pages/itemdetails/PhotoPage.qml
|
||||
qml/pages/itemdetails/SeasonPage.qml
|
||||
qml/pages/itemdetails/SeriesPage.qml
|
||||
qml/pages/itemdetails/UnsupportedPage.qml
|
||||
|
|
|
@ -115,6 +115,8 @@ function getPageUrl(mediaType, itemType, isFolder) {
|
|||
return Qt.resolvedUrl("pages/itemdetails/MusicAlbumPage.qml")
|
||||
case "photo":
|
||||
return Qt.resolvedUrl("pages/itemdetails/PhotoPage.qml")
|
||||
case "tvchannel":
|
||||
return Qt.resolvedUrl("pages/itemdetails/LiveTvChannelPage.qml")
|
||||
case "collectionfolder":
|
||||
// TODO: support for other collection folders
|
||||
switch(mediaType.toLowerCase()) {
|
||||
|
@ -124,6 +126,8 @@ function getPageUrl(mediaType, itemType, isFolder) {
|
|||
// FALLTRHOUGH
|
||||
default:
|
||||
switch (mediaType ? mediaType.toLowerCase() : isFolder ? "folder" : "") {
|
||||
case "livetv":
|
||||
return Qt.resolvedUrl("pages/itemdetails/LiveTvChannelsPage.qml")
|
||||
case "folder":
|
||||
return Qt.resolvedUrl("pages/itemdetails/CollectionPage.qml")
|
||||
case "video":
|
||||
|
|
|
@ -190,7 +190,7 @@ PanelBackground {
|
|||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: parent
|
||||
height: parent.height
|
||||
source: "image://theme/icon-s-device-upload"
|
||||
visible: controllingRemote
|
||||
}
|
||||
|
|
|
@ -106,6 +106,9 @@ SilicaItem {
|
|||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
running: realImage.status === Image.Loading
|
||||
size: root.height <= Theme.fontSizeLarge
|
||||
? BusyIndicatorSize.Small
|
||||
: BusyIndicatorSize.Medium
|
||||
}
|
||||
|
||||
HighlightImage {
|
||||
|
|
|
@ -114,6 +114,12 @@ Page {
|
|||
apiClient: appWindow.apiClient
|
||||
parentId: jellyfinId
|
||||
}
|
||||
Binding on loader {
|
||||
when: model.collectionType == "livetv"
|
||||
value: J.LiveTvChannelsLoader{
|
||||
apiClient: appWindow.apiClient
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: mediaLibraryLoader
|
||||
onReady: loader.reload()
|
||||
|
|
23
sailfish/qml/pages/itemdetails/LiveTvChannelPage.qml
Normal file
23
sailfish/qml/pages/itemdetails/LiveTvChannelPage.qml
Normal file
|
@ -0,0 +1,23 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
import "../../components"
|
||||
|
||||
VideoPage {
|
||||
title: itemData.currentProgram.name
|
||||
subtitle: qsTr("%1 | %2 - %3")
|
||||
.arg(itemData.name)
|
||||
.arg(Qt.formatTime(itemData.currentProgram.startDate))
|
||||
.arg(Qt.formatTime(itemData.currentProgram.endDate))
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Program info")
|
||||
}
|
||||
|
||||
PlainLabel {
|
||||
id: overviewText
|
||||
text: itemData.currentProgram.overview || qsTr("No program info available")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.secondaryHighlightColor
|
||||
}
|
||||
}
|
109
sailfish/qml/pages/itemdetails/LiveTvChannelsPage.qml
Normal file
109
sailfish/qml/pages/itemdetails/LiveTvChannelsPage.qml
Normal file
|
@ -0,0 +1,109 @@
|
|||
import QtQuick 2.6
|
||||
import Sailfish.Silica 1.0
|
||||
import nl.netsoj.chris.Jellyfin 1.0 as J
|
||||
|
||||
import "../../components"
|
||||
import "../../"
|
||||
|
||||
BaseDetailPage {
|
||||
J.ItemModel {
|
||||
id: episodeModel
|
||||
loader: J.LiveTvChannelsLoader{
|
||||
apiClient: appWindow.apiClient
|
||||
fields: [J.ItemFields.Overview]
|
||||
autoReload: itemData.jellyfinId.length > 0
|
||||
}
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
anchors.fill: parent
|
||||
model: episodeModel
|
||||
header: PageHeader {
|
||||
title: itemData.name
|
||||
description: itemData.seriesName
|
||||
}
|
||||
delegate: BackgroundItem {
|
||||
height: content.height
|
||||
onClicked: appWindow.navigateToItem(model.jellyfinId, model.mediaType, model.type, model.isFolder);
|
||||
|
||||
Column {
|
||||
id: content
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: Theme.horizontalPageMargin
|
||||
right: parent.right
|
||||
rightMargin: Theme.horizontalPageMargin
|
||||
}
|
||||
spacing: Theme.paddingSmall
|
||||
topPadding: Theme.paddingLarge
|
||||
bottomPadding: Theme.paddingLarge
|
||||
width: parent.width
|
||||
|
||||
|
||||
Row {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
RemoteImage {
|
||||
id: channelLogo
|
||||
width: Theme.fontSizeLarge
|
||||
height: width
|
||||
source: Utils.itemModelImageUrl(apiClient.baseUrl, model.jellyfinId, model.imageTags.Primary, "Primary", {"maxHeight": height})
|
||||
blurhash: model.imageBlurHashes.Primary[model.imageTags.Primary]
|
||||
fillMode: Image.PreserveAspectFit
|
||||
fallbackColor: "transparent"
|
||||
}
|
||||
|
||||
Label {
|
||||
anchors.verticalCenter: channelLogo.verticalCenter
|
||||
id: channelName
|
||||
text: model.name
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
}
|
||||
}
|
||||
Item {
|
||||
anchors { left: parent.left; right: parent.right }
|
||||
height: programName.height
|
||||
Label {
|
||||
id: programName
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: programTime.left
|
||||
rightMargin: Theme.paddingLarge
|
||||
}
|
||||
text: currentProgramName
|
||||
? currentProgramName
|
||||
//: Shown in the channel list when the name of the current program is unknown
|
||||
: qsTr("No program information available")
|
||||
truncationMode: TruncationMode.Fade
|
||||
}
|
||||
Label {
|
||||
id: programTime
|
||||
anchors.right: parent.right
|
||||
text: "%1 - %2"
|
||||
.arg(Qt.formatTime(currentProgramStartDate))
|
||||
.arg(Qt.formatTime(currentProgramEndDate))
|
||||
color: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||
}
|
||||
}
|
||||
Label {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
visible: text
|
||||
|
||||
text: currentProgramOverview
|
||||
color: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
elide: "ElideRight"
|
||||
}
|
||||
}
|
||||
}
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
}
|
|
@ -55,7 +55,6 @@ BaseDetailPage {
|
|||
fields: [J.ItemFields.ItemCounts, J.ItemFields.PrimaryImageAspectRatio]
|
||||
parentId: itemData.jellyfinId
|
||||
autoReload: itemData.jellyfinId.length > 0
|
||||
//onParentIdChanged: if (parentId.length > 0) reload()
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
|
|
|
@ -37,11 +37,6 @@ BaseDetailPage {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: itemData
|
||||
onReady: episodeModel.reload()
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
anchors.fill: parent
|
||||
contentHeight: content.height
|
||||
|
@ -149,19 +144,4 @@ BaseDetailPage {
|
|||
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
Connections {
|
||||
target: itemData
|
||||
onStatusChanged: {
|
||||
if (itemData.status == JellyfinItem.Ready) {
|
||||
episodeModel.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
onStatusChanged: {
|
||||
if (status == PageStatus.Active) {
|
||||
//console.log(JSON.stringify(itemData))
|
||||
//episodeModel.show = itemData.seriesId
|
||||
//episodeModel.seasonId = itemData.jellyfinId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,10 +72,6 @@ BaseDetailPage {
|
|||
autoReload: itemData.jellyfinId.length > 0
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: itemData
|
||||
onReady: showSeasonsModel.reload()
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
model: showSeasonsModel
|
||||
|
@ -96,17 +92,4 @@ BaseDetailPage {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
/*onStatusChanged: {
|
||||
if (status == PageStatus.Active) {
|
||||
showSeasonsModel.reload()
|
||||
}
|
||||
}*/
|
||||
Connections {
|
||||
target: itemData
|
||||
onJellyfinIdChanged: {
|
||||
console.log("Item id changed")
|
||||
//showSeasonsModel.show = itemData.jellyfinId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import "../.."
|
|||
*/
|
||||
BaseDetailPage {
|
||||
id: detailPage
|
||||
property alias title: pageHeader.title
|
||||
property alias subtitle: pageHeader.description
|
||||
default property alias _data: content.data
|
||||
property real _playbackProsition: itemData.userData.playbackPositionTicks
|
||||
|
|
|
@ -265,6 +265,29 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelPage</name>
|
||||
<message>
|
||||
<source>%1 | %2 - %3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Program info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No program info available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelsPage</name>
|
||||
<message>
|
||||
<source>No program information available</source>
|
||||
<extracomment>Shown in the channel list when the name of the current program is unknown</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginDialog</name>
|
||||
<message>
|
||||
|
|
|
@ -265,6 +265,29 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelPage</name>
|
||||
<message>
|
||||
<source>%1 | %2 - %3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Program info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No program info available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelsPage</name>
|
||||
<message>
|
||||
<source>No program information available</source>
|
||||
<extracomment>Shown in the channel list when the name of the current program is unknown</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginDialog</name>
|
||||
<message>
|
||||
|
|
|
@ -265,6 +265,29 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelPage</name>
|
||||
<message>
|
||||
<source>%1 | %2 - %3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Program info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No program info available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LiveTvChannelsPage</name>
|
||||
<message>
|
||||
<source>No program information available</source>
|
||||
<extracomment>Shown in the channel list when the name of the current program is unknown</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginDialog</name>
|
||||
<message>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue