Jellyfin Qt
QML Library for interacting with the Jellyfin multimedia server
Loading...
Searching...
No Matches
loader.h
Go to the documentation of this file.
1/*
2 * Sailfin: a Jellyfin client written using Qt
3 * Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#ifndef JELLYFIN_DTO_DTO
20#define JELLYFIN_DTO_DTO
21
22#include <optional>
23
24#include <QFuture>
25#include <QFutureWatcher>
26#include <QMutex>
27#include <QMutexLocker>
28#include <QtConcurrent/QtConcurrent>
29
30#include "../support/loader.h"
31
32namespace Jellyfin {
33namespace ViewModel {
34
42class LoaderBase : public QObject, public QQmlParserStatus {
43 Q_OBJECT
44 Q_INTERFACES(QQmlParserStatus)
45public:
56 Q_ENUM(Status)
57
58 explicit LoaderBase(QObject *parent = nullptr) : QObject(parent) {}
59 LoaderBase(ApiClient *apiClient, QObject *parent = nullptr)
60 : QObject(parent), m_apiClient(apiClient) {}
61
62 Q_PROPERTY(ApiClient *apiClient MEMBER m_apiClient WRITE setApiClient NOTIFY apiClientChanged STORED false)
63 Q_PROPERTY(Jellyfin::ViewModel::LoaderBase::Status status READ status NOTIFY statusChanged STORED false)
64 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged STORED false)
65 Q_PROPERTY(bool autoReload MEMBER m_autoReload NOTIFY autoReloadChanged)
66 Q_PROPERTY(QObject *data READ data NOTIFY dataChanged STORED false)
67
68 Status status() const { return m_status; }
69 QString errorString() const { return m_errorString; }
70
71 virtual QObject *data() const { return nullptr; }
72
73 void setApiClient(ApiClient *newApiClient);
74 void setExtraFields(const QStringList &extraFields);
75signals:
77 void apiClientChanged(ApiClient *newApiClient);
78 void errorStringChanged(QString newErrorString);
79 void autoReloadChanged(bool newAutoReload);
81
85 void ready();
86public slots:
87
98 virtual void reload() {};
99protected:
107 virtual bool canReload() const;
108
109 void setStatus(Status newStatus);
110 void setError(QNetworkReply::NetworkError error);
111 void setErrorString(const QString &newErrorString);
112
113
115 if (canReload()) {
116 reload();
117 }
118 }
119 void classBegin() override {
120 m_isParsing = true;
121 }
122
123 void componentComplete() override {
124 m_isParsing = false;
126 }
128protected:
129 // Returns true if this class is instantiated within QML and is still being parsed.
130 bool isQmlParsing() const { return m_isParsing; }
131 void emitDataChanged();
132private:
133 Status m_status = Uninitialised;
134 QString m_errorString;
135 bool m_autoReload = true;
136 bool m_isParsing = false;
137};
138
147template <class T, class R, class P>
148class Loader : public LoaderBase {
149 using RFutureWatcher = QFutureWatcher<std::optional<R>>;
150public:
151 Loader(Support::Loader<R, P> *loaderImpl, QObject *parent = nullptr)
152 : Loader(nullptr, loaderImpl, parent) {}
153
154 Loader(ApiClient *apiClient, Support::Loader<R, P> *loaderImpl, QObject *parent = nullptr)
155 : LoaderBase(apiClient, parent),
156 m_loader(loaderImpl) {
157
158 m_dataViewModel = new T(this);
161 }
162
163 T *dataViewModel() const { return m_dataViewModel; }
164 QObject *data() const override { return m_dataViewModel; }
165
166 void reload() override {
167 if (m_loader->isRunning()) {
168 m_loader->cancel();
169 };
171 m_loader->setApiClient(m_apiClient);
172 m_loader->setParameters(m_parameters);
173 m_loader->load();
174 }
175protected:
181 QScopedPointer<Support::Loader<R, P>> m_loader = nullptr;
182private:
183
187 void onLoaderReady() {
188 try {
189 R newData = m_loader->result();
190 if (m_dataViewModel->data()->sameAs(newData)) {
191 // Replace the data the model holds
192 m_dataViewModel->data()->replaceData(newData);
193 } else {
194 // Replace the model
195 using PointerType = typename decltype(m_dataViewModel->data())::Type;
196 m_dataViewModel = new T(this, QSharedPointer<PointerType>::create(newData, m_apiClient));
197 }
200 } catch(QException &e) {
201 setErrorString(e.what());
203 }
204 }
205
206 void onLoaderError(QString message) {
208 setErrorString(message);
209 }
210};
211
212void registerRemoteTypes(const char *uri);
213
214} // NS ViewModel
215} // NS Jellyfin
216
217#endif // JELLYFIN_DTO_DTO_H
An Api client for Jellyfin. Handles requests and authentication.
Definition apiclient.h:90
void error(QString message=QString())
Emitted when an error has occurred during loading and no result is available.
void ready()
Emitted when data was successfully loaded.
Definition loader.h:134
An "interface" for a remote data source.
Definition loader.h:42
void setExtraFields(const QStringList &extraFields)
LoaderBase(ApiClient *apiClient, QObject *parent=nullptr)
Definition loader.h:59
bool isQmlParsing() const
Definition loader.h:130
void classBegin() override
Definition loader.h:119
void ready()
Convenience signal for status == RemoteData.Ready.
QObject * data
Definition loader.h:66
void statusChanged(Jellyfin::ViewModel::LoaderBase::Status newStatus)
void autoReloadChanged(bool newAutoReload)
void setApiClient(ApiClient *newApiClient)
Definition loader.cpp:41
void setStatus(Status newStatus)
Definition loader.cpp:30
Status
Definition loader.h:46
@ Ready
The data is ready, the properties in this object are up to date.
Definition loader.h:52
@ Loading
The data is being loaded over the network.
Definition loader.h:50
@ Error
An error has occurred while loading the data. See error() for more details.
Definition loader.h:54
@ Uninitialised
The data is unitialized and not loading either.
Definition loader.h:48
void reloadIfNeeded()
Definition loader.h:114
void setErrorString(const QString &newErrorString)
Definition loader.cpp:36
bool autoReload
Definition loader.h:65
void componentComplete() override
Definition loader.h:123
virtual void reload()
Overload this method to reimplement the fetching mechanism to populate the RemoteData with data from ...
Definition loader.h:98
void errorStringChanged(QString newErrorString)
void apiClientChanged(ApiClient *newApiClient)
void setError(QNetworkReply::NetworkError error)
QString errorString
Definition loader.h:64
virtual QObject * data() const
Definition loader.h:71
ApiClient * apiClient
Definition loader.h:62
Jellyfin::ViewModel::LoaderBase::Status status
Definition loader.h:63
void emitDataChanged()
Definition loader.cpp:47
virtual bool canReload() const
Subclasses should implement this to determine if they can load data from the server.
Definition loader.cpp:26
QString errorString() const
Definition loader.h:69
ApiClient * m_apiClient
Definition loader.h:127
Definition loader.h:148
QObject * data() const override
Definition loader.h:164
Loader(Support::Loader< R, P > *loaderImpl, QObject *parent=nullptr)
Definition loader.h:151
QScopedPointer< Support::Loader< R, P > > m_loader
Subclasses should initialize this to a loader that actually loads stuff.
Definition loader.h:181
P m_parameters
Definition loader.h:177
Loader(ApiClient *apiClient, Support::Loader< R, P > *loaderImpl, QObject *parent=nullptr)
Definition loader.h:154
T * m_dataViewModel
Definition loader.h:176
T * dataViewModel() const
Definition loader.h:163
void reload() override
Overload this method to reimplement the fetching mechanism to populate the RemoteData with data from ...
Definition loader.h:166
void registerRemoteTypes(const char *uri)
Definition loader.cpp:51
void writeRequestTypesFile R(File headerFile, File implementationFile, R endpoints) if(is(ElementType!R
Definition openapigenerator.d:278