1
0
Fork 0
mirror of https://github.com/HenkKalkwater/harbour-sailfin.git synced 2024-11-24 10:05:17 +00:00

ui: improve empty state, add remote playback indicator

This commit is contained in:
Chris Josten 2023-01-11 23:11:02 +01:00
parent 3783de9ce7
commit 7c6d8486de
7 changed files with 76 additions and 13 deletions

View file

@ -69,7 +69,11 @@ function randomBackdrop(baseUrl, item) {
function itemBackdropUrl(baseUrl, item, idx, options) { function itemBackdropUrl(baseUrl, item, idx, options) {
var extraQuery = propsToQuery(options) var extraQuery = propsToQuery(options)
return baseUrl + "/Items/" + item.jellyfinId + "/Images/Backdrop/" + idx + "?tag=" + item.backdropImageTags[idx] + extraQuery; if (item.backdropImageTags[idx]) {
return baseUrl + "/Items/" + item.jellyfinId + "/Images/Backdrop/" + idx + "?tag=" + item.backdropImageTags[idx] + extraQuery;
} else {
return baseUrl + "/Items/" + item.parentBackdropItemId + "/Images/Backdrop/" + idx + "?tag=" + item.parentBackdropImageTags[idx] + extraQuery;
}
} }

View file

@ -48,6 +48,8 @@ PanelBackground {
property bool showQueue: false property bool showQueue: false
property bool _pageWasShowingNavigationIndicator property bool _pageWasShowingNavigationIndicator
readonly property bool _isItemSet: manager.item !== null && manager.item !== undefined && manager.item.jellyfinId.length > 0
readonly property bool controllingRemote: !manager.controllingSessionLocal
readonly property bool mediaLoading: [J.MediaStatus.Loading, J.MediaStatus.Buffering].indexOf(manager.mediaStatus) >= 0 readonly property bool mediaLoading: [J.MediaStatus.Loading, J.MediaStatus.Buffering].indexOf(manager.mediaStatus) >= 0
@ -67,9 +69,12 @@ PanelBackground {
top: parent.top top: parent.top
} }
width: height width: height
Binding on blurhash { blurhash: {
when: manager.item !== null && "Primary" in manager.item.imageBlurHashes && "Primary" in manager.item.imageTags if (_isItemSet && "Primary" in manager.item.imageBlurHashes && "Primary" in manager.item.imageTags) {
value: manager.item.imageBlurHashes["Primary"][manager.item.imageTags["Primary"]] return manager.item.imageBlurHashes["Primary"][manager.item.imageTags["Primary"]]
} else {
return ""
}
} }
source: largeAlbumArt.source source: largeAlbumArt.source
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
@ -125,7 +130,10 @@ PanelBackground {
Label { Label {
id: name id: name
text: manager.item === null ? qsTr("No media selected") : manager.item.name text: manager.item.jellyfinId
? manager.item.name
//: Shown in a bright font when no media is playing in the bottom bar and now playing screen
: qsTr("Nothing is playing")
width: Math.min(contentWidth, parent.width) width: Math.min(contentWidth, parent.width)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
maximumLineCount: 1 maximumLineCount: 1
@ -133,8 +141,23 @@ PanelBackground {
} }
Label { Label {
id: artists id: artists
leftPadding: controllingRemote ? remoteIcon.width + Theme.paddingSmall : 0
text: { text: {
if (manager.item === null) return qsTr("Play some media!") if (!_isItemSet) {
if (controllingRemote) {
//: Shown when no media is being played, but the app is controlling another Jellyfin client
//: %1 is the name of said client
return qsTr("Connected to %1").arg(manager.controllingSessionName)
} else {
return qsTr("Start playing some media!")
}
}
var remoteText = "";
if (controllingRemote) {
remoteText = manager.controllingSessionName + " - "
}
switch(manager.item.mediaType) { switch(manager.item.mediaType) {
case "Audio": case "Audio":
var links = []; var links = [];
@ -147,7 +170,7 @@ PanelBackground {
.arg(Theme.secondaryColor) .arg(Theme.secondaryColor)
) )
} }
return links.join(", ") return remoteText + links.join(", ")
} }
return qsTr("No audio") return qsTr("No audio")
} }
@ -162,6 +185,16 @@ PanelBackground {
appWindow.navigateToItem(link, "Audio", "MusicArtist", true) appWindow.navigateToItem(link, "Audio", "MusicArtist", true)
} }
textFormat: Text.StyledText textFormat: Text.StyledText
Icon {
id: remoteIcon
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
height: parent
source: "image://theme/icon-s-device-upload"
visible: controllingRemote
}
} }
} }
@ -395,7 +428,9 @@ PanelBackground {
}, },
State { State {
name: "hidden" name: "hidden"
when: ((manager.playbackState === J.PlayerState.Stopped && !mediaLoading) || "__hidePlaybackBar" in pageStack.currentPage) && !isFullPage when: ((manager.playbackState === J.PlayerState.Stopped && !mediaLoading)
|| ("__hidePlaybackBar" in pageStack.currentPage && pageStack.currentPage.__hidePlaybackBar))
&& !isFullPage
PropertyChanges { PropertyChanges {
target: playbackBarTranslate target: playbackBarTranslate
// + small padding since the ProgressBar otherwise would stick out // + small padding since the ProgressBar otherwise would stick out

View file

@ -50,6 +50,16 @@ SilicaItem {
color: Theme.overlayBackgroundColor color: Theme.overlayBackgroundColor
} }
RemoteImage {
id: backdrop
anchors.fill: parent
visible: !manager.controllingSessionLocal
|| [J.MediaStatus.NoMedia, J.MediaStatus.Loading].indexOf(manager.mediaStatus) >= 0
fillMode: Image.PreserveAspectFit
source: Utils.itemBackdropUrl(apiClient.baseUrl, item, 0, {"maxWidth": parent.width})
blurhash: item.imageBlurHashes["Backdrop"][item.backdropImageTags[0]]
}
VideoOutput { VideoOutput {
id: videoOutput id: videoOutput
source: manager source: manager
@ -64,7 +74,7 @@ SilicaItem {
anchors.fill: parent anchors.fill: parent
manager: playerRoot.manager manager: playerRoot.manager
title: videoPlayer.title title: videoPlayer.title
alwaysVisible: !manager.controllingSessionLocal
} }
VideoError { VideoError {

View file

@ -34,6 +34,8 @@ Item {
property var manager property var manager
property string title property string title
property bool _manuallyActivated: false property bool _manuallyActivated: false
/// Don't allow the HUD to hide
property bool alwaysVisible: false
readonly property bool hidden: opacity == 0.0 readonly property bool hidden: opacity == 0.0
Behavior on opacity { FadeAnimator {} } Behavior on opacity { FadeAnimator {} }
@ -174,6 +176,7 @@ Item {
} }
function hide(manual) { function hide(manual) {
if (alwaysVisible) return
// Don't hide if the user decided on their own to show the hud // Don't hide if the user decided on their own to show the hud
//if (!manual && _manuallyActivated) return; //if (!manual && _manuallyActivated) return;
// Don't give in to the user if they want to hide the hud while it was forced upon them // Don't give in to the user if they want to hide the hud while it was forced upon them

View file

@ -75,7 +75,7 @@ ApplicationWindow {
//cover: CoverBackground {CoverPlaceholder { icon.source: "icon.png"; text: "Sailfin"}} //cover: CoverBackground {CoverPlaceholder { icon.source: "icon.png"; text: "Sailfin"}}
cover: { cover: {
// Disabled due to buggy Loader behaviour // Disabled due to buggy Loader behaviour
if ([MediaPlayer.NoMedia, MediaPlayer.InvalidMedia, MediaPlayer.UnknownStatus].indexOf(_playbackManager.mediaStatus) >= 0 if ([MediaStatus.NoMedia, MediaStatus.InvalidMedia].indexOf(_playbackManager.mediaStatus) >= 0
|| _playbackManager.playbackState === MediaPlayer.StoppedState) { || _playbackManager.playbackState === MediaPlayer.StoppedState) {
return Qt.resolvedUrl("cover/CollectionPage.qml") return Qt.resolvedUrl("cover/CollectionPage.qml")
} else { } else {
@ -134,7 +134,9 @@ ApplicationWindow {
} }
DisplayBlanking { DisplayBlanking {
preventBlanking: playbackManager.playbackState === MediaPlayer.PlayingState && playbackManager.hasVideo preventBlanking: playbackManager.playbackState === MediaPlayer.PlayingState
&& playbackManager.hasVideo
&& playbackManager.controllingSessionLocal // Must be controlling a local session
} }
PlaybackBar { PlaybackBar {

View file

@ -25,7 +25,7 @@ Page {
property bool isConnected: model.jellyfinId === appWindow.playbackManager.controllingSessionId property bool isConnected: model.jellyfinId === appWindow.playbackManager.controllingSessionId
onClicked: deviceList.activateSession(appWindow.playbackManager, model.index) onClicked: deviceList.activateSession(appWindow.playbackManager, model.index)
contentHeight: Theme.itemSizeMedium contentHeight: Theme.itemSizeMedium
HighlightImage { Icon {
id: deviceIcon id: deviceIcon
anchors { anchors {
left: parent.left left: parent.left

View file

@ -38,7 +38,16 @@ Page {
property int subtitleTrack property int subtitleTrack
property bool resume: true property bool resume: true
allowedOrientations: Orientation.All allowedOrientations: {
if (itemData.width !== null && itemData.height !== null) {
return itemData.width / itemData.height > Screen.width / Screen.height
? Orientation.LandscapeMask
: Orientation.PortraitMask
} else {
return Orientation.All
}
}
showNavigationIndicator: videoPlayer.hudVisible showNavigationIndicator: videoPlayer.hudVisible
VideoPlayer { VideoPlayer {