mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2025-09-05 10:12:46 +00:00
WIP: Slowly bringing back viewmodels
This commit is contained in:
parent
9abee12658
commit
228f81984b
17 changed files with 292 additions and 96 deletions
|
@ -62,7 +62,7 @@ void BaseModelLoader::setApiClient(ApiClient *newApiClient) {
|
|||
void BaseModelLoader::setLimit(int newLimit) {
|
||||
int oldLimit = this->m_limit;
|
||||
m_limit = newLimit;
|
||||
if (oldLimit != this->m_limit) {
|
||||
if (oldLimit != newLimit) {
|
||||
emit limitChanged(this->m_limit);
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ void BaseModelLoader::setAutoReload(bool newAutoReload) {
|
|||
|
||||
bool BaseModelLoader::canReload() const {
|
||||
return m_apiClient != nullptr
|
||||
&& !m_isBeingParsed
|
||||
// If the loader for this model needs authentication (almost every one does)
|
||||
// block if the ApiClient is not authenticated yet.
|
||||
&& (!m_needsAuthentication || m_apiClient->authenticated())
|
||||
|
@ -88,6 +89,8 @@ void BaseApiModel::reload() {
|
|||
qWarning() << " BaseApiModel slot called instead of overloaded method";
|
||||
}
|
||||
|
||||
// Parameters injectors and result extractors
|
||||
|
||||
template <>
|
||||
bool setRequestStartIndex(Loader::GetUserViewsParams ¶ms, int startIndex) {
|
||||
// Not supported
|
||||
|
@ -112,6 +115,28 @@ int extractTotalRecordCount(const DTO::BaseItemDtoQueryResult &result) {
|
|||
return result.totalRecordCount();
|
||||
}
|
||||
|
||||
template <>
|
||||
QList<DTO::BaseItemDto> extractRecords(const QList<DTO::BaseItemDto> &result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
int extractTotalRecordCount(const QList<DTO::BaseItemDto> &result) {
|
||||
return result.size();
|
||||
}
|
||||
|
||||
template<>
|
||||
void setRequestLimit(Loader::GetLatestMediaParams ¶ms, int limit) {
|
||||
params.setLimit(limit);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool setRequestStartIndex(Loader::GetLatestMediaParams ¶ms, int offset) {
|
||||
Q_UNUSED(params)
|
||||
Q_UNUSED(offset)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void registerModels(const char *URI) {
|
||||
Q_UNUSED(URI)
|
||||
|
|
|
@ -22,20 +22,25 @@ namespace Jellyfin {
|
|||
void registerTypes(const char *uri) {
|
||||
qmlRegisterType<ApiClient>(uri, 1, 0, "ApiClient");
|
||||
qmlRegisterType<ServerDiscoveryModel>(uri, 1, 0, "ServerDiscoveryModel");
|
||||
qmlRegisterType<ViewModel::PlaybackManager>(uri, 1, 0, "PlaybackManager");
|
||||
qmlRegisterUncreatableType<ViewModel::Item>(uri, 1, 0, "Item", "Acquire one via ItemLoader or exposed properties");
|
||||
qmlRegisterUncreatableType<WebSocket>(uri, 1, 0, "WebSocket", "Obtain one via your ApiClient");
|
||||
|
||||
|
||||
// AbstractItemModels
|
||||
qmlRegisterUncreatableType<BaseApiModel>(uri, 1, 0, "BaseApiModel", "Please use one of its subclasses");
|
||||
qmlRegisterUncreatableType<BaseModelLoader>(uri, 1, 0, "BaseModelLoader", "Please use one of its subclasses");
|
||||
qmlRegisterUncreatableType<ViewModel::LoaderBase>(uri, 1, 0, "LoaderBase", "Use on eof its subclasses");
|
||||
|
||||
qmlRegisterUncreatableType<ViewModel::Item>(uri, 1, 0, "Item", "Acquire one via ItemLoader or exposed properties");
|
||||
qmlRegisterType<ViewModel::ItemLoader>(uri, 1, 0, "ItemLoader");
|
||||
qmlRegisterType<ViewModel::ItemModel>(uri, 1, 0, "ItemModel");
|
||||
qmlRegisterType<ViewModel::UserViewsLoader>(uri, 1, 0, "UsersViewLoader");
|
||||
|
||||
qmlRegisterType<ViewModel::PlaybackManager>(uri, 1, 0, "PlaybackManager");
|
||||
// Loaders
|
||||
qmlRegisterUncreatableType<ViewModel::LoaderBase>(uri, 1, 0, "LoaderBase", "Use one of its subclasses");
|
||||
qmlRegisterType<ViewModel::ItemLoader>(uri, 1, 0, "ItemLoader");
|
||||
qmlRegisterType<ViewModel::LatestMediaLoader>(uri, 1, 0, "LatestMediaLoader");
|
||||
qmlRegisterType<ViewModel::UserItemsLoader>(uri, 1, 0, "UserItemsLoader");
|
||||
qmlRegisterType<ViewModel::UserViewsLoader>(uri, 1, 0, "UsersViewsLoader");
|
||||
|
||||
// Enumerations
|
||||
qmlRegisterUncreatableType<DTO::GeneralCommandTypeClass>(uri, 1, 0, "GeneralCommandType", "Is an enum");
|
||||
qmlRegisterUncreatableType<ViewModel::ModelStatusClass>(uri, 1, 0, "ModelStatus", "Is an enum");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
namespace Jellyfin {
|
||||
namespace Model {
|
||||
|
||||
|
||||
Item::Item()
|
||||
: Item(DTO::BaseItemDto(), nullptr) { }
|
||||
|
||||
Item::Item(const DTO::BaseItemDto &data, ApiClient *apiClient)
|
||||
: DTO::BaseItemDto(data), m_apiClient(apiClient) {
|
||||
if (m_apiClient != nullptr) {
|
||||
|
|
|
@ -149,8 +149,14 @@ QJsonValue toJsonValue<QStringList>(const QStringList &source, convertType<QStri
|
|||
// QJsonObject
|
||||
template <>
|
||||
QJsonObject fromJsonValue<QJsonObject>(const QJsonValue &source, convertType<QJsonObject>) {
|
||||
if (!source.isObject()) throw ParseException("Error parsing JSON value as object: not a double");
|
||||
return source.toObject();
|
||||
switch(source.type()) {
|
||||
case QJsonValue::Null:
|
||||
return QJsonObject();
|
||||
case QJsonValue::Object:
|
||||
return source.toObject();
|
||||
default:
|
||||
throw ParseException("Error parsing JSON value as object: not an object");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -161,7 +167,7 @@ QJsonValue toJsonValue<QJsonObject>(const QJsonObject &source, convertType<QJson
|
|||
// Double
|
||||
template <>
|
||||
double fromJsonValue<double>(const QJsonValue &source, convertType<double>) {
|
||||
if (!source.isDouble()) throw ParseException("Error parsing JSON value as integer: not a double");
|
||||
if (!source.isDouble()) throw ParseException("Error parsing JSON value as double: not a double");
|
||||
return source.toDouble();
|
||||
}
|
||||
|
||||
|
@ -170,6 +176,18 @@ QJsonValue toJsonValue<double>(const double &source, convertType<double>) {
|
|||
return QJsonValue(source);
|
||||
}
|
||||
|
||||
// Float
|
||||
template <>
|
||||
float fromJsonValue<float>(const QJsonValue &source, convertType<float>) {
|
||||
if (!source.isDouble()) throw ParseException("Error parsing JSON value as float: not a double");
|
||||
return static_cast<float>(source.toDouble());
|
||||
}
|
||||
|
||||
template <>
|
||||
QJsonValue toJsonValue<float>(const float &source, convertType<float>) {
|
||||
return QJsonValue(static_cast<double>(source));
|
||||
}
|
||||
|
||||
// QDateTime
|
||||
template <>
|
||||
QDateTime fromJsonValue<QDateTime>(const QJsonValue &source, convertType<QDateTime>) {
|
||||
|
@ -205,27 +223,37 @@ QJsonValue toJsonValue<QUuid>(const QUuid &source, convertType<QUuid>) {
|
|||
|
||||
// String types
|
||||
template <>
|
||||
QString toString(const QUuid &source) {
|
||||
QString toString(const QUuid &source, convertType<QUuid>) {
|
||||
return uuidToString(source);
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const qint32 &source) {
|
||||
QString toString(const qint32 &source, convertType<qint32>) {
|
||||
return QString::number(source);
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const qint64 &source) {
|
||||
QString toString(const qint64 &source, convertType<qint64>) {
|
||||
return QString::number(source);
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const bool &source) {
|
||||
QString toString(const float &source, convertType<float>) {
|
||||
return QString::number(source);
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const double &source, convertType<double>) {
|
||||
return QString::number(source);
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const bool &source, convertType<bool>) {
|
||||
return source ? QStringLiteral("true") : QStringLiteral("false");
|
||||
}
|
||||
|
||||
template <>
|
||||
QString toString(const QString &source) {
|
||||
QString toString(const QString &source, convertType<QString>) {
|
||||
return source;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,10 @@
|
|||
namespace Jellyfin {
|
||||
namespace ViewModel {
|
||||
|
||||
Item::Item(QObject *parent)
|
||||
: Item(nullptr, parent){}
|
||||
Item::Item(QObject *parent, QSharedPointer<Model::Item> data)
|
||||
: QObject(parent), m_data(data){
|
||||
|
||||
Item::Item(QSharedPointer<Model::Item> data, QObject *parent)
|
||||
: QObject(parent), m_data(data){}
|
||||
}
|
||||
|
||||
void Item::setData(QSharedPointer<Model::Item> newData) {
|
||||
Model::Item oldData = *m_data.data();
|
||||
|
@ -36,7 +35,8 @@ void Item::setData(QSharedPointer<Model::Item> newData) {
|
|||
// ItemLoader
|
||||
|
||||
ItemLoader::ItemLoader(QObject *parent)
|
||||
: BaseClass(Jellyfin::Loader::HTTP::GetItemLoader(), parent) {
|
||||
: BaseClass(new Jellyfin::Loader::HTTP::GetItemLoader(), parent) {
|
||||
connect(this, &LoaderBase::apiClientChanged, this, &ItemLoader::onApiClientChanged);
|
||||
}
|
||||
|
||||
void ItemLoader::onApiClientChanged(ApiClient *newApiClient) {
|
||||
|
@ -54,7 +54,9 @@ void ItemLoader::setUserId(const QString &newUserId) {
|
|||
}
|
||||
|
||||
bool ItemLoader::canReload() const {
|
||||
return BaseClass::canReload() && !m_parameters.itemId().isEmpty();
|
||||
return BaseClass::canReload()
|
||||
&& !m_parameters.itemId().isEmpty()
|
||||
&& !m_parameters.userId().isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
#include "JellyfinQt/viewmodel/itemmodel.h"
|
||||
|
||||
#include "JellyfinQt/loader/http/getlatestmedia.h"
|
||||
#include "JellyfinQt/loader/http/getitemsbyuserid.h"
|
||||
|
||||
#define JF_CASE(roleName) case roleName: \
|
||||
try { \
|
||||
return QVariant(item.roleName()); \
|
||||
|
@ -30,37 +33,13 @@ namespace Jellyfin {
|
|||
namespace ViewModel {
|
||||
|
||||
UserViewsLoader::UserViewsLoader(QObject *parent)
|
||||
: UserViewsLoaderBase(new Jellyfin::Loader::HTTP::GetUserViewsLoader(), parent) {
|
||||
connect(this, &BaseModelLoader::apiClientChanged, this, &UserViewsLoader::apiClientChanged);
|
||||
}
|
||||
: UserViewsLoaderBase(new Jellyfin::Loader::HTTP::GetUserViewsLoader(), parent) { }
|
||||
|
||||
void UserViewsLoader::apiClientChanged(ApiClient *newApiClient) {
|
||||
if (m_apiClient != nullptr) disconnect(m_apiClient, &ApiClient::userIdChanged, this, &UserViewsLoader::userIdChanged);
|
||||
if (newApiClient != nullptr) {
|
||||
connect(newApiClient, &ApiClient::userIdChanged, this, &UserViewsLoader::userIdChanged);
|
||||
if (!newApiClient->userId().isNull()) {
|
||||
m_parameters.setUserId(newApiClient->userId());
|
||||
}
|
||||
}
|
||||
}
|
||||
LatestMediaLoader::LatestMediaLoader(QObject *parent)
|
||||
: LatestMediaBase(new Jellyfin::Loader::HTTP::GetLatestMediaLoader(), parent){ }
|
||||
|
||||
void UserViewsLoader::userIdChanged(const QString &newUserId) {
|
||||
m_parameters.setUserId(newUserId);
|
||||
autoReloadIfNeeded();
|
||||
}
|
||||
void UserItemsLoader::apiClientChanged(ApiClient *newApiClient) {
|
||||
if (m_apiClient != nullptr) disconnect(m_apiClient, &ApiClient::userIdChanged, this, &UserItemsLoader::userIdChanged);
|
||||
if (newApiClient != nullptr) connect(newApiClient, &ApiClient::userIdChanged, this, &UserItemsLoader::userIdChanged);
|
||||
}
|
||||
|
||||
void UserItemsLoader::userIdChanged(const QString &newUserId) {
|
||||
m_parameters.setUserId(newUserId);
|
||||
autoReloadIfNeeded();
|
||||
}
|
||||
|
||||
bool UserItemsLoader::canReload() const {
|
||||
return BaseModelLoader::canReload() && !m_parameters.userId().isNull();
|
||||
}
|
||||
UserItemsLoader::UserItemsLoader(QObject *parent)
|
||||
: UserItemsLoaderBase(new Jellyfin::Loader::HTTP::GetItemsByUserIdLoader(), parent) {}
|
||||
|
||||
ItemModel::ItemModel(QObject *parent)
|
||||
: ApiModel<Model::Item>(parent) { }
|
||||
|
@ -81,6 +60,8 @@ QVariant ItemModel::data(const QModelIndex &index, int role) const {
|
|||
JF_CASE(dateCreated)
|
||||
JF_CASE(dateLastMediaAdded)
|
||||
JF_CASE(extraType)
|
||||
// Handpicked, important ones
|
||||
JF_CASE(imageTags)
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue