mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2024-11-22 09:15:18 +00:00
Added debug page, fix RemoteImage on covers
This commit is contained in:
parent
eda4994aac
commit
5ddd5e8e2e
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -32,6 +32,7 @@ BackgroundItem {
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
bottomMargin: Theme.paddingMedium
|
bottomMargin: Theme.paddingMedium
|
||||||
}
|
}
|
||||||
|
width: height
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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"
|
||||||
|
|
65
sailfish/qml/pages/settings/DebugPage.qml
Normal file
65
sailfish/qml/pages/settings/DebugPage.qml
Normal 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 {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue