1
0
Fork 0
mirror of https://github.com/HenkKalkwater/harbour-sailfin.git synced 2025-09-04 01:42:44 +00:00

[3/3] update openapi spec: update code interacting with generated code

Adjusted C++ code to handle with new and renamed objects, as well as
properties with different types.

As a result of changing types, the QML side had to be updated as well.
I hope I found everything by manually testing.

Additionally, the Qt Quick application has been updated to test the
remote sessions more easily and to make it launch again.
This commit is contained in:
Chris Josten 2025-03-13 02:51:19 +01:00 committed by Chris Josten
parent 9e1a20cd3a
commit 0c72906f88
39 changed files with 366 additions and 317 deletions

View file

@ -248,8 +248,8 @@ extern template int extractTotalRecordCount(const QList<DTO::BaseItemDto> &resul
extern template void setRequestLimit(Loader::GetLatestMediaParams &params, int limit);
extern template bool setRequestStartIndex(Loader::GetLatestMediaParams &params, int offset);
extern template void setRequestLimit(Loader::GetItemsByUserIdParams &params, int limit);
extern template bool setRequestStartIndex(Loader::GetItemsByUserIdParams &params, int offset);
extern template void setRequestLimit(Loader::GetItemsParams &params, int limit);
extern template bool setRequestStartIndex(Loader::GetItemsParams &params, int offset);
extern template void setRequestLimit(Loader::GetResumeItemsParams &params, int limit);
extern template bool setRequestStartIndex(Loader::GetResumeItemsParams &params, int offset);
@ -332,7 +332,6 @@ protected:
R result = m_loader->result();
QList<D> records = extractRecords<D, R>(result);
int totalRecordCount = extractTotalRecordCount<R>(result);
qDebug() << "Total record count: " << totalRecordCount << ", records in request: " << records.size();
// If totalRecordCount < 0, it is not supported for this endpoint
if (totalRecordCount < 0) {
totalRecordCount = records.size();
@ -549,7 +548,6 @@ protected:
void loadingFinished() override {
Q_ASSERT(m_loader != nullptr);
std::pair<QList<T*>, int> result = m_loader->result();
qDebug() << "Results loaded: index: " << result.second << ", count: " << result.first.size();
if (result.second == -1) {
clear();
} else if (result.second == m_array.size()) {

View file

@ -26,7 +26,7 @@ namespace Jellyfin {
namespace DTO {
class UserItemDataDto;
class PlaystateRequest;
class SessionInfo;
class SessionInfoDto;
}
/**
@ -43,14 +43,14 @@ signals:
* @param itemId The id of the item which was updated.
* @param userData The new userData
*/
void itemUserDataUpdated(const QString &itemId, const DTO::UserItemDataDto &userData);
void itemUserDataUpdated(const QString &itemId, const Jellyfin::DTO::UserItemDataDto &userData);
/**
* @brief The information about a session has been updated
* @param sessionId The id of the session
* @param sessionInfo The associated information
*/
void sessionInfoUpdated(const QString &sessionId, const DTO::SessionInfo &sessionInfo);
void sessionInfoUpdated(const QString &sessionId, const Jellyfin::DTO::SessionInfoDto &sessionInfo);
/**
* @brief The server has requested to display an message to the user

View file

@ -5,7 +5,7 @@
#include <QScopedPointer>
#include <QSharedPointer>
#include "JellyfinQt/dto/sessioninfo.h"
#include "JellyfinQt/dto/sessioninfodto.h"
namespace Jellyfin {
@ -105,7 +105,7 @@ private:
class ControllableJellyfinSession : public ControllableSession {
Q_OBJECT
public:
ControllableJellyfinSession(QSharedPointer<DTO::SessionInfo> info, ApiClient &apiClient, QObject *parent = nullptr);
ControllableJellyfinSession(QSharedPointer<DTO::SessionInfoDto> info, ApiClient &apiClient, QObject *parent = nullptr);
QString id() const override;
QString name() const override;
QString appName() const override;
@ -113,7 +113,7 @@ public:
QString userName() const override;
PlaybackManager *createPlaybackManager() const override;
private:
QSharedPointer<DTO::SessionInfo> m_data;
QSharedPointer<DTO::SessionInfoDto> m_data;
ApiClient &m_apiClient;
};

View file

@ -22,7 +22,7 @@
#include <JellyfinQt/dto/generalcommandtype.h>
#include <JellyfinQt/dto/playcommand.h>
#include <JellyfinQt/dto/playstatecommand.h>
#include <JellyfinQt/dto/sessioninfo.h>
#include <JellyfinQt/dto/sessioninfodto.h>
#include <JellyfinQt/model/playbackmanager.h>
#include <JellyfinQt/support/loader.h>
@ -69,7 +69,7 @@ public slots:
void seek(qint64 pos) override;
private slots:
void onPositionTimerFired();
void onSessionInfoUpdated(const QString &sessionId, const DTO::SessionInfo &sessionInfo);
void onSessionInfoUpdated(const QString &sessionId, const DTO::SessionInfoDto &sessionInfo);
private:
void sendPlaystateCommand(DTO::PlaystateCommand command, qint64 seekTicks = -1);
void sendGeneralCommand(DTO::GeneralCommandType command, QJsonObject arguments = QJsonObject());
@ -88,7 +88,7 @@ private:
void updateQueue(QList<QueueItem> itemIds);
ApiClient &m_apiClient;
QString m_sessionId;
std::optional<DTO::SessionInfo> m_lastSessionInfo;
std::optional<DTO::SessionInfoDto> m_lastSessionInfo;
QTimer *m_positionTimer;
qint64 m_position = 0;
};

View file

@ -116,7 +116,7 @@ public:
Q_PROPERTY(QString playlistItemId READ playlistItemId NOTIFY playlistItemIdChanged)
Q_PROPERTY(QDateTime dateCreated READ dateCreated NOTIFY dateCreatedChanged)
Q_PROPERTY(QDateTime dateLastMediaAdded READ dateLastMediaAdded NOTIFY dateLastMediaAddedChanged)
Q_PROPERTY(QString extraType READ extraType NOTIFY extraTypeChanged)
Q_PROPERTY(Jellyfin::DTO::ExtraTypeClass::Value extraType READ extraType NOTIFY extraTypeChanged)
Q_PROPERTY(int airsBeforeSeasonNumber READ airsBeforeSeasonNumber NOTIFY airsBeforeSeasonNumberChanged)
Q_PROPERTY(int airsAfterSeasonNumber READ airsAfterSeasonNumber NOTIFY airsAfterSeasonNumberChanged)
Q_PROPERTY(int airsBeforeEpisodeNumber READ airsBeforeEpisodeNumber NOTIFY airsBeforeEpisodeNumberChanged)
@ -143,7 +143,7 @@ public:
Q_PROPERTY(int indexNumber READ indexNumber NOTIFY indexNumberChanged)
Q_PROPERTY(int indexNumberEnd READ indexNumberEnd NOTIFY indexNumberEndChanged)
Q_PROPERTY(bool isFolder READ isFolder NOTIFY isFolderChanged)
Q_PROPERTY(QString type READ type NOTIFY typeChanged)
Q_PROPERTY(Jellyfin::DTO::BaseItemKindClass::Value type READ type NOTIFY typeChanged)
Q_PROPERTY(QString parentBackdropItemId READ parentBackdropItemId NOTIFY parentBackdropItemIdChanged)
Q_PROPERTY(QStringList parentBackdropImageTags READ parentBackdropImageTags NOTIFY parentBackdropImageTagsChanged)
Q_PROPERTY(Jellyfin::ViewModel::UserData *userData READ userData NOTIFY userDataChanged)
@ -163,7 +163,7 @@ public:
Q_PROPERTY(double primaryImageAspectRatio READ primaryImageAspectRatio NOTIFY primaryImageAspectRatioChanged)
Q_PROPERTY(QStringList artists READ artists NOTIFY artistsChanged)
Q_PROPERTY(QList<QObject *> artistItems READ artistItems NOTIFY artistItemsChanged);
Q_PROPERTY(QString collectionType READ collectionType NOTIFY collectionTypeChanged)
Q_PROPERTY(Jellyfin::DTO::CollectionTypeClass::Value collectionType READ collectionType NOTIFY collectionTypeChanged)
// 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 READ imageTags NOTIFY imageTagsChanged)
@ -178,7 +178,7 @@ public:
Q_PROPERTY(int albumCount READ albumCount NOTIFY albumCountChanged)
Q_PROPERTY(int artistCount READ artistCount NOTIFY artistCountChanged)
Q_PROPERTY(int musicVideoCount READ musicVideoCount NOTIFY musicVideoCountChanged)
Q_PROPERTY(QString mediaType READ mediaType NOTIFY mediaTypeChanged)
Q_PROPERTY(Jellyfin::DTO::MediaTypeClass::Value mediaType READ mediaType NOTIFY mediaTypeChanged)
Q_PROPERTY(QDateTime endDate READ endDate NOTIFY endDateChanged)
Q_PROPERTY(QDateTime startDate READ startDate NOTIFY startDateChanged)
Q_PROPERTY(int width READ width NOTIFY widthChanged)
@ -194,7 +194,7 @@ public:
QString playlistItemId() const { return m_data->playlistItemId(); }
QDateTime dateCreated() const { return m_data->dateCreated(); }
QDateTime dateLastMediaAdded() const { return m_data->dateLastMediaAdded(); }
QString extraType() const { return m_data->extraType(); }
ExtraType extraType() const { return m_data->extraType(); }
int airsBeforeSeasonNumber() const { return m_data->airsBeforeSeasonNumber().value_or(0); }
int airsAfterSeasonNumber() const { return m_data->airsAfterSeasonNumber().value_or(999); }
int airsBeforeEpisodeNumber() const { return m_data->airsBeforeEpisodeNumber().value_or(0); }
@ -204,7 +204,7 @@ public:
int indexNumber() const { return m_data->indexNumber().value_or(-1); }
int indexNumberEnd() const { return m_data->indexNumberEnd().value_or(-1); }
bool isFolder() const { return m_data->isFolder().value_or(false); }
QString type() const { return m_data->type(); }
BaseItemKind type() const { return m_data->type(); }
QString parentBackdropItemId() const { return m_data->parentBackdropItemId(); }
QStringList parentBackdropImageTags() const { return m_data->parentBackdropImageTags(); }
UserData *userData() const { return m_userData; }
@ -223,11 +223,11 @@ public:
double primaryImageAspectRatio() const { return m_data->primaryImageAspectRatio().value_or(1.0); }
QStringList artists() const { return m_data->artists(); }
QList<QObject *> artistItems() const{ return this->m_artistItems; }
QString collectionType() const { return this->m_data->collectionType(); }
CollectionType collectionType() const { return this->m_data->collectionType(); }
QJsonObject imageTags() const { return m_data->imageTags(); }
QStringList backdropImageTags() const { return m_data->backdropImageTags(); }
QJsonObject imageBlurHashes() const { return m_data->imageBlurHashes(); }
QString mediaType() const { return m_data->mediaType(); }
MediaType mediaType() const { return m_data->mediaType(); }
QDateTime endDate() const { return m_data->endDate(); }
QDateTime startDate() const { return m_data->startDate(); }
Item *currentProgram() const { return m_currentProgram; }
@ -281,7 +281,7 @@ signals:
void indexNumberChanged(int newIndexNumber);
void indexNumberEndChanged(int newIndexNumberEnd);
void isFolderChanged(bool newIsFolder);
void typeChanged(const QString &newType);
void typeChanged(const BaseItemKind &newType);
void parentBackdropItemIdChanged();
void parentBackdropImageTagsChanged();
void userDataChanged(UserData *newUserData);
@ -313,7 +313,7 @@ signals:
void albumCountChanged(int newAlbumCount);
void artistCountChanged(int newArtistCount);
void musicVideoCountChanged(int newMusicVideoCount);
void mediaTypeChanged(const QString &newMediaType);
void mediaTypeChanged(const MediaType &newMediaType);
void endDateChanged();
void startDateChanged();
void widthChanged(int newWidth);

View file

@ -38,7 +38,7 @@
public: \
Q_PROPERTY(type propName READ propName WRITE set##propSetName NOTIFY propName##Changed) \
type propName() const { return this->m_parameters.propName(); } \
void set##propSetName(type newValue) { \
void set##propSetName(const type &newValue) { \
this->m_parameters.set##propSetName( newValue ); \
emit propName##Changed(); \
autoReloadIfNeeded(); \
@ -92,7 +92,7 @@ public:
this->connect(this, &BaseModelLoader::apiClientChanged, this, &AbstractUserParameterLoader<T, D, R, P>::apiClientChanged);
}
protected:
virtual bool canReload() const override {
bool canReload() const override {
return BaseModelLoader::canReload() && !this->m_parameters.userId().isNull();
}
private:
@ -125,7 +125,7 @@ public:
FWDPROP(bool, includeExternalContent, IncludeExternalContent)
FWDPROP(bool, includeHidden, IncludeHidden)
FWDPROP(QStringList, presetViews, PresetViews)
FWDLISTPROP(Jellyfin::DTO::CollectionType, presetViews, PresetViews)
};
using LatestMediaBase = AbstractUserParameterLoader<Model::Item, DTO::BaseItemDto, QList<DTO::BaseItemDto>, Jellyfin::Loader::GetLatestMediaParams>;
@ -141,12 +141,12 @@ public:
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
FWDPROP(bool, groupItems, GroupItems)
FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, includeItemTypes, IncludeItemTypes)
FWDPROP(bool, isPlayed, IsPlayed)
FWDPROP(QString, parentId, ParentId)
};
using UserItemsLoaderBase = AbstractUserParameterLoader<Model::Item, DTO::BaseItemDto, DTO::BaseItemDtoQueryResult, Jellyfin::Loader::GetItemsByUserIdParams>;
using UserItemsLoaderBase = AbstractUserParameterLoader<Model::Item, DTO::BaseItemDto, DTO::BaseItemDtoQueryResult, Jellyfin::Loader::GetItemsParams>;
class UserItemsLoader : public UserItemsLoaderBase {
Q_OBJECT
public:
@ -166,7 +166,7 @@ public:
FWDPROP(bool, enableUserData, EnableUserData)
FWDPROP(QStringList, excludeArtistIds, ExcludeArtistIds)
FWDPROP(QStringList, excludeItemIds, ExcludeItemIds)
FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, excludeItemTypes, ExcludeItemTypes)
FWDPROP(QList<Jellyfin::DTO::LocationTypeClass::Value>, excludeLocationTypes, ExcludeLocationTypes)
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
FWDLISTPROP(Jellyfin::DTO::ItemFilterClass::Value, filters, Filters)
@ -186,7 +186,7 @@ public:
FWDPROP(QStringList, ids, Ids)
FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, imageTypes, ImageTypes)
FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, includeItemTypes, IncludeItemTypes)
FWDPROP(bool, is3D, Is3D)
FWDPROP(bool, is4K, Is4K)
FWDPROP(bool, isFavorite, IsFavorite)
@ -201,13 +201,13 @@ public:
FWDPROP(QString, maxOfficialRating, MaxOfficialRating)
FWDPROP(QDateTime, maxPremiereDate, MaxPremiereDate)
FWDPROP(qint32, maxWidth, MaxWidth)
FWDPROP(QStringList, mediaTypes, MediaTypes)
FWDLISTPROP(Jellyfin::DTO::MediaTypeClass::Value, mediaTypes, MediaTypes)
FWDPROP(qint32, minHeight, MinHeight)
FWDPROP(QString, minOfficialRating, MinOfficialRating)
FWDPROP(QDateTime, minPremiereDate, MinPremiereDate)
FWDPROP(qint32, minWidth, MinWidth)
FWDPROP(QString, sortBy, SortBy)
FWDPROP(QString, sortOrder, SortOrder)
FWDLISTPROP(Jellyfin::DTO::ItemSortByClass::Value, sortBy, SortBy)
FWDLISTPROP(Jellyfin::DTO::SortOrderClass::Value, sortOrder, SortOrder)
FWDPROP(QStringList, tags, Tags)
FWDPROP(QList<qint32>, years, Years)
@ -227,11 +227,11 @@ public:
FWDPROP(bool, enableImages, EnableImages)
FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
FWDPROP(bool, enableUserData, EnableUserData)
FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, excludeItemTypes, ExcludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
FWDPROP(QStringList, mediaTypes, MediaTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, includeItemTypes, IncludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::MediaTypeClass::Value, mediaTypes, MediaTypes)
FWDPROP(QString, parentId, ParentId)
FWDPROP(QString, searchTerm, SearchTerm)
};
@ -269,7 +269,7 @@ public:
FWDPROP(bool, isMissing, IsMissing)
FWDPROP(qint32, season, Season)
FWDPROP(QString, seasonId, SeasonId)
FWDPROP(QString, sortBy, SortBy)
FWDPROP(Jellyfin::DTO::ItemSortByClass::Value, sortBy, SortBy)
FWDPROP(QString, startItemId, StartItemId)
};
@ -281,7 +281,7 @@ public:
FWDPROP(bool, disableFirstEpisode, DisableFirstEpisode)
FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes);
FWDPROP(bool, enableImges, EnableImges)
FWDPROP(bool, enableImages, EnableImages)
FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
FWDPROP(bool, enableUserData, EnableUserData)
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
@ -300,16 +300,16 @@ public:
FWDPROP(bool, enableImages, EnableImages)
FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
FWDPROP(bool, enableUserData, EnableUserData)
FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, excludeItemTypes, ExcludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
FWDLISTPROP(Jellyfin::DTO::ItemFilterClass::Value, filters, Filters)
FWDPROP(QStringList, genreIds, GenreIds)
FWDPROP(QStringList, genres, Genres)
FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
FWDLISTPROP(Jellyfin::DTO::BaseItemKindClass::Value, includeItemTypes, IncludeItemTypes)
FWDPROP(bool, isFavorite, IsFavorite)
FWDPROP(int, limit, Limit)
FWDPROP(QStringList, mediaTypes, MediaTypes)
FWDLISTPROP(Jellyfin::DTO::MediaTypeClass::Value, mediaTypes, MediaTypes)
FWDPROP(double, minCommunityRating, MinCommunityRating)
FWDPROP(QString, nameLessThan, NameLessThan)
FWDPROP(QString, nameStartsWith, NameStartsWith)
@ -347,7 +347,7 @@ public:
FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes)
FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
FWDPROP(bool, enableUserData, EnableUserData)
FWDPROP(QStringList, sortBy, SortBy)
FWDLISTPROP(Jellyfin::DTO::ItemSortByClass::Value, sortBy, SortBy)
FWDPROP(Jellyfin::DTO::SortOrderClass::Value, sortOrder, SortOrder)
FWDPROP(bool, enableFavoriteSorting, EnableFavoriteSorting)
FWDPROP(bool, addCurrentProgram, AddCurrentProgram)
@ -405,7 +405,7 @@ public:
explicit ItemModel (QObject *parent = nullptr);
virtual QHash<int, QByteArray> roleNames() const override {
QHash<int, QByteArray> roleNames() const override {
return {
JFRN(jellyfinId),
JFRN(name),
@ -450,7 +450,7 @@ public:
QSharedPointer<Model::Item> itemAt(int index);
private slots:
void onInsertItems(const QModelIndex &parent, int start, int end);
void onUserDataUpdated(const DTO::UserItemDataDto &newUserData);
void onUserDataUpdated(const Jellyfin::DTO::UserItemDataDto &newUserData);
};
#undef JFRN

View file

@ -41,7 +41,7 @@ public:
Q_PROPERTY(QString comment READ comment NOTIFY commentChanged);
Q_PROPERTY(QString timeBase READ timeBase NOTIFY timeBaseChanged);
Q_PROPERTY(QString title READ title NOTIFY titleChanged);
Q_PROPERTY(QString videoRange READ videoRange NOTIFY videoRangeChanged);
Q_PROPERTY(Jellyfin::DTO::VideoRangeClass::Value videoRange READ videoRange NOTIFY videoRangeChanged);
Q_PROPERTY(QString localizedUndefined READ localizedUndefined NOTIFY localizedUndefinedChanged);
Q_PROPERTY(QString localizedDefault READ localizedDefault NOTIFY localizedDefaultChanged);
Q_PROPERTY(QString localizedForced READ localizedForced NOTIFY localizedForcedChanged);
@ -78,7 +78,7 @@ public:
QString comment() const { return m_data->comment(); }
QString timeBase() const { return m_data->timeBase(); }
QString title() const { return m_data->title(); }
QString videoRange() const { return m_data->videoRange(); }
DTO::VideoRange videoRange() const { return m_data->videoRange(); }
QString localizedUndefined() const { return m_data->localizedUndefined(); }
QString localizedDefault() const { return m_data->localizedDefault(); }
QString localizedForced() const { return m_data->localizedForced(); }
@ -116,7 +116,7 @@ signals:
void commentChanged(const QString &newComment);
void timeBaseChanged(const QString &newTimeBase);
void titleChanged(const QString &newTitle);
void videoRangeChanged(const QString &newVideoRanged);
void videoRangeChanged(const DTO::VideoRange &newVideoRanged);
void localizedUndefinedChanged(const QString &newLocalizedUndefined);
void localizedDefaultChanged(const QString &newLocalizedDefault);
void localizedForcedChanged(const QString &newLocalizedForced);

View file

@ -430,15 +430,15 @@ void ApiClient::authenticate(QString username, QString password, bool storeCrede
}
void ApiClient::submitQuickConnectCode(const QString &code) {
using QQAuthorizeLoader = Loader::HTTP::AuthorizeLoader;
Loader::AuthorizeParams params;
using QQAuthorizeLoader = Loader::HTTP::AuthorizeQuickConnectLoader;
Loader::AuthorizeQuickConnectParams params;
params.setCode(code);
QQAuthorizeLoader *loader = new QQAuthorizeLoader(this);
loader->setParameters(params);
loader->load();
loader->connect(loader, &QQAuthorizeLoader::error, this, [this, loader](QString message) {
loader->connect(loader, &QQAuthorizeLoader::error, this, [this, loader](const QString &message) {
qDebug() << "QQ error: " << message;
emit this->quickConnectRejected();
loader->deleteLater();
@ -475,17 +475,18 @@ void ApiClient::generateDeviceProfile() {
Q_D(ApiClient);
QSharedPointer<DTO::DeviceProfile> deviceProfile = QSharedPointer<DTO::DeviceProfile>::create(Model::DeviceProfile::generateProfile());
deviceProfile->setJellyfinId(d->deviceId);
deviceProfile->setFriendlyName(QSysInfo::prettyProductName());
deviceProfile->setName(QSysInfo::prettyProductName());
deviceProfile->setMaxStreamingBitrate(d->settings->maxStreamingBitRate());
d->deviceProfile = deviceProfile;
QSharedPointer<DTO::ClientCapabilitiesDto> clientCapabilities = QSharedPointer<DTO::ClientCapabilitiesDto>::create(true, // supports mediaControl
false, // supports content uploading
true, // supports persistent identifier
false, // supports sync
deviceProfile);
clientCapabilities->setPlayableMediaTypes({"Audio", "Video", "Photo"});
clientCapabilities->setSupportedCommands(d->supportedCommands);
QSharedPointer<DTO::ClientCapabilitiesDto> clientCapabilities = QSharedPointer<DTO::ClientCapabilitiesDto>::create(
QList({ MediaType::Audio, MediaType::Video, MediaType::Photo }),
d->supportedCommands,
true, // supports mediaControl
true, // supports persistent identifier
deviceProfile
);
clientCapabilities->setAppStoreUrl("https://chris.netsoj.nl/projects/harbour-sailfin");
clientCapabilities->setIconUrl("https://chris.netsoj.nl/static/img/logo.png");

View file

@ -64,7 +64,6 @@ void BaseModelLoader::setApiClient(ApiClient *newApiClient) {
void BaseModelLoader::setLimit(int newLimit) {
m_explicitLimitSet = newLimit >= 0;
qCDebug(jellyfinApiModel) << "Limit explicitly set to " << newLimit;
this->m_limit = newLimit;
emit limitChanged(newLimit);
}
@ -144,12 +143,12 @@ bool setRequestStartIndex(Loader::GetLatestMediaParams &params, int offset) {
}
template<>
void setRequestLimit(Loader::GetItemsByUserIdParams &params, int limit) {
void setRequestLimit(Loader::GetItemsParams &params, int limit) {
params.setLimit(limit);
}
template<>
bool setRequestStartIndex(Loader::GetItemsByUserIdParams &params, int index) {
bool setRequestStartIndex(Loader::GetItemsParams &params, int index) {
params.setStartIndex(index);
return true;
}

View file

@ -18,7 +18,9 @@
*/
#include "JellyfinQt/jellyfin.h"
#include "JellyfinQt/dto/collectiontype.h"
#include "JellyfinQt/model/item.h"
#include "JellyfinQt/dto/itemsortby.h"
#include "JellyfinQt/dto/itemfields.h"
#include "JellyfinQt/dto/mediastream.h"
#include "JellyfinQt/dto/nameguidpair.h"
@ -92,11 +94,16 @@ void JellyfinPlugin::registerTypes(const char *uri) {
qmlRegisterType<ViewModel::LiveTvChannelsLoader>(uri, 1, 0, "LiveTvChannelsLoader");
// Enumerations
qmlRegisterUncreatableType<Jellyfin::DTO::CollectionTypeClass>(uri, 1, 0, "CollectionType", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::GeneralCommandTypeClass>(uri, 1, 0, "GeneralCommandType", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::ViewModel::ModelStatusClass>(uri, 1, 0, "ModelStatus", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::PlayMethodClass>(uri, 1, 0, "PlayMethod", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::ItemFieldsClass>(uri, 1, 0, "ItemFields", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::ImageTypeClass>(uri, 1, 0, "ImageType", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::MediaTypeClass>(uri, 1, 0, "MediaType", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::BaseItemKindClass>(uri, 1, 0, "ItemType", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::PlayMethodClass>(uri, 1, 0, "PlayMethod", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::ItemSortByClass>(uri, 1, 0, "SortBy", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::DTO::SortOrderClass>(uri, 1, 0, "SortOrder", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::ViewModel::ModelStatusClass>(uri, 1, 0, "ModelStatus", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::ViewModel::NowPlayingSection>(uri, 1, 0, "NowPlayingSection", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::Model::PlayerStateClass>(uri, 1, 0, "PlayerState", "Is an enum");
qmlRegisterUncreatableType<Jellyfin::Model::MediaStatusClass>(uri, 1, 0, "MediaStatus", "Is an enum");

View file

@ -46,7 +46,7 @@ PlaybackManager *LocalSession::createPlaybackManager() const {
}
// ControllableJellyfinSession
ControllableJellyfinSession::ControllableJellyfinSession(const QSharedPointer<DTO::SessionInfo> info, ApiClient &apiClient, QObject *parent)
ControllableJellyfinSession::ControllableJellyfinSession(const QSharedPointer<DTO::SessionInfoDto> info, ApiClient &apiClient, QObject *parent)
: ControllableSession(parent),
m_data(info),
m_apiClient(apiClient){}
@ -147,14 +147,15 @@ void RemoteJellyfinSessionScanner::startScanning() {
d->loader->setParameters(params);
connect(d->loader, &Loader::HTTP::GetSessionsLoader::ready, this, [this, d, localSession]() {
if (d->loader == nullptr) return;
QList<DTO::SessionInfo> sessions = d->loader->result();
QList<DTO::SessionInfoDto> sessions = d->loader->result();
qDebug() << "Found " << sessions.count() << " sessions";
for(auto it = sessions.begin(); it != sessions.end(); it++) {
// Skip this device
if (it->deviceId() == localSession->id()) continue;
emit sessionFound(new ControllableJellyfinSession(QSharedPointer<DTO::SessionInfo>::create(*it), *d->apiClient));
emit sessionFound(new ControllableJellyfinSession(QSharedPointer<DTO::SessionInfoDto>::create(*it), *d->apiClient));
}
});
d->loader->load();

View file

@ -53,8 +53,6 @@ int DeviceProfile::maxStreamingBitrate() {
}
DTO::DeviceProfile DeviceProfile::generateProfile() {
using JsonPair = QPair<QString, QJsonValue>;
QStringList audioCodes = {
"aac",
"flac",
@ -94,130 +92,138 @@ DTO::DeviceProfile DeviceProfile::generateProfile() {
// AAC
DTO::CodecProfile codecProfile1(DTO::CodecType::VideoAudio);
DTO::CodecProfile codecProfile1(
DTO::CodecType::VideoAudio,
{
createCondition(CondVal::IsSecondaryAudio,
Condition::Equals,
"false",
false)
},
{}
);
codecProfile1.setCodec("aac");
QList<DTO::ProfileCondition> codecProfile1Conditions;
codecProfile1Conditions.append(createCondition(CondVal::IsSecondaryAudio,
Condition::Equals,
"false",
false));
codecProfile1.setConditions(codecProfile1Conditions);
DTO::CodecProfile codecProfile2(DTO::CodecType::Video);
codecProfile2.setCodec("h264");
codecProfile2.setConditions({
createCondition(CondVal::IsAnamorphic,
DTO::CodecProfile codecProfile2(
DTO::CodecType::Video,
{
createCondition(CondVal::IsAnamorphic,
Condition::NotEquals,
"true", false),
createCondition(CondVal::VideoProfile,
Condition::EqualsAny,
"baseline|constrained baseline", false), //"high|main|baseline|constrained baseline"
createCondition(CondVal::VideoLevel,
Condition::LessThanEqual,
"51", false),
createCondition(CondVal::IsInterlaced,
Condition::NotEquals,
"true", false)
});
createCondition(CondVal::VideoProfile,
Condition::EqualsAny,
"baseline|constrained baseline", false), //"high|main|baseline|constrained baseline"
createCondition(CondVal::VideoLevel,
Condition::LessThanEqual,
"51", false),
createCondition(CondVal::IsInterlaced,
Condition::NotEquals,
"true", false)
},
{}
);
codecProfile2.setCodec("h264");
QList<DTO::CodecProfile> codecProfiles = {
codecProfile1,
codecProfile2
};
// Hard coded nr 1:
DTO::TranscodingProfile transcoding1(DTO::DlnaProfileType::Audio,
false, // estimeateContentLength
false, // enable MPEG2 TS M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copyTimestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true // set break on nonkeyframes
);
transcoding1.setAudioCodec("aac");
transcoding1.setContainer("ts");
DTO::TranscodingProfile transcoding1(
QStringLiteral("ts"),
DTO::DlnaProfileType::Audio,
QStringLiteral("h264"),
QStringLiteral("aac"),
DTO::MediaStreamProtocol::Hls,
false, // estimeateContentLength
false, // enable MPEG2 TS M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copyTimestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true, // set break on nonkeyframes,
{}, // conditions
true // Enable audio VBR encoding
);
transcoding1.setMaxAudioChannels("2");
transcoding1.setProtocol("hls");
// Hard code nr 2
DTO::TranscodingProfile transcoding2(DTO::DlnaProfileType::Video,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true // set break on non-keyframes
);
transcoding2.setAudioCodec("mp3,aac");
transcoding2.setContainer("ts");
DTO::TranscodingProfile transcoding2(
QStringLiteral("ts"),
DTO::DlnaProfileType::Video,
QStringLiteral("h264"),
QStringLiteral("mp3,aac"),
DTO::MediaStreamProtocol::Hls,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true, // set break on non-keyframes
{}, // conditions
true// enableAudioVbrEncoding
);
transcoding2.setMaxAudioChannels("2");
transcoding2.setProtocol("hls");
transcoding2.setVideoCodec("h264");
// Fallback
DTO::TranscodingProfile transcoding3(DTO::DlnaProfileType::Video,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Static,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true // set break on non-keyframes
);
transcoding3.setContainer("mp4");
transcoding3.setAudioCodec(videoAudioCodecs.join(','));
transcoding3.setVideoCodec("h264");
transcoding3.setProtocol("http");
DTO::TranscodingProfile transcoding3(
QStringLiteral("mp4"),
DTO::DlnaProfileType::Video,
QStringLiteral("h264"),
videoAudioCodecs.join(","),
DTO::MediaStreamProtocol::Http,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Static,
false, // enable subtitles in manifest
0, // minSegments
0, // minSegmentLength
true, // set break on non-keyframes
{},
true
);
QList<DTO::TranscodingProfile> transcodingProfiles = {
transcoding1, transcoding2, transcoding3
};
if (supportsHls() && !hlsVideoAudioCodecs.isEmpty()) {
DTO::TranscodingProfile transcoding4(DTO::DlnaProfileType::Video,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
1, // minSegments
0, // minSegmentLength
true // set break on non-keyframes
);
transcoding4.setContainer("ts");
transcoding4.setAudioCodec(hlsVideoAudioCodecs.join(','));
transcoding4.setVideoCodec(hlsVideoCodecs.join(','));
transcoding4.setProtocol("hls");
DTO::TranscodingProfile transcoding4(
QStringLiteral("ts"),
DTO::DlnaProfileType::Video,
hlsVideoAudioCodecs.join(","),
hlsVideoAudioCodecs.join(","),
DTO::MediaStreamProtocol::Hls,
false, // estimate content length
false, // enable MPEG2 ts M2 mode
DTO::TranscodeSeekInfo::Auto,
false, // copy timestamps
DTO::EncodingContext::Streaming,
false, // enable subtitles in manifest
1, // minSegments
0, // minSegmentLength
true, // set break on non-keyframes
{},
true
);
transcoding4.setMaxAudioChannels("2");
transcodingProfiles.append(transcoding4);
}
// Response profiles (or whatever it actually does?)
DTO::ResponseProfile responseProfile1(DTO::DlnaProfileType::Video);
responseProfile1.setContainer("m4v");
responseProfile1.setMimeType("video/mp4");
QList<DTO::ResponseProfile> responseProfiles = {
responseProfile1
};
// Direct play profiles
// Video
DTO::DirectPlayProfile directPlayProfile1(DTO::DlnaProfileType::Video);
directPlayProfile1.setContainer("mp4,m4v");
DTO::DirectPlayProfile directPlayProfile1("mp4,m4v", DTO::DlnaProfileType::Video);
directPlayProfile1.setVideoCodec(mp4VideoCodecs.join(','));
directPlayProfile1.setAudioCodec(videoAudioCodecs.join(','));
DTO::DirectPlayProfile directPlayProfile2(DTO::DlnaProfileType::Video);
directPlayProfile2.setContainer("mkv");
DTO::DirectPlayProfile directPlayProfile2("mkv", DTO::DlnaProfileType::Video);
directPlayProfile2.setVideoCodec(mp4VideoCodecs.join(','));
directPlayProfile2.setAudioCodec(videoAudioCodecs.join(','));
@ -227,43 +233,36 @@ DTO::DeviceProfile DeviceProfile::generateProfile() {
// Audio
for (auto it = audioCodes.begin(); it != audioCodes.end(); it++) {
if (*it == "mp2") {
DTO::DirectPlayProfile profile(DTO::DlnaProfileType::Audio);
profile.setContainer("mp2,mp3");
DTO::DirectPlayProfile profile("mp2,mp3", DTO::DlnaProfileType::Audio);
profile.setAudioCodec("mp2");
directPlayProfiles.append(profile);
} else if(*it == "mp3") {
DTO::DirectPlayProfile profile(DTO::DlnaProfileType::Audio);
profile.setContainer("mp3");
DTO::DirectPlayProfile profile("mp3", DTO::DlnaProfileType::Audio);
profile.setAudioCodec("mp3");
directPlayProfiles.append(profile);
} else if (*it == "webma") {
DTO::DirectPlayProfile profile(DTO::DlnaProfileType::Audio);
profile.setContainer("webma,webm");
DTO::DirectPlayProfile profile("webma,webm", DTO::DlnaProfileType::Audio);
directPlayProfiles.append(profile);
} else {
DTO::DirectPlayProfile profile(DTO::DlnaProfileType::Audio);
profile.setContainer(*it);
DTO::DirectPlayProfile profile(*it, DTO::DlnaProfileType::Audio);
directPlayProfiles.append(profile);
}
}
QList<DTO::ContainerProfile> containerProfiles = { };
QList<DTO::SubtitleProfile> subtitleProfiles = {
DTO::SubtitleProfile(DTO::SubtitleDeliveryMethodClass::Hls),
DTO::SubtitleProfile(DTO::SubtitleDeliveryMethodClass::Encode)
};
DTO::DeviceProfile profile(
QSharedPointer<DTO::DeviceIdentification>::create(),
false, // enableAlbumArtInDidl
false, // enableSingleAlbumArtLimit
false, // enableSingleSubtitleLimit
std::numeric_limits<qint32>().max(), // max album art width
std::numeric_limits<qint32>().max(), // max album art height
0, // timeline offset seconds
false, // request plain video items
false, // request plain folders
false, // enableMSMediaReceiverRegistrar,
false //ignoreTranscodeByteRangeRequests
directPlayProfiles,
transcodingProfiles,
containerProfiles,
codecProfiles,
subtitleProfiles
);
profile.setCodecProfiles(codecProfiles);
profile.setDirectPlayProfiles(directPlayProfiles);
profile.setResponseProfiles(responseProfiles);
profile.setTranscodingProfiles(transcodingProfiles);
profile.setMaxStreamingBitrate(std::make_optional<qint32>(maxStreamingBitrate()));
return profile;
}

View file

@ -26,12 +26,16 @@ namespace Model {
Item::Item(ApiClient *apiClient, QObject *parent)
: Item(DTO::BaseItemDto(
QString(), // id
ExtraType::Unknown,
Video3DFormat::EnumNotSet,
PlayAccess::Full,
QSharedPointer<UserItemDataDto>::create(0, 0, false, false),
BaseItemKind::EnumNotSet,
QSharedPointer<UserItemDataDto>::create(0, 0, false, false, QString(), QString()),
CollectionType::EnumNotSet,
VideoType::EnumNotSet,
LocationType::Virtual,
IsoType::EnumNotSet,
MediaType::EnumNotSet,
ImageOrientation::EnumNotSet,
ChannelType::EnumNotSet,
ProgramAudio::EnumNotSet,

View file

@ -232,7 +232,7 @@ public:
void requestItemUrl(QSharedPointer<Model::Item> item);
// slots
void handlePlaybackInfoResponse(QString itemId, QString mediaType, DTO::PlaybackInfoResponse &response);
void handlePlaybackInfoResponse(QString itemId, MediaType mediaType, DTO::PlaybackInfoResponse &response);
/// Called when we have fetched the playback URL and playSession
void onItemUrlReceived(const QString &itemId, const QUrl &url, const QString &playSession,
// Fully specify class to please MOC
@ -352,7 +352,7 @@ void LocalPlaybackManagerPrivate::setItem(QSharedPointer<Model::Item> newItem) {
}
}
void LocalPlaybackManagerPrivate::handlePlaybackInfoResponse(QString itemId, QString mediaType, DTO::PlaybackInfoResponse &response) {
void LocalPlaybackManagerPrivate::handlePlaybackInfoResponse(QString itemId, MediaType mediaType, DTO::PlaybackInfoResponse &response) {
Q_Q(LocalPlaybackManager);
//TODO: move the item URL fetching logic out of this function, into MediaSourceInfo?
QList<DTO::MediaSourceInfo> mediaSources = response.mediaSources();
@ -394,15 +394,16 @@ void LocalPlaybackManagerPrivate::handlePlaybackInfoResponse(QString itemId, QSt
resultingUrl = QUrl::fromLocalFile(source.path());
playMethod = PlayMethod::DirectPlay;
} else if (source.supportsDirectStream() && !transcodePreferred) {
if (mediaType == "Video") {
mediaType.append('s');
QString mediaTypeUrl = Support::toString(mediaType);
if (mediaType == MediaType::Video) {
mediaTypeUrl.append('s');
}
QUrlQuery query;
query.addQueryItem("mediaSourceId", source.jellyfinId());
query.addQueryItem("deviceId", m_apiClient->deviceId());
query.addQueryItem("api_key", m_apiClient->token());
query.addQueryItem("Static", "True");
resultingUrl = QUrl(m_apiClient->baseUrl() + "/" + mediaType + "/" + itemId
resultingUrl = QUrl(m_apiClient->baseUrl() + "/" + mediaTypeUrl + "/" + itemId
+ "/stream." + source.container() + "?" + query.toString(QUrl::EncodeReserved));
playMethod = PlayMethod::DirectStream;
} else if (source.supportsTranscoding() && !source.transcodingUrlNull() && transcodingAllowed) {

View file

@ -149,7 +149,9 @@ void PlaybackReporterPrivate::postPlaybackInfo(PlaybackInfoType type) {
m_playbackManager->player()->state() == PlayerState::Paused,
false, // is muted?
m_playbackManager->playMethod(),
DTO::RepeatMode::RepeatNone);
DTO::RepeatMode::RepeatNone,
DTO::PlaybackOrder::Default
);
progress.setSessionId(m_playbackManager->sessionId());

View file

@ -20,7 +20,7 @@
#include <JellyfinQt/model/remotejellyfinplayback.h>
#include <JellyfinQt/apiclient.h>
#include <JellyfinQt/dto/sessioninfo.h>
#include <JellyfinQt/dto/sessioninfodto.h>
#include <JellyfinQt/loader/http/items.h>
#include <JellyfinQt/loader/http/session.h>
#include <JellyfinQt/loader/requesttypes.h>
@ -174,7 +174,7 @@ void RemoteJellyfinPlayback::onPositionTimerFired() {
emit positionChanged(position());
}
void RemoteJellyfinPlayback::onSessionInfoUpdated(const QString &sessionId, const SessionInfo &sessionInfo) {
void RemoteJellyfinPlayback::onSessionInfoUpdated(const QString &sessionId, const SessionInfoDto &sessionInfo) {
if (sessionId != m_sessionId) return;
m_lastSessionInfo = sessionInfo;
@ -245,8 +245,7 @@ void RemoteJellyfinPlayback::sendGeneralCommand(DTO::GeneralCommandType command,
using CommandLoader = Loader::HTTP::SendFullGeneralCommandLoader;
Params params;
QSharedPointer<DTO::GeneralCommand> fullCommand = QSharedPointer<DTO::GeneralCommand>::create(command, m_apiClient.userId());
fullCommand->setArguments(arguments);
QSharedPointer<DTO::GeneralCommand> fullCommand = QSharedPointer<DTO::GeneralCommand>::create(command, m_apiClient.userId(), arguments);
params.setBody(fullCommand);
params.setSessionId(m_sessionId);

View file

@ -101,7 +101,7 @@ void Item::setUserData(DTO::UserItemDataDto &newData) {
void Item::setUserData(QSharedPointer<DTO::UserItemDataDto> newData) {
if (m_data.isNull() || m_data->userData().isNull()) {
m_userData->setData(QSharedPointer<DTO::UserData>::create(0, 0, false, false));
m_userData->setData(QSharedPointer<DTO::UserData>::create(0, 0, false, false, QString(), QString()));
} else {
m_userData->setData(newData);
}

View file

@ -48,7 +48,7 @@ LatestMediaLoader::LatestMediaLoader(QObject *parent)
: LatestMediaBase(new Jellyfin::Loader::HTTP::GetLatestMediaLoader(), parent){ }
UserItemsLoader::UserItemsLoader(QObject *parent)
: UserItemsLoaderBase(new Jellyfin::Loader::HTTP::GetItemsByUserIdLoader(), parent) {}
: UserItemsLoaderBase(new Jellyfin::Loader::HTTP::GetItemsLoader(), parent) {}
ResumeItemsLoader::ResumeItemsLoader(QObject *parent)
: ResumeItemsLoaderBase(new Jellyfin::Loader::HTTP::GetResumeItemsLoader(), parent) {}

View file

@ -22,7 +22,7 @@ namespace Jellyfin {
namespace ViewModel {
UserData::UserData(QObject *parent)
: UserData(QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false), parent) {
: UserData(QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false, QString(), QString()), parent) {
}
@ -30,13 +30,13 @@ UserData::UserData(QSharedPointer<DTO::UserItemDataDto> data, QObject *parent)
: QObject(parent),
m_data(data) {
if (m_data.isNull()) {
m_data = QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false);
m_data = QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false, QString(), QString());
}
}
void UserData::setData(QSharedPointer<DTO::UserItemDataDto> data) {
if (data.isNull()) {
m_data = QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false);
m_data = QSharedPointer<DTO::UserItemDataDto>::create(0, 0, false, false, QString(), QString());
} else {
m_data = data;
}

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <JellyfinQt/dto/generalcommand.h>
#include <JellyfinQt/dto/generalcommandtype.h>
#include <JellyfinQt/dto/playstaterequest.h>
#include <JellyfinQt/dto/sessioninfo.h>
#include <JellyfinQt/dto/sessioninfodto.h>
#include <JellyfinQt/dto/useritemdatadto.h>
Q_LOGGING_CATEGORY(jellyfinWebSocket, "jellyfin.websocket");
@ -157,7 +157,7 @@ void WebSocket::textMessageReceived(const QString &message) {
}
} else if (messageType == QStringLiteral("Sessions")) {
try {
QList<DTO::SessionInfo> sessionInfoList = Support::fromJsonValue<QList<DTO::SessionInfo>>(data);
QList<DTO::SessionInfoDto> sessionInfoList = Support::fromJsonValue<QList<DTO::SessionInfoDto>>(data);
for (auto it = sessionInfoList.cbegin(); it != sessionInfoList.cend(); it++) {
emit m_apiClient->eventbus()->sessionInfoUpdated(it->jellyfinId(), *it);
}