From 5ddd5e8e2e0dba3ae6f447c3fcac5341c05775ba Mon Sep 17 00:00:00 2001 From: Chris Josten Date: Sat, 13 Feb 2021 21:42:57 +0100 Subject: [PATCH] Added debug page, fix RemoteImage on covers --- core/include/JellyfinQt/jellyfinapiclient.h | 3 + core/src/jellyfinapiclient.cpp | 1 + core/src/jellyfindeviceprofile.cpp | 2 +- sailfish/CMakeLists.txt | 2 +- sailfish/qml/components/IconListItem.qml | 1 + sailfish/qml/components/RemoteImage.qml | 4 +- .../qml/components/VideoTrackSelector.qml | 21 ++++ sailfish/qml/cover/PosterCover.qml | 12 +- sailfish/qml/harbour-sailfin.qml | 5 +- sailfish/qml/harbour-sailfin.qml.autosave | 113 ------------------ sailfish/qml/pages/SettingsPage.qml | 6 + sailfish/qml/pages/settings/DebugPage.qml | 65 ++++++++++ 12 files changed, 112 insertions(+), 123 deletions(-) delete mode 100644 sailfish/qml/harbour-sailfin.qml.autosave create mode 100644 sailfish/qml/pages/settings/DebugPage.qml diff --git a/core/include/JellyfinQt/jellyfinapiclient.h b/core/include/JellyfinQt/jellyfinapiclient.h index 5dcb5a0..1a6c4da 100644 --- a/core/include/JellyfinQt/jellyfinapiclient.h +++ b/core/include/JellyfinQt/jellyfinapiclient.h @@ -77,6 +77,7 @@ public: Q_PROPERTY(QString baseUrl MEMBER m_baseUrl READ baseUrl NOTIFY baseUrlChanged) Q_PROPERTY(bool authenticated READ authenticated WRITE setAuthenticated NOTIFY authenticatedChanged) Q_PROPERTY(QString userId READ userId NOTIFY userIdChanged) + Q_PROPERTY(QJsonObject deviceProfile READ deviceProfile NOTIFY deviceProfileChanged) Q_PROPERTY(QString version READ version) /*QNetworkReply *handleRequest(QString path, QStringList sort, Pagination *pagination, @@ -145,6 +146,8 @@ signals: void itemFetched(const QString &itemId, const QJsonObject &result); 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. * @param itemId The id of the item being changed diff --git a/core/src/jellyfinapiclient.cpp b/core/src/jellyfinapiclient.cpp index f9e5322..1932476 100644 --- a/core/src/jellyfinapiclient.cpp +++ b/core/src/jellyfinapiclient.cpp @@ -265,6 +265,7 @@ void ApiClient::generateDeviceProfile() { root["PlayableMediaTypes"] = playableMediaTypes; m_deviceProfile = root; + emit deviceProfileChanged(); } void ApiClient::defaultNetworkErrorHandler(QNetworkReply::NetworkError error) { diff --git a/core/src/jellyfindeviceprofile.cpp b/core/src/jellyfindeviceprofile.cpp index 1dca3fd..c40a76e 100644 --- a/core/src/jellyfindeviceprofile.cpp +++ b/core/src/jellyfindeviceprofile.cpp @@ -80,7 +80,7 @@ QJsonObject DeviceProfile::generateProfile() { JsonPair("Type", "VideoAudio") }); codecProfiles.append(QJsonObject { - JsonPair("Coded", "h264"), + JsonPair("Codec", "h264"), JsonPair("Conditions", QJsonArray { QJsonObject { JsonPair("Property", "IsAnamorphic"), diff --git a/sailfish/CMakeLists.txt b/sailfish/CMakeLists.txt index a098c3e..0facdc9 100644 --- a/sailfish/CMakeLists.txt +++ b/sailfish/CMakeLists.txt @@ -25,7 +25,6 @@ set(sailfin_QML_SOURCES qml/components/music/SongDelegate.qml qml/components/videoplayer/VideoError.qml qml/components/videoplayer/VideoHud.qml - qml/components/GlassyBackground.qml qml/components/IconListItem.qml qml/components/LibraryItemDelegate.qml qml/components/MoreSection.qml @@ -55,6 +54,7 @@ set(sailfin_QML_SOURCES qml/pages/itemdetails/SeriesPage.qml qml/pages/itemdetails/UnsupportedPage.qml qml/pages/itemdetails/VideoPage.qml + qml/pages/settings/DebugPage.qml qml/pages/setup/AddServerConnectingPage.qml qml/pages/setup/LoginDialog.qml qml/qmldir) diff --git a/sailfish/qml/components/IconListItem.qml b/sailfish/qml/components/IconListItem.qml index 122c9dc..b3e2dd8 100644 --- a/sailfish/qml/components/IconListItem.qml +++ b/sailfish/qml/components/IconListItem.qml @@ -32,6 +32,7 @@ BackgroundItem { bottom: parent.bottom bottomMargin: Theme.paddingMedium } + width: height } Label { diff --git a/sailfish/qml/components/RemoteImage.qml b/sailfish/qml/components/RemoteImage.qml index 88e8988..ade3c7a 100644 --- a/sailfish/qml/components/RemoteImage.qml +++ b/sailfish/qml/components/RemoteImage.qml @@ -36,7 +36,9 @@ SilicaItem { property var __parentPage : null 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 diff --git a/sailfish/qml/components/VideoTrackSelector.qml b/sailfish/qml/components/VideoTrackSelector.qml index 92931a7..519f8a2 100644 --- a/sailfish/qml/components/VideoTrackSelector.qml +++ b/sailfish/qml/components/VideoTrackSelector.qml @@ -26,6 +26,9 @@ Column { readonly property int audioTrack: audioSelector.currentItem ? audioSelector.currentItem._index : 0 readonly property int subtitleTrack: subitleSelector.currentItem._index + ListModel { + id: videoModel + } ListModel { id: audioModel } @@ -34,6 +37,21 @@ Column { 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 { id: audioSelector label: qsTr("Audio track") @@ -80,6 +98,9 @@ Column { for(var i = 0; i < tracks.length; i++) { var track = tracks[i]; switch(track.type) { + case MediaStream.Video: + videoModel.append(track) + break; case MediaStream.Audio: audioModel.append(track) break; diff --git a/sailfish/qml/cover/PosterCover.qml b/sailfish/qml/cover/PosterCover.qml index 74761d4..e40bf1f 100644 --- a/sailfish/qml/cover/PosterCover.qml +++ b/sailfish/qml/cover/PosterCover.qml @@ -26,10 +26,10 @@ import "../components" import ".." CoverBackground { - property var mData: appWindow.itemData + property JellyfinItem mData: appWindow.itemData RemoteImage { 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 onSourceChanged: console.log(source) } @@ -37,7 +37,7 @@ CoverBackground { Shim { // Movies usually show their name on the poster, // so showing it here as well is a bit double - visible: itemData.type !== "Movie" + visible: mData.type !== "Movie" anchors { left: parent.left right: parent.right @@ -71,13 +71,13 @@ CoverBackground { right: parent.right } color: Theme.primaryColor - text: itemData.name + text: mData.name truncationMode: TruncationMode.Fade } Label { - visible: typeof itemData.runTimeTicks !== "undefined" + visible: typeof mData.runTimeTicks !== "undefined" color: Theme.secondaryColor - text: Utils.ticksToText(itemData.runTimeTicks) + text: Utils.ticksToText(mData.runTimeTicks) } } } diff --git a/sailfish/qml/harbour-sailfin.qml b/sailfish/qml/harbour-sailfin.qml index ebfd280..6da8128 100644 --- a/sailfish/qml/harbour-sailfin.qml +++ b/sailfish/qml/harbour-sailfin.qml @@ -35,7 +35,7 @@ ApplicationWindow { readonly property MediaPlayer mediaPlayer: _mediaPlayer // 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. property string collectionId @@ -106,5 +106,8 @@ ApplicationWindow { DisplayBlanking { preventBlanking: _mediaPlayer.playbackState == MediaPlayer.PlayingState && _mediaPlayer.hasVideo } + + DockedPanel { + } } diff --git a/sailfish/qml/harbour-sailfin.qml.autosave b/sailfish/qml/harbour-sailfin.qml.autosave deleted file mode 100644 index 15648fe..0000000 --- a/sailfish/qml/harbour-sailfin.qml.autosave +++ /dev/null @@ -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 { - } - -} diff --git a/sailfish/qml/pages/SettingsPage.qml b/sailfish/qml/pages/SettingsPage.qml index fcf7860..2c65732 100644 --- a/sailfish/qml/pages/SettingsPage.qml +++ b/sailfish/qml/pages/SettingsPage.qml @@ -112,6 +112,12 @@ Page { text: qsTr("Other") } + IconListItem { + text: qsTr("Debug information") + iconSource: "image://theme/icon-s-developer" + onClicked: pageStack.push(Qt.resolvedUrl("settings/DebugPage.qml")) + } + IconListItem { text: qsTr("About Sailfin") iconSource: "image://theme/icon-m-about" diff --git a/sailfish/qml/pages/settings/DebugPage.qml b/sailfish/qml/pages/settings/DebugPage.qml new file mode 100644 index 0000000..b27ca4a --- /dev/null +++ b/sailfish/qml/pages/settings/DebugPage.qml @@ -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 {} + } +}