mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2024-11-22 09:15:18 +00:00
Added more fields to Jellyfin::Item, update qml
* [UI] Improved: series season page now shows favourite and watched marks Refractored some more QML to support camelCase items
This commit is contained in:
parent
d81fa50715
commit
8a683df2a2
|
@ -13,6 +13,7 @@ SOURCES += \
|
||||||
src/jellyfinitem.cpp \
|
src/jellyfinitem.cpp \
|
||||||
src/jellyfinplaybackmanager.cpp \
|
src/jellyfinplaybackmanager.cpp \
|
||||||
src/jellyfinwebsocket.cpp \
|
src/jellyfinwebsocket.cpp \
|
||||||
|
src/jsonhelper.cpp \
|
||||||
src/serverdiscoverymodel.cpp
|
src/serverdiscoverymodel.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
@ -24,6 +25,7 @@ HEADERS += \
|
||||||
include/jellyfinitem.h \
|
include/jellyfinitem.h \
|
||||||
include/jellyfinplaybackmanager.h \
|
include/jellyfinplaybackmanager.h \
|
||||||
include/jellyfinwebsocket.h \
|
include/jellyfinwebsocket.h \
|
||||||
|
include/jsonhelper.h \
|
||||||
include/serverdiscoverymodel.h
|
include/serverdiscoverymodel.h
|
||||||
|
|
||||||
VERSION = $$SAILFIN_VERSION
|
VERSION = $$SAILFIN_VERSION
|
||||||
|
|
|
@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include "jellyfinapiclient.h"
|
#include "jellyfinapiclient.h"
|
||||||
|
#include "jsonhelper.h"
|
||||||
|
|
||||||
namespace Jellyfin {
|
namespace Jellyfin {
|
||||||
class SortOptions : public QObject{
|
class SortOptions : public QObject{
|
||||||
|
@ -243,9 +244,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void generateFields();
|
void generateFields();
|
||||||
QString sortByToString(SortOptions::SortBy sortBy);
|
QString sortByToString(SortOptions::SortBy sortBy);
|
||||||
|
|
||||||
void convertToCamelCase(QJsonValueRef val);
|
|
||||||
QString convertToCamelCaseHelper(const QString &str);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "jellyfinapiclient.h"
|
#include "jellyfinapiclient.h"
|
||||||
|
#include "jsonhelper.h"
|
||||||
|
|
||||||
namespace Jellyfin {
|
namespace Jellyfin {
|
||||||
class ApiClient;
|
class ApiClient;
|
||||||
|
@ -63,6 +64,7 @@ public:
|
||||||
private:
|
private:
|
||||||
QVariant jsonToVariant(QMetaProperty prop, const QJsonValue &val, const QJsonObject &root);
|
QVariant jsonToVariant(QMetaProperty prop, const QJsonValue &val, const QJsonObject &root);
|
||||||
QJsonValue variantToJson(const QVariant var) const;
|
QJsonValue variantToJson(const QVariant var) const;
|
||||||
|
QVariant deserializeQobject(const QJsonObject &obj, const QMetaProperty &prop);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the first letter of the string to lower case (to make it camelCase).
|
* @brief Sets the first letter of the string to lower case (to make it camelCase).
|
||||||
|
@ -278,6 +280,10 @@ public:
|
||||||
Q_PROPERTY(QString seasonName MEMBER m_seasonName NOTIFY seasonNameChanged)
|
Q_PROPERTY(QString seasonName MEMBER m_seasonName NOTIFY seasonNameChanged)
|
||||||
Q_PROPERTY(QList<MediaStream *> __list__mediaStreams MEMBER __list__m_mediaStreams NOTIFY mediaStreamsChanged)
|
Q_PROPERTY(QList<MediaStream *> __list__mediaStreams MEMBER __list__m_mediaStreams NOTIFY mediaStreamsChanged)
|
||||||
Q_PROPERTY(QVariantList mediaStreams MEMBER m_mediaStreams NOTIFY mediaStreamsChanged STORED false)
|
Q_PROPERTY(QVariantList mediaStreams MEMBER m_mediaStreams NOTIFY mediaStreamsChanged STORED false)
|
||||||
|
// Why is this a QJsonObject? Well, because I couldn't be bothered to implement the deserialisations of
|
||||||
|
// a QHash at the moment.
|
||||||
|
Q_PROPERTY(QJsonObject imageTags MEMBER m_imageTags NOTIFY imageTagsChanged)
|
||||||
|
Q_PROPERTY(QJsonObject imageBlurHashes MEMBER m_imageBlurHashes NOTIFY imageBlurHashesChanged)
|
||||||
|
|
||||||
QString jellyfinId() const { return m_id; }
|
QString jellyfinId() const { return m_id; }
|
||||||
void setJellyfinId(QString newId);
|
void setJellyfinId(QString newId);
|
||||||
|
@ -355,6 +361,8 @@ signals:
|
||||||
void seriesNameChanged(const QString &newSeriesName);
|
void seriesNameChanged(const QString &newSeriesName);
|
||||||
void seasonNameChanged(const QString &newSeasonName);
|
void seasonNameChanged(const QString &newSeasonName);
|
||||||
void mediaStreamsChanged(/*const QList<MediaStream *> &newMediaStreams*/);
|
void mediaStreamsChanged(/*const QList<MediaStream *> &newMediaStreams*/);
|
||||||
|
void imageTagsChanged();
|
||||||
|
void imageBlurHashesChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/**
|
/**
|
||||||
|
@ -402,6 +410,8 @@ protected:
|
||||||
QString m_seasonName;
|
QString m_seasonName;
|
||||||
QList<MediaStream *> __list__m_mediaStreams;
|
QList<MediaStream *> __list__m_mediaStreams;
|
||||||
QVariantList m_mediaStreams;
|
QVariantList m_mediaStreams;
|
||||||
|
QJsonObject m_imageTags;
|
||||||
|
QJsonObject m_imageBlurHashes;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
QQmlListProperty<T> toReadOnlyQmlListProperty(QList<T *> &list) {
|
QQmlListProperty<T> toReadOnlyQmlListProperty(QList<T *> &list) {
|
||||||
|
|
21
core/include/jsonhelper.h
Normal file
21
core/include/jsonhelper.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef JSON_SERIALIZER_H
|
||||||
|
#define JSON_SERIALIZER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
|
#include <QJsonValueRef>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Jellyfin {
|
||||||
|
|
||||||
|
namespace JsonHelper {
|
||||||
|
void convertToCamelCase(QJsonValueRef val);
|
||||||
|
QString convertToCamelCaseHelper(const QString &str);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // JSONSERIALIZER_H
|
|
@ -126,7 +126,7 @@ void ApiModel::load(LoadType type) {
|
||||||
this->beginInsertRows(QModelIndex(), m_array.size(), m_array.size() + items.size() - 1);
|
this->beginInsertRows(QModelIndex(), m_array.size(), m_array.size() + items.size() - 1);
|
||||||
// QJsonArray apparently doesn't allow concatenating lists like QList or std::vector
|
// QJsonArray apparently doesn't allow concatenating lists like QList or std::vector
|
||||||
for (auto it = items.begin(); it != items.end(); it++) {
|
for (auto it = items.begin(); it != items.end(); it++) {
|
||||||
convertToCamelCase(*it);
|
JsonHelper::convertToCamelCase(*it);
|
||||||
}
|
}
|
||||||
foreach (const QJsonValue &val, items) {
|
foreach (const QJsonValue &val, items) {
|
||||||
m_array.append(val);
|
m_array.append(val);
|
||||||
|
@ -165,7 +165,7 @@ void ApiModel::generateFields() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto it = m_array.begin(); it != m_array.end(); it++){
|
for (auto it = m_array.begin(); it != m_array.end(); it++){
|
||||||
convertToCamelCase(*it);
|
JsonHelper::convertToCamelCase(*it);
|
||||||
}
|
}
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
}
|
}
|
||||||
|
@ -212,37 +212,7 @@ void ApiModel::fetchMore(const QModelIndex &parent) {
|
||||||
|
|
||||||
void ApiModel::addQueryParameters(QUrlQuery &query) { Q_UNUSED(query)}
|
void ApiModel::addQueryParameters(QUrlQuery &query) { Q_UNUSED(query)}
|
||||||
|
|
||||||
void ApiModel::convertToCamelCase(QJsonValueRef val) {
|
|
||||||
switch(val.type()) {
|
|
||||||
case QJsonValue::Object: {
|
|
||||||
QJsonObject obj = val.toObject();
|
|
||||||
for(const QString &key: obj.keys()) {
|
|
||||||
QJsonValueRef ref = obj[key];
|
|
||||||
convertToCamelCase(ref);
|
|
||||||
obj[convertToCamelCaseHelper(key)] = ref;
|
|
||||||
obj.remove(key);
|
|
||||||
}
|
|
||||||
val = obj;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QJsonValue::Array: {
|
|
||||||
QJsonArray arr = val.toArray();
|
|
||||||
for (auto it = arr.begin(); it != arr.end(); it++) {
|
|
||||||
convertToCamelCase(*it);
|
|
||||||
}
|
|
||||||
val = arr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ApiModel::convertToCamelCaseHelper(const QString &str) {
|
|
||||||
QString res(str);
|
|
||||||
res[0] = res[0].toLower();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Itemmodel
|
// Itemmodel
|
||||||
|
|
|
@ -87,6 +87,18 @@ QVariant JsonSerializable::jsonToVariant(QMetaProperty prop, const QJsonValue &v
|
||||||
}
|
}
|
||||||
case QJsonValue::Object:
|
case QJsonValue::Object:
|
||||||
QJsonObject innerObj = val.toObject();
|
QJsonObject innerObj = val.toObject();
|
||||||
|
if (prop.userType() == QMetaType::QJsonObject) {
|
||||||
|
QJsonArray tmp = {innerObj };
|
||||||
|
JsonHelper::convertToCamelCase(QJsonValueRef(&tmp, 0));
|
||||||
|
return QVariant(innerObj);
|
||||||
|
} else {
|
||||||
|
return deserializeQobject(innerObj, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant JsonSerializable::deserializeQobject(const QJsonObject &innerObj, const QMetaProperty &prop) {
|
||||||
int typeNo = prop.userType();
|
int typeNo = prop.userType();
|
||||||
const QMetaObject *metaType = QMetaType::metaObjectForType(prop.userType());
|
const QMetaObject *metaType = QMetaType::metaObjectForType(prop.userType());
|
||||||
if (metaType == nullptr) {
|
if (metaType == nullptr) {
|
||||||
|
@ -119,8 +131,6 @@ QVariant JsonSerializable::jsonToVariant(QMetaProperty prop, const QJsonValue &v
|
||||||
qDebug() << "Object is not a serializable one!";
|
qDebug() << "Object is not a serializable one!";
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject JsonSerializable::serialize(bool capitalize) const {
|
QJsonObject JsonSerializable::serialize(bool capitalize) const {
|
||||||
|
|
40
core/src/jsonhelper.cpp
Normal file
40
core/src/jsonhelper.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "jsonhelper.h"
|
||||||
|
|
||||||
|
namespace Jellyfin {
|
||||||
|
|
||||||
|
namespace JsonHelper {
|
||||||
|
|
||||||
|
void convertToCamelCase(QJsonValueRef val) {
|
||||||
|
switch(val.type()) {
|
||||||
|
case QJsonValue::Object: {
|
||||||
|
QJsonObject obj = val.toObject();
|
||||||
|
for(const QString &key: obj.keys()) {
|
||||||
|
QJsonValueRef ref = obj[key];
|
||||||
|
convertToCamelCase(ref);
|
||||||
|
obj[convertToCamelCaseHelper(key)] = ref;
|
||||||
|
obj.remove(key);
|
||||||
|
}
|
||||||
|
val = obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QJsonValue::Array: {
|
||||||
|
QJsonArray arr = val.toArray();
|
||||||
|
for (auto it = arr.begin(); it != arr.end(); it++) {
|
||||||
|
convertToCamelCase(*it);
|
||||||
|
}
|
||||||
|
val = arr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString convertToCamelCaseHelper(const QString &str) {
|
||||||
|
QString res(str);
|
||||||
|
res[0] = res[0].toLower();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // NS JsonHelper
|
||||||
|
} // NS Jellyfin
|
|
@ -79,7 +79,7 @@ CoverBackground {
|
||||||
clip: true
|
clip: true
|
||||||
height: row1.height
|
height: row1.height
|
||||||
width: height
|
width: height
|
||||||
source: model.id ? Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags["Primary"], "Primary", {"maxHeight": row1.height})
|
source: model.id ? Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags.primary, "Primary", {"maxHeight": row1.height})
|
||||||
: ""
|
: ""
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ CoverBackground {
|
||||||
clip: true
|
clip: true
|
||||||
height: row2.height
|
height: row2.height
|
||||||
width: height
|
width: height
|
||||||
source: Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags["Primary"], "Primary", {"maxHeight": row1.height})
|
source: Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags.primary, "Primary", {"maxHeight": row1.height})
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,15 @@ CoverBackground {
|
||||||
property var mData: appWindow.itemData
|
property var mData: appWindow.itemData
|
||||||
RemoteImage {
|
RemoteImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: mData.ImageTags["Primary"] ? ApiClient.baseUrl + "/Items/" + mData.Id
|
source: Utils.itemImageUrl(ApiClient.baseUrl, itemData, "Primary", {"maxWidth": parent.width})
|
||||||
+ "/Images/Primary?maxHeight=" + height + "&tag=" + mData.ImageTags["Primary"]
|
|
||||||
: ""
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
onSourceChanged: console.log(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
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: itemData.type !== "Movie"
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@ -52,7 +51,7 @@ CoverBackground {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
}
|
}
|
||||||
width: itemData.UserData.PlayedPercentage / 100 * parent.width
|
width: itemData.userData.playedPercentage / 100 * parent.width
|
||||||
height: Theme.paddingSmall
|
height: Theme.paddingSmall
|
||||||
color: Theme.highlightColor
|
color: Theme.highlightColor
|
||||||
}
|
}
|
||||||
|
@ -72,13 +71,13 @@ CoverBackground {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
}
|
}
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
text: itemData.Name
|
text: itemData.name
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
visible: typeof itemData.RunTimeTicks !== "undefined"
|
visible: typeof itemData.runTimeTicks !== "undefined"
|
||||||
color: Theme.secondaryColor
|
color: Theme.secondaryColor
|
||||||
text: Utils.ticksToText(itemData.RunTimeTicks)
|
text: Utils.ticksToText(itemData.runTimeTicks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,30 +25,22 @@ import nl.netsoj.chris.Jellyfin 1.0
|
||||||
|
|
||||||
import "../components"
|
import "../components"
|
||||||
|
|
||||||
CoverBackground {
|
PosterCover {
|
||||||
readonly property MediaPlayer player: appWindow.mediaPlayer
|
readonly property MediaPlayer player: appWindow.mediaPlayer
|
||||||
property var mData: appWindow.itemData
|
property var mData: appWindow.itemData
|
||||||
|
|
||||||
Rectangle {
|
// Wanted to display the currently running move on here, but it's hard :/
|
||||||
|
/*Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "black"
|
color: "black"
|
||||||
|
|
||||||
// Wanted to display the currently running move on here, but it's hard :/
|
VideoOutput {
|
||||||
/*VideoOutput {
|
|
||||||
id: coverOutput
|
id: coverOutput
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: player
|
source: player
|
||||||
}*/
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
// As a temporary fallback, use the poster image
|
|
||||||
RemoteImage {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: mData.ImageTags["Primary"] ? ApiClient.baseUrl + "/Items/" + mData.Id
|
|
||||||
+ "/Images/Primary?maxHeight=" + height + "&tag=" + mData.ImageTags["Primary"]
|
|
||||||
: ""
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
}
|
|
||||||
|
|
||||||
Shim {
|
Shim {
|
||||||
anchors {
|
anchors {
|
||||||
|
|
|
@ -83,7 +83,7 @@ Page {
|
||||||
//appWindow.itemData = ({})
|
//appWindow.itemData = ({})
|
||||||
}
|
}
|
||||||
if (status == PageStatus.Active) {
|
if (status == PageStatus.Active) {
|
||||||
|
appWindow.itemData = jItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ BaseDetailPage {
|
||||||
cellHeight: Utils.usePortraitCover(itemData.CollectionType) ? Constants.libraryDelegatePosterHeight
|
cellHeight: Utils.usePortraitCover(itemData.CollectionType) ? Constants.libraryDelegatePosterHeight
|
||||||
: Constants.libraryDelegateHeight
|
: Constants.libraryDelegateHeight
|
||||||
header: PageHeader {
|
header: PageHeader {
|
||||||
title: itemData.Name || qsTr("Loading")
|
title: itemData.name || qsTr("Loading")
|
||||||
}
|
}
|
||||||
PullDownMenu {
|
PullDownMenu {
|
||||||
id: downMenu
|
id: downMenu
|
||||||
|
@ -58,7 +58,7 @@ BaseDetailPage {
|
||||||
RemoteImage {
|
RemoteImage {
|
||||||
id: itemImage
|
id: itemImage
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags["Primary"], "Primary", {"maxWidth": width})
|
source: Utils.itemModelImageUrl(ApiClient.baseUrl, model.id, model.imageTags.primary, "Primary", {"maxWidth": width})
|
||||||
fallbackColor: Utils.colorFromString(model.name)
|
fallbackColor: Utils.colorFromString(model.name)
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
clip: true
|
clip: true
|
||||||
|
|
|
@ -68,7 +68,7 @@ BaseDetailPage {
|
||||||
shimColor: Theme.overlayBackgroundColor
|
shimColor: Theme.overlayBackgroundColor
|
||||||
shimOpacity: Theme.opacityOverlay
|
shimOpacity: Theme.opacityOverlay
|
||||||
//width: model.userData.PlayedPercentage * parent.width / 100
|
//width: model.userData.PlayedPercentage * parent.width / 100
|
||||||
visible: episodeProgress.width > 0 // It doesn't look nice when it's visible on every image
|
visible: episodeProgress.width > 0 || model.userData.played || model.userData.isFavorite // It doesn't look nice when it's visible on every image
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -81,6 +81,25 @@ BaseDetailPage {
|
||||||
width: model.userData.playedPercentage * parent.width / 100
|
width: model.userData.playedPercentage * parent.width / 100
|
||||||
color: Theme.highlightColor
|
color: Theme.highlightColor
|
||||||
}
|
}
|
||||||
|
Row {
|
||||||
|
spacing: Theme.paddingSmall
|
||||||
|
anchors {
|
||||||
|
bottom: episodeProgress.width > 0 ? episodeProgress.top : parent.bottom
|
||||||
|
bottomMargin: Theme.paddingMedium
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.paddingMedium
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon {
|
||||||
|
source: "image://theme/icon-s-checkmark"
|
||||||
|
visible: model.userData.played
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon {
|
||||||
|
source: "image://theme/icon-s-favorite"
|
||||||
|
visible: model.userData.isFavorite
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
@ -129,7 +148,7 @@ BaseDetailPage {
|
||||||
}
|
}
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status == PageStatus.Active) {
|
if (status == PageStatus.Active) {
|
||||||
console.log(JSON.stringify(itemData))
|
//console.log(JSON.stringify(itemData))
|
||||||
episodeModel.show = itemData.seriesId
|
episodeModel.show = itemData.seriesId
|
||||||
episodeModel.seasonId = itemData.jellyfinId
|
episodeModel.seasonId = itemData.jellyfinId
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue