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

Repair broken userdata.

The UserData of an item was not displaying, this should re-add it.
This commit is contained in:
Chris Josten 2021-08-17 16:43:17 +02:00
parent 7b6c272aa9
commit bb1e3ea21d
13 changed files with 79 additions and 41 deletions

View file

@ -36,6 +36,7 @@
#include "viewmodel/loader.h" #include "viewmodel/loader.h"
#include "viewmodel/modelstatus.h" #include "viewmodel/modelstatus.h"
#include "viewmodel/playbackmanager.h" #include "viewmodel/playbackmanager.h"
#include "viewmodel/userdata.h"
namespace Jellyfin { namespace Jellyfin {

View file

@ -37,6 +37,7 @@ class Item : public QObject, public DTO::BaseItemDto {
Q_OBJECT Q_OBJECT
public: public:
using UserDataChangedCallback = std::function<void(DTO::UserItemDataDto)>; using UserDataChangedCallback = std::function<void(DTO::UserItemDataDto)>;
using BaseItemDto::userData;
/** /**
* @brief Constructor that creates an empty item. * @brief Constructor that creates an empty item.
*/ */

View file

@ -100,7 +100,7 @@ public:
Q_PROPERTY(QString type READ type NOTIFY typeChanged) Q_PROPERTY(QString type READ type NOTIFY typeChanged)
Q_PROPERTY(QString parentBackdropItemId READ parentBackdropItemId NOTIFY parentBackdropItemIdChanged) Q_PROPERTY(QString parentBackdropItemId READ parentBackdropItemId NOTIFY parentBackdropItemIdChanged)
Q_PROPERTY(QStringList parentBackdropImageTags READ parentBackdropImageTags NOTIFY parentBackdropImageTagsChanged) Q_PROPERTY(QStringList parentBackdropImageTags READ parentBackdropImageTags NOTIFY parentBackdropImageTagsChanged)
Q_PROPERTY(UserData *userData READ userData NOTIFY userDataChanged) Q_PROPERTY(Jellyfin::ViewModel::UserData *userData READ userData NOTIFY userDataChanged)
Q_PROPERTY(int recursiveItemCount READ recursiveItemCount NOTIFY recursiveItemCountChanged) Q_PROPERTY(int recursiveItemCount READ recursiveItemCount NOTIFY recursiveItemCountChanged)
Q_PROPERTY(int childCount READ childCount NOTIFY childCountChanged) Q_PROPERTY(int childCount READ childCount NOTIFY childCountChanged)
Q_PROPERTY(QString albumArtist READ albumArtist NOTIFY albumArtistChanged) Q_PROPERTY(QString albumArtist READ albumArtist NOTIFY albumArtistChanged)

View file

@ -28,6 +28,7 @@
#include "../loader/http/getuserviews.h" #include "../loader/http/getuserviews.h"
#include "../loader/requesttypes.h" #include "../loader/requesttypes.h"
#include "../model/item.h" #include "../model/item.h"
#include "../viewmodel/item.h"
#include "../apimodel.h" #include "../apimodel.h"
#include "modelstatus.h" #include "modelstatus.h"
#include "propertyhelper.h" #include "propertyhelper.h"
@ -268,6 +269,16 @@ public:
artists, artists,
isFolder, isFolder,
parentIndexNumber, parentIndexNumber,
userDataRating,
userDataPlayedPercentage,
userDataUnplayedItemCount,
userDataPlaybackPositionTicks,
userDataPlayCount,
userDataFavorite,
userDataLikes,
userDataLastPlayedDate,
userDataPlayed,
userDataKey,
jellyfinExtendModelAfterHere = Qt::UserRole + 300 // Should be enough for now jellyfinExtendModelAfterHere = Qt::UserRole + 300 // Should be enough for now
}; };
@ -297,41 +308,22 @@ public:
JFRN(artists), JFRN(artists),
JFRN(isFolder), JFRN(isFolder),
JFRN(parentIndexNumber), JFRN(parentIndexNumber),
JFRN(userDataRating),
JFRN(userDataPlayedPercentage),
JFRN(userDataUnplayedItemCount),
JFRN(userDataPlaybackPositionTicks),
JFRN(userDataPlayCount),
JFRN(userDataFavorite),
JFRN(userDataLikes),
JFRN(userDataLastPlayedDate),
JFRN(userDataPlayed),
JFRN(userDataKey),
}; };
} }
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
QSharedPointer<Model::Item> itemAt(int index); QSharedPointer<Model::Item> itemAt(int index);
}; };
/*class UserItemModel : public ItemModel {
public:
explicit UserItemModel (QObject *parent = nullptr);
};
class UserItemResumeModel : public ItemModel {
public:
explicit UserItemResumeModel (QObject *parent = nullptr);
};
class UserItemLatestModel : public ItemModel {
public:
explicit UserItemLatestModel (QObject *parent = nullptr);
};
class ShowNextUpModel : public ItemModel {
public:
explicit ShowNextUpModel (QObject *parent = nullptr);
};
class ShowSeasonsModel : public ItemModel {
public:
explicit ShowSeasonsModel (QObject *parent = nullptr);
};
class ShowEpisodesModel : public ItemModel {
public:
explicit ShowEpisodesModel (QObject *parent = nullptr);
};*/
#undef JFRN #undef JFRN
} // NS Jellyfin } // NS Jellyfin

View file

@ -26,6 +26,7 @@ void registerTypes(const char *uri) {
qmlRegisterUncreatableType<ViewModel::Item>(uri, 1, 0, "Item", "Acquire one via ItemLoader or exposed properties"); qmlRegisterUncreatableType<ViewModel::Item>(uri, 1, 0, "Item", "Acquire one via ItemLoader or exposed properties");
qmlRegisterUncreatableType<EventBus>(uri, 1, 0, "EventBus", "Obtain one via your ApiClient"); qmlRegisterUncreatableType<EventBus>(uri, 1, 0, "EventBus", "Obtain one via your ApiClient");
qmlRegisterUncreatableType<WebSocket>(uri, 1, 0, "WebSocket", "Obtain one via your ApiClient"); qmlRegisterUncreatableType<WebSocket>(uri, 1, 0, "WebSocket", "Obtain one via your ApiClient");
qmlRegisterUncreatableType<ViewModel::UserData>(uri, 1, 0, "UserData", "Obtain one via an Item");
// AbstractItemModels // AbstractItemModels
qmlRegisterUncreatableType<BaseApiModel>(uri, 1, 0, "BaseApiModel", "Please use one of its subclasses"); qmlRegisterUncreatableType<BaseApiModel>(uri, 1, 0, "BaseApiModel", "Please use one of its subclasses");

View file

@ -27,16 +27,21 @@ Item::Item(QObject *parent, QSharedPointer<Model::Item> data)
m_data(data), m_data(data),
m_userData(new UserData(this)){ m_userData(new UserData(this)){
connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged); connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged);
m_userData->setData(data->userData());
} }
void Item::setData(QSharedPointer<Model::Item> newData) { void Item::setData(QSharedPointer<Model::Item> newData) {
if (!m_data.isNull()) { if (!m_data.isNull()) {
disconnect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged); disconnect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged);
} }
m_data = newData; m_data = newData;
if (!m_data.isNull()) { if (!m_data.isNull()) {
connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged); connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged);
setUserData(m_data->userData());
} }
emit userDataChanged(m_userData);
} }
void Item::setUserData(DTO::UserItemDataDto &newData) { void Item::setUserData(DTO::UserItemDataDto &newData) {
@ -44,7 +49,11 @@ void Item::setUserData(DTO::UserItemDataDto &newData) {
} }
void Item::setUserData(QSharedPointer<DTO::UserItemDataDto> newData) { void Item::setUserData(QSharedPointer<DTO::UserItemDataDto> newData) {
m_userData->setData(newData); if (m_data.isNull() || m_data->userData().isNull()) {
m_userData->setData(QSharedPointer<DTO::UserData>::create());
} else {
m_userData->setData(newData);
}
emit userDataChanged(m_userData); emit userDataChanged(m_userData);
} }

View file

@ -24,6 +24,8 @@
#include "JellyfinQt/loader/http/getresumeitems.h" #include "JellyfinQt/loader/http/getresumeitems.h"
#include "JellyfinQt/loader/http/getseasons.h" #include "JellyfinQt/loader/http/getseasons.h"
#include "JellyfinQt/viewmodel/userdata.h"
#define JF_CASE(roleName) case roleName: \ #define JF_CASE(roleName) case roleName: \
try { \ try { \
return QVariant(item->roleName()); \ return QVariant(item->roleName()); \
@ -87,6 +89,27 @@ QVariant ItemModel::data(const QModelIndex &index, int role) const {
return QVariant(item->isFolder().value_or(false)); return QVariant(item->isFolder().value_or(false));
case RoleNames::parentIndexNumber: case RoleNames::parentIndexNumber:
return QVariant(item->parentIndexNumber().value_or(1)); return QVariant(item->parentIndexNumber().value_or(1));
// UserData
case RoleNames::userDataRating:
return QVariant(item->userData()->rating().value_or(0.0));
case RoleNames::userDataPlayedPercentage:
return QVariant(item->userData()->playedPercentage().value_or(0.0));
case RoleNames::userDataUnplayedItemCount:
return QVariant(item->userData()->unplayedItemCount().value_or(0));
case RoleNames::userDataPlaybackPositionTicks:
return QVariant(item->userData()->playbackPositionTicks());
case RoleNames::userDataPlayCount:
return QVariant(item->userData()->playCount());
case RoleNames::userDataFavorite:
return QVariant(item->userData()->isFavorite());
case RoleNames::userDataLikes:
return QVariant(item->userData()->likes().value_or(false));
case RoleNames::userDataLastPlayedDate:
return QVariant(item->userData()->lastPlayedDate());
case RoleNames::userDataPlayed:
return QVariant(item->userData()->played());
case RoleNames::userDataKey:
return QVariant(item->userData()->key());
default: default:
return QVariant(); return QVariant();
} }

View file

@ -22,17 +22,24 @@ namespace Jellyfin {
namespace ViewModel { namespace ViewModel {
UserData::UserData(QObject *parent) UserData::UserData(QObject *parent)
: QObject(parent), : UserData(QSharedPointer<DTO::UserItemDataDto>::create(), parent) {
m_data(QSharedPointer<DTO::UserItemDataDto>::create()) {
} }
UserData::UserData(QSharedPointer<DTO::UserItemDataDto> data, QObject *parent) UserData::UserData(QSharedPointer<DTO::UserItemDataDto> data, QObject *parent)
: QObject(parent), : QObject(parent),
m_data(data) { m_data(data) {
if (m_data.isNull()) {
m_data = QSharedPointer<DTO::UserItemDataDto>::create();
}
} }
void UserData::setData(QSharedPointer<DTO::UserItemDataDto> data) { void UserData::setData(QSharedPointer<DTO::UserItemDataDto> data) {
m_data = data; if (data.isNull()) {
m_data = QSharedPointer<DTO::UserItemDataDto>::create();
} else {
m_data = data;
}
} }
} // NS ViewModel } // NS ViewModel

View file

@ -51,6 +51,9 @@ Page {
height: parent.height / 3 * 2 height: parent.height / 3 * 2
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
model: tracks model: tracks
header: Label {
text: "Play count: %1".arg(jellyfinItem.userData.playCount)
}
delegate: ItemDelegate { delegate: ItemDelegate {
icon.source: ApiClient.baseUrl + "/Items/" + model.jellyfinId + "/Images/Primary?tag=" + model.tag icon.source: ApiClient.baseUrl + "/Items/" + model.jellyfinId + "/Images/Primary?tag=" + model.tag
text: model.name text: model.name

BIN
qtquick/test.rcc Normal file

Binary file not shown.

View file

@ -34,6 +34,7 @@ Page {
id: pageRoot id: pageRoot
property string itemId: "" property string itemId: ""
property alias itemData: jItemLoader.data property alias itemData: jItemLoader.data
property alias itemLoader: jItemLoader
property bool _loading: jItemLoader.status === J.ItemLoader.Loading property bool _loading: jItemLoader.status === J.ItemLoader.Loading
readonly property bool hasLogo: (typeof itemData.imageTags !== "undefined") && (typeof itemData.imageTags["Logo"] !== "undefined") readonly property bool hasLogo: (typeof itemData.imageTags !== "undefined") && (typeof itemData.imageTags["Logo"] !== "undefined")
property string _chosenBackdropImage: "" property string _chosenBackdropImage: ""

View file

@ -79,7 +79,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 || model.userData.played || model.userData.isFavorite // It doesn't look nice when it's visible on every image visible: episodeProgress.width > 0 || model.userDataPlayed || model.userDataFavorite // It doesn't look nice when it's visible on every image
} }
Rectangle { Rectangle {
@ -89,7 +89,7 @@ BaseDetailPage {
bottom: parent.bottom bottom: parent.bottom
} }
height: Theme.paddingMedium height: Theme.paddingMedium
width: model.userData.playedPercentage * parent.width / 100 width: model.userDataPlayedPercentage * parent.width / 100
color: Theme.highlightColor color: Theme.highlightColor
} }
Row { Row {
@ -103,12 +103,12 @@ BaseDetailPage {
Icon { Icon {
source: "image://theme/icon-s-checkmark" source: "image://theme/icon-s-checkmark"
visible: model.userData.played visible: model.userDataPlayed
} }
Icon { Icon {
source: "image://theme/icon-s-favorite" source: "image://theme/icon-s-favorite"
visible: model.userData.isFavorite visible: model.userDataFavorite
} }
} }
} }

View file

@ -33,7 +33,7 @@ BaseDetailPage {
property alias subtitle: pageHeader.description property alias subtitle: pageHeader.description
default property alias _data: content.data default property alias _data: content.data
property real _playbackProsition: itemData.userData.playbackPositionTicks property real _playbackProsition: itemData.userData.playbackPositionTicks
readonly property bool _userdataReady: itemData.status === J.ItemLoader.Ready && itemData.userData !== null readonly property bool _userdataReady: itemLoader.status === J.ItemLoader.Ready && itemData.userData !== null
SilicaFlickable { SilicaFlickable {
anchors.fill: parent anchors.fill: parent
contentHeight: content.height + Theme.paddingLarge contentHeight: content.height + Theme.paddingLarge
@ -60,7 +60,7 @@ BaseDetailPage {
imageBlurhash: itemData.imageBlurHashes["Primary"][itemData.imageTags["Primary"]] imageBlurhash: itemData.imageBlurHashes["Primary"][itemData.imageTags["Primary"]]
Binding on favourited { Binding on favourited {
when: _userdataReady when: _userdataReady
value: itemData.userData.isFavorite value: itemData.userData.favorite
} }
Binding on playProgress { Binding on playProgress {
when: _userdataReady when: _userdataReady
@ -82,7 +82,7 @@ BaseDetailPage {
} }
Connections { Connections {
target: itemData target: itemLoader
onStatusChanged: { onStatusChanged: {
if (status === J.ItemLoader.Ready) { if (status === J.ItemLoader.Ready) {
console.log(itemData.mediaStreams) console.log(itemData.mediaStreams)