1
0
Fork 0
mirror of https://github.com/HenkKalkwater/harbour-sailfin.git synced 2024-05-18 20:02:43 +00:00

Added debug page, fix RemoteImage on covers

This commit is contained in:
Chris Josten 2021-02-13 21:42:57 +01:00
parent eda4994aac
commit 5ddd5e8e2e
12 changed files with 112 additions and 123 deletions

View file

@ -77,6 +77,7 @@ public:
Q_PROPERTY(QString baseUrl MEMBER m_baseUrl READ baseUrl NOTIFY baseUrlChanged) Q_PROPERTY(QString baseUrl MEMBER m_baseUrl READ baseUrl NOTIFY baseUrlChanged)
Q_PROPERTY(bool authenticated READ authenticated WRITE setAuthenticated NOTIFY authenticatedChanged) Q_PROPERTY(bool authenticated READ authenticated WRITE setAuthenticated NOTIFY authenticatedChanged)
Q_PROPERTY(QString userId READ userId NOTIFY userIdChanged) Q_PROPERTY(QString userId READ userId NOTIFY userIdChanged)
Q_PROPERTY(QJsonObject deviceProfile READ deviceProfile NOTIFY deviceProfileChanged)
Q_PROPERTY(QString version READ version) Q_PROPERTY(QString version READ version)
/*QNetworkReply *handleRequest(QString path, QStringList sort, Pagination *pagination, /*QNetworkReply *handleRequest(QString path, QStringList sort, Pagination *pagination,
@ -145,6 +146,8 @@ signals:
void itemFetched(const QString &itemId, const QJsonObject &result); void itemFetched(const QString &itemId, const QJsonObject &result);
void itemFetchFailed(const QString &itemId, const QNetworkReply::NetworkError error); void itemFetchFailed(const QString &itemId, const QNetworkReply::NetworkError error);
void deviceProfileChanged();
/** /**
* @brief onUserDataChanged Emitted when the user data of an item is changed on the server. * @brief onUserDataChanged Emitted when the user data of an item is changed on the server.
* @param itemId The id of the item being changed * @param itemId The id of the item being changed

View file

@ -265,6 +265,7 @@ void ApiClient::generateDeviceProfile() {
root["PlayableMediaTypes"] = playableMediaTypes; root["PlayableMediaTypes"] = playableMediaTypes;
m_deviceProfile = root; m_deviceProfile = root;
emit deviceProfileChanged();
} }
void ApiClient::defaultNetworkErrorHandler(QNetworkReply::NetworkError error) { void ApiClient::defaultNetworkErrorHandler(QNetworkReply::NetworkError error) {

View file

@ -80,7 +80,7 @@ QJsonObject DeviceProfile::generateProfile() {
JsonPair("Type", "VideoAudio") JsonPair("Type", "VideoAudio")
}); });
codecProfiles.append(QJsonObject { codecProfiles.append(QJsonObject {
JsonPair("Coded", "h264"), JsonPair("Codec", "h264"),
JsonPair("Conditions", QJsonArray { JsonPair("Conditions", QJsonArray {
QJsonObject { QJsonObject {
JsonPair("Property", "IsAnamorphic"), JsonPair("Property", "IsAnamorphic"),

View file

@ -25,7 +25,6 @@ set(sailfin_QML_SOURCES
qml/components/music/SongDelegate.qml qml/components/music/SongDelegate.qml
qml/components/videoplayer/VideoError.qml qml/components/videoplayer/VideoError.qml
qml/components/videoplayer/VideoHud.qml qml/components/videoplayer/VideoHud.qml
qml/components/GlassyBackground.qml
qml/components/IconListItem.qml qml/components/IconListItem.qml
qml/components/LibraryItemDelegate.qml qml/components/LibraryItemDelegate.qml
qml/components/MoreSection.qml qml/components/MoreSection.qml
@ -55,6 +54,7 @@ set(sailfin_QML_SOURCES
qml/pages/itemdetails/SeriesPage.qml qml/pages/itemdetails/SeriesPage.qml
qml/pages/itemdetails/UnsupportedPage.qml qml/pages/itemdetails/UnsupportedPage.qml
qml/pages/itemdetails/VideoPage.qml qml/pages/itemdetails/VideoPage.qml
qml/pages/settings/DebugPage.qml
qml/pages/setup/AddServerConnectingPage.qml qml/pages/setup/AddServerConnectingPage.qml
qml/pages/setup/LoginDialog.qml qml/pages/setup/LoginDialog.qml
qml/qmldir) qml/qmldir)

View file

@ -32,6 +32,7 @@ BackgroundItem {
bottom: parent.bottom bottom: parent.bottom
bottomMargin: Theme.paddingMedium bottomMargin: Theme.paddingMedium
} }
width: height
} }
Label { Label {

View file

@ -36,7 +36,9 @@ SilicaItem {
property var __parentPage : null property var __parentPage : null
property bool _alreadyLoaded: false property bool _alreadyLoaded: false
readonly property bool _shouldLoad: _alreadyLoaded || __parentPage && [PageStatus.Active, PageStatus.Deactivating].indexOf(__parentPage.status) >= 0 readonly property bool _shouldLoad: _alreadyLoaded
|| __parentPage == null // Not an indirect child of a page. Immediatly start loading.
|| __parentPage && [PageStatus.Active, PageStatus.Deactivating].indexOf(__parentPage.status) >= 0
onSourceChanged: _alreadyLoaded = false onSourceChanged: _alreadyLoaded = false

View file

@ -26,6 +26,9 @@ Column {
readonly property int audioTrack: audioSelector.currentItem ? audioSelector.currentItem._index : 0 readonly property int audioTrack: audioSelector.currentItem ? audioSelector.currentItem._index : 0
readonly property int subtitleTrack: subitleSelector.currentItem._index readonly property int subtitleTrack: subitleSelector.currentItem._index
ListModel {
id: videoModel
}
ListModel { ListModel {
id: audioModel id: audioModel
} }
@ -34,6 +37,21 @@ Column {
id: subtitleModel id: subtitleModel
} }
ComboBox {
id: videoSelector
label: qsTr("Video track")
enabled: videoModel.count > 1
menu: ContextMenu {
Repeater {
model: videoModel
MenuItem {
readonly property int _index: model.index
text: model.displayTitle
}
}
}
}
ComboBox { ComboBox {
id: audioSelector id: audioSelector
label: qsTr("Audio track") label: qsTr("Audio track")
@ -80,6 +98,9 @@ Column {
for(var i = 0; i < tracks.length; i++) { for(var i = 0; i < tracks.length; i++) {
var track = tracks[i]; var track = tracks[i];
switch(track.type) { switch(track.type) {
case MediaStream.Video:
videoModel.append(track)
break;
case MediaStream.Audio: case MediaStream.Audio:
audioModel.append(track) audioModel.append(track)
break; break;

View file

@ -26,10 +26,10 @@ import "../components"
import ".." import ".."
CoverBackground { CoverBackground {
property var mData: appWindow.itemData property JellyfinItem mData: appWindow.itemData
RemoteImage { RemoteImage {
anchors.fill: parent anchors.fill: parent
source: Utils.itemImageUrl(ApiClient.baseUrl, itemData, "Primary", {"maxWidth": parent.width}) source: mData == null ? "" : Utils.itemImageUrl(ApiClient.baseUrl, mData, "Primary", {"maxWidth": parent.width})
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
onSourceChanged: console.log(source) onSourceChanged: console.log(source)
} }
@ -37,7 +37,7 @@ CoverBackground {
Shim { Shim {
// Movies usually show their name on the poster, // Movies usually show their name on the poster,
// so showing it here as well is a bit double // so showing it here as well is a bit double
visible: itemData.type !== "Movie" visible: mData.type !== "Movie"
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
@ -71,13 +71,13 @@ CoverBackground {
right: parent.right right: parent.right
} }
color: Theme.primaryColor color: Theme.primaryColor
text: itemData.name text: mData.name
truncationMode: TruncationMode.Fade truncationMode: TruncationMode.Fade
} }
Label { Label {
visible: typeof itemData.runTimeTicks !== "undefined" visible: typeof mData.runTimeTicks !== "undefined"
color: Theme.secondaryColor color: Theme.secondaryColor
text: Utils.ticksToText(itemData.runTimeTicks) text: Utils.ticksToText(mData.runTimeTicks)
} }
} }
} }

View file

@ -35,7 +35,7 @@ ApplicationWindow {
readonly property MediaPlayer mediaPlayer: _mediaPlayer readonly property MediaPlayer mediaPlayer: _mediaPlayer
// Data of the currently selected item. For use on the cover. // Data of the currently selected item. For use on the cover.
property var itemData property JellyfinItem itemData
// Id of the collection currently browsing. For use on the cover. // Id of the collection currently browsing. For use on the cover.
property string collectionId property string collectionId
@ -106,5 +106,8 @@ ApplicationWindow {
DisplayBlanking { DisplayBlanking {
preventBlanking: _mediaPlayer.playbackState == MediaPlayer.PlayingState && _mediaPlayer.hasVideo preventBlanking: _mediaPlayer.playbackState == MediaPlayer.PlayingState && _mediaPlayer.hasVideo
} }
DockedPanel {
}
} }

View file

@ -1,113 +0,0 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.6
import nl.netsoj.chris.Jellyfin 1.0
import Nemo.Notifications 1.0
import Nemo.KeepAlive 1.2
import "components"
import "pages"
ApplicationWindow {
id: appWindow
property bool _hasInitialized: false
// The global mediaPlayer instance
readonly property MediaPlayer mediaPlayer: _mediaPlayer
// Data of the currently selected item. For use on the cover.
property var itemData
// Id of the collection currently browsing. For use on the cover.
property string collectionId
//FIXME: proper error handling
Connections {
target: ApiClient
onNetworkError: errorNotification.show("Network error: " + error)
onConnectionFailed: errorNotification.show("Connect error: " + error)
//onConnectionSuccess: errorNotification.show("Success: " + loginMessage)
onSetupRequired: {
var isInSetup = pageStack.find(function (page) { return typeof page._isSetupPage !== "undefined" }) !== null
console.log("Is in setup: " + isInSetup)
if (!isInSetup) {
pageStack.replace(Qt.resolvedUrl("pages/setup/AddServerPage.qml"), {"backNavigation": false});
}
}
}
initialPage: Component {
MainPage {
Connections {
target: ApiClient
// Replace the MainPage if no server was set up.
}
onStatusChanged: {
if (status == PageStatus.Active && !_hasInitialized) {
_hasInitialized = true;
ApiClient.restoreSavedSession();
}
}
}
}
cover: {
if ([MediaPlayer.NoMedia, MediaPlayer.InvalidMedia, MediaPlayer.UnknownStatus].indexOf(mediaPlayer.status) >= 0) {
if (itemData) {
return Qt.resolvedUrl("cover/PosterCover.qml")
} else {
return Qt.resolvedUrl("cover/CoverPage.qml")
}
} else if (mediaPlayer.hasVideo){
return Qt.resolvedUrl("cover/VideoCover.qml")
}
}
allowedOrientations: Orientation.All
Notification {
id: errorNotification
previewSummary: "foo"
isTransient: true
function show(data) {
previewSummary = data;
publish();
}
}
MediaPlayer {
id: _mediaPlayer
autoPlay: true
}
// Keep the sytem alive while playing media
KeepAlive {
enabled: _mediaPlayer.playbackState == MediaPlayer.PlayingState
}
DisplayBlanking {
preventBlanking: _mediaPlayer.playbackState == MediaPlayer.PlayingState && _mediaPlayer.hasVideo
}
DockedPanel {
}
}

View file

@ -112,6 +112,12 @@ Page {
text: qsTr("Other") text: qsTr("Other")
} }
IconListItem {
text: qsTr("Debug information")
iconSource: "image://theme/icon-s-developer"
onClicked: pageStack.push(Qt.resolvedUrl("settings/DebugPage.qml"))
}
IconListItem { IconListItem {
text: qsTr("About Sailfin") text: qsTr("About Sailfin")
iconSource: "image://theme/icon-m-about" iconSource: "image://theme/icon-m-about"

View file

@ -0,0 +1,65 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import QtQuick 2.6
import Sailfish.Silica 1.0
import nl.netsoj.chris.Jellyfin 1.0
import "../../components"
Page {
id: page
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
SilicaFlickable {
anchors.fill: parent
contentHeight: content.height
Column {
id: content
width: parent.width
PageHeader {
title: qsTr("Debug information")
}
SectionHeader {
text: qsTr("Device profile")
}
SilicaFlickable {
anchors {
left: parent.left
leftMargin: Theme.horizontalPageMargin
right: parent.right
rightMargin: Theme.horizontalPageMargin
}
height: deviceProfile.contentHeight
contentWidth: deviceProfile.contentWidth
Label {
id: deviceProfile
color: Theme.secondaryHighlightColor
text: JSON.stringify(ApiClient.deviceProfile, null, '\t')
}
HorizontalScrollDecorator {}
}
}
VerticalScrollDecorator {}
}
}