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

Big C++ refractor

- Removed "jellyfin" prefix from files, as they are already in a
  directory named Jellyfin
- Split the former "jellyfinitem.{h,cpp}" into multiple files in the DTO
  directory, one for each class. The jellyfinitem files started to
  become enormous.
- Use forward declarations in headers instead of including files
  wherever possible.
- Updated copyright headers
This commit is contained in:
Chris Josten 2021-02-17 19:42:10 +01:00
parent b345a1c650
commit 895731ae38
34 changed files with 914 additions and 463 deletions

View file

@ -0,0 +1,167 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_DTO
#define JELLYFIN_DTO_DTO
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QMetaObject>
#include <QMetaProperty>
#include <QNetworkReply>
#include <QObject>
#include <QRegularExpression>
#include <QString>
#include <QVariant>
#include "../apiclient.h"
#include "../jsonhelper.h"
namespace Jellyfin {
namespace DTO {
/**
* @brief Base class for a serializable object.
*
* This class will be (de)serialized based on its properties.
* Note: it must have a constructor without arguments marked with Q_INVOKABLE
*/
class JsonSerializable : public QObject {
Q_OBJECT
public:
Q_INVOKABLE JsonSerializable(QObject *parent);
/**
* @brief Sets this objects properties based on obj.
* @param obj The data to load into this object.
*/
void deserialize(const QJsonObject &obj);
QJsonObject serialize(bool capitalize = true) const;
private:
QVariant jsonToVariant(QMetaProperty prop, const QJsonValue &val, const QJsonObject &root);
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).
* @param str The string to modify
* @return THe modified string
*/
static QString fromPascalCase(QString str);
/**
* @brief Sets the first letter of the string to uper case (to make it PascalCase).
* @param str The string to modify
* @return THe modified string
*/
static QString toPascalCase(QString st);
static const QRegularExpression m_listExpression;
/**
* @brief Qt is doing weird. I'll keep track of the metatypes myself.
*/
QHash<QString, const QMetaType *> m_nameMetatypeMap;
};
/**
* @brief An "interface" for a remote data source
*
* This class is basically a base class for JSON data that can be fetched from over the network.
* Subclasses should reimplement reload and call setStatus to update the QML part of the code
* appropiatly.
*/
class RemoteData : public JsonSerializable {
Q_OBJECT
public:
enum Status {
/// The data is unitialized and not loading either.
Uninitialised,
/// The data is being loaded over the network
Loading,
/// The data is ready, the properties in this object are up to date.
Ready,
/// An error has occurred while loading the data. See error() for more details.
Error
};
Q_ENUM(Status)
explicit RemoteData(QObject *parent = nullptr);
Q_PROPERTY(ApiClient *apiClient MEMBER m_apiClient WRITE setApiClient NOTIFY apiClientChanged STORED false)
Q_PROPERTY(Status status READ status NOTIFY statusChanged STORED false)
Q_PROPERTY(QNetworkReply::NetworkError error READ error NOTIFY errorChanged STORED false)
Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged STORED false)
Status status() const { return m_status; }
QNetworkReply::NetworkError error() const { return m_error; }
QString errorString() const { return m_errorString; }
void setApiClient(ApiClient *newApiClient);
signals:
void statusChanged(Status newStatus);
void apiClientChanged(ApiClient *newApiClient);
void errorChanged(QNetworkReply::NetworkError newError);
void errorStringChanged(QString newErrorString);
/**
* @brief Convenience signal for status == RemoteData.Ready.
*/
void ready();
public slots:
/**
* @brief Overload this method to reimplement the fetching mechanism to
* populate the RemoteData with data from the server.
*
* The default implementation makes a GET request to getDataUrl() and parses the resulting JSON,
* which should be enough for most cases. Consider overriding getDataUrl() and
* canRelaod() if possible. Manual overrides need to make sure that
* they're calling setStatus(Status), setError(QNetworkReply::NetworkError) and
* setErrorString() to let the QML side know what this thing is up to.
*/
virtual void reload();
protected:
/**
* @brief Subclasses should implement this to determine if they can
* load data from the server.
*
* Usage cases include checking if the
* required properties, such as the item id are set.
*/
virtual bool canReload() const = 0;
/**
* @brief Construct the URL to fetch the data from.
* @return The URL to load data from.
*/
virtual QString getDataUrl() const = 0;
void setStatus(Status newStatus);
void setError(QNetworkReply::NetworkError error);
void setErrorString(const QString &newErrorString);
ApiClient *m_apiClient = nullptr;
private:
Status m_status = Uninitialised;
QNetworkReply::NetworkError m_error = QNetworkReply::NoError;
QString m_errorString;
};
} // NS DTO
} // NS Jellyfin
#endif // JELLYFIN_DTO_DTO_H

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -25,278 +25,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>
#include <QMetaObject>
#include <QMetaProperty>
#include <QDateTime>
#include <QDebug>
#include <QList>
#include <QObject>
#include <QRegularExpression>
#include <QtQml>
#include <QNetworkReply>
#include <optional>
#include <cmath>
#include "jellyfinapiclient.h"
#include "jsonhelper.h"
#include "dto.h"
#include "mediastream.h"
#include "namedguidpair.h"
#include "userdata.h"
namespace Jellyfin {
class ApiClient;
/**
* @brief Base class for a serializable object.
*
* This class will be (de)serialized based on its properties.
* Note: it must have a constructor without arguments marked with Q_INVOKABLE
*/
class JsonSerializable : public QObject {
Q_OBJECT
public:
Q_INVOKABLE JsonSerializable(QObject *parent);
/**
* @brief Sets this objects properties based on obj.
* @param obj The data to load into this object.
*/
void deserialize(const QJsonObject &obj);
QJsonObject serialize(bool capitalize = true) const;
private:
QVariant jsonToVariant(QMetaProperty prop, const QJsonValue &val, const QJsonObject &root);
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).
* @param str The string to modify
* @return THe modified string
*/
static QString fromPascalCase(QString str);
/**
* @brief Sets the first letter of the string to uper case (to make it PascalCase).
* @param str The string to modify
* @return THe modified string
*/
static QString toPascalCase(QString st);
static const QRegularExpression m_listExpression;
/**
* @brief Qt is doing weird. I'll keep track of the metatypes myself.
*/
QHash<QString, const QMetaType *> m_nameMetatypeMap;
};
/**
* @brief An "interface" for a remote data source
*
* This class is basically a base class for JSON data that can be fetched from over the network.
* Subclasses should reimplement reload and call setStatus to update the QML part of the code
* appropiatly.
*/
class RemoteData : public JsonSerializable {
Q_OBJECT
public:
enum Status {
/// The data is unitialized and not loading either.
Uninitialised,
/// The data is being loaded over the network
Loading,
/// The data is ready, the properties in this object are up to date.
Ready,
/// An error has occurred while loading the data. See error() for more details.
Error
};
Q_ENUM(Status)
explicit RemoteData(QObject *parent = nullptr);
Q_PROPERTY(ApiClient *apiClient MEMBER m_apiClient WRITE setApiClient NOTIFY apiClientChanged STORED false)
Q_PROPERTY(Status status READ status NOTIFY statusChanged STORED false)
Q_PROPERTY(QNetworkReply::NetworkError error READ error NOTIFY errorChanged STORED false)
Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged STORED false)
Status status() const { return m_status; }
QNetworkReply::NetworkError error() const { return m_error; }
QString errorString() const { return m_errorString; }
void setApiClient(ApiClient *newApiClient);
signals:
void statusChanged(Status newStatus);
void apiClientChanged(ApiClient *newApiClient);
void errorChanged(QNetworkReply::NetworkError newError);
void errorStringChanged(QString newErrorString);
/**
* @brief Convenience signal for status == RemoteData.Ready.
*/
void ready();
public slots:
/**
* @brief Overload this method to reimplement the fetching mechanism to
* populate the RemoteData with data from the server.
*
* The default implementation makes a GET request to getDataUrl() and parses the resulting JSON,
* which should be enough for most cases. Consider overriding getDataUrl() and
* canRelaod() if possible. Manual overrides need to make sure that
* they're calling setStatus(Status), setError(QNetworkReply::NetworkError) and
* setErrorString() to let the QML side know what this thing is up to.
*/
virtual void reload();
protected:
/**
* @brief Subclasses should implement this to determine if they can
* load data from the server.
*
* Usage cases include checking if the
* required properties, such as the item id are set.
*/
virtual bool canReload() const = 0;
/**
* @brief Construct the URL to fetch the data from.
* @return The URL to load data from.
*/
virtual QString getDataUrl() const = 0;
void setStatus(Status newStatus);
void setError(QNetworkReply::NetworkError error);
void setErrorString(const QString &newErrorString);
ApiClient *m_apiClient = nullptr;
private:
Status m_status = Uninitialised;
QNetworkReply::NetworkError m_error = QNetworkReply::NoError;
QString m_errorString;
};
class NameGuidPair : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE NameGuidPair(QObject *parent = nullptr);
Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
// Once again the Jellyfin id workaround
Q_PROPERTY(QString jellyfinId MEMBER m_id NOTIFY jellyfinIdChanged)
signals:
void nameChanged(const QString &newName);
void jellyfinIdChanged(const QString &newJellyfinId);
private:
QString m_name;
QString m_id;
};
class User : public RemoteData {
Q_OBJECT
public:
Q_INVOKABLE User(QObject *parent = nullptr);
Q_PROPERTY(QString userId MEMBER m_userId WRITE setUserId NOTIFY userIdChanged)
Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
Q_PROPERTY(QString primaryImageTag MEMBER m_primaryImageTag NOTIFY primaryImageTagChanged)
void setUserId(const QString &newUserId) {
this->m_userId = newUserId;
emit userIdChanged(newUserId);
reload();
}
signals:
void userIdChanged(const QString &newUserId);
void nameChanged(const QString &newName);
void primaryImageTagChanged(const QString &newPrimaryImageTag);
protected:
QString getDataUrl() const override;
bool canReload() const override;
private:
QString m_userId;
QString m_name;
QString m_primaryImageTag;
};
class MediaStream : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE explicit MediaStream(QObject *parent = nullptr);
MediaStream(const MediaStream &other);
bool operator==(const MediaStream &other);
virtual ~MediaStream() { qDebug() << "MediaStream destroyed"; }
enum MediaStreamType {
Undefined,
Audio,
Video,
Subtitle,
EmbeddedImage
};
Q_ENUM(MediaStreamType)
Q_PROPERTY(QString codec MEMBER m_codec NOTIFY codecChanged)
Q_PROPERTY(QString codecTag MEMBER m_codecTag NOTIFY codecTagChanged)
Q_PROPERTY(QString language MEMBER m_language NOTIFY languageChanged)
Q_PROPERTY(QString displayTitle MEMBER m_displayTitle NOTIFY displayTitleChanged)
Q_PROPERTY(MediaStreamType type MEMBER m_type NOTIFY typeChanged)
Q_PROPERTY(int index MEMBER m_index NOTIFY indexChanged)
signals:
void codecChanged(const QString &newCodec);
void codecTagChanged(const QString &newCodecTag);
void languageChanged(const QString &newLanguage);
void displayTitleChanged(const QString &newDisplayTitle);
void typeChanged(MediaStreamType newType);
void indexChanged(int newIndex);
private:
QString m_codec;
QString m_codecTag;
QString m_language;
QString m_displayTitle;
MediaStreamType m_type = Undefined;
int m_index = -1;
};
class UserData : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE explicit UserData(QObject *parent = nullptr);
Q_PROPERTY(double playedPercentage READ playedPercentage WRITE setPlayedPercentage RESET resetPlayedPercentage NOTIFY playedPercentageChanged)
Q_PROPERTY(qint64 playbackPositionTicks READ playbackPositionTicks WRITE setPlaybackPositionTicks NOTIFY playbackPositionTicksChanged)
Q_PROPERTY(bool isFavorite READ isFavorite WRITE setIsFavorite NOTIFY isFavoriteChanged)
Q_PROPERTY(bool likes READ likes WRITE setLikes RESET resetLikes NOTIFY likesChanged)
Q_PROPERTY(bool played READ played WRITE setPlayed NOTIFY playedChanged)
Q_PROPERTY(QString itemId READ itemId MEMBER m_itemId);
double playedPercentage() const { return m_playedPercentage.value_or(0.0); }
void setPlayedPercentage(double newPlayedPercentage) { m_playedPercentage = newPlayedPercentage; emit playedPercentageChanged(newPlayedPercentage); }
void resetPlayedPercentage() { m_playedPercentage = std::nullopt; emit playedPercentageChanged(0.0); updateOnServer(); }
qint64 playbackPositionTicks() const { return m_playbackPositionTicks; }
void setPlaybackPositionTicks(qint64 newPlaybackPositionTicks) { m_playbackPositionTicks = newPlaybackPositionTicks; emit playbackPositionTicksChanged(newPlaybackPositionTicks); }
bool played() const { return m_played; }
void setPlayed(bool newPlayed) { m_played = newPlayed; emit playedChanged(newPlayed); updateOnServer(); }
bool likes() const { return m_likes.value_or(false); }
void setLikes(bool newLikes) { m_likes = newLikes; emit likesChanged(newLikes); }
void resetLikes() { m_likes = std::nullopt; emit likesChanged(false); updateOnServer(); }
bool isFavorite() const { return m_isFavorite; }
void setIsFavorite(bool newIsFavorite) { m_isFavorite = newIsFavorite; emit isFavoriteChanged(newIsFavorite); updateOnServer(); }
const QString &itemId() const { return m_itemId; }
signals:
void playedPercentageChanged(double newPlayedPercentage);
void playbackPositionTicksChanged(qint64 playbackPositionTicks);
void isFavoriteChanged(bool newIsFavorite);
void likesChanged(bool newLikes);
void playedChanged(bool newPlayed);
public slots:
void updateOnServer();
void onUpdated(QSharedPointer<UserData> other);
private:
std::optional<double> m_playedPercentage = std::nullopt;
qint64 m_playbackPositionTicks = 0;
bool m_isFavorite = false;
std::optional<bool> m_likes = std::nullopt;
bool m_played;
QString m_itemId;
};
namespace DTO {
class Item : public RemoteData {
Q_OBJECT
@ -527,24 +272,9 @@ protected:
QString m_mediaType;
int m_width;
int m_height;
template<typename T>
QQmlListProperty<T> toReadOnlyQmlListProperty(QList<T *> &list) {
return QQmlListProperty<T>(this, std::addressof(list), &qlist_count, &qlist_at);
}
template<typename T>
static int qlist_count(QQmlListProperty<T> *p) {
return reinterpret_cast<QList<T *> *>(p->data)->count();
}
template<typename T>
static T *qlist_at(QQmlListProperty<T> *p, int idx) {
return reinterpret_cast<QList<T *> *>(p->data)->at(idx);
}
};
void registerSerializableJsonTypes(const char* URI);
}
} // NS DTO
} // NS Jellyfin
#endif // JELLYFIN_ITEM_H

View file

@ -0,0 +1,74 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_MEDIASTREAM_H
#define JELLYFIN_DTO_MEDIASTREAM_H
#include <QDebug>
#include <QObject>
#include <QString>
#include "dto.h"
namespace Jellyfin {
namespace DTO {
class MediaStream : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE explicit MediaStream(QObject *parent = nullptr);
MediaStream(const MediaStream &other);
bool operator==(const MediaStream &other);
virtual ~MediaStream() { qDebug() << "MediaStream destroyed"; }
enum MediaStreamType {
Undefined,
Audio,
Video,
Subtitle,
EmbeddedImage
};
Q_ENUM(MediaStreamType)
Q_PROPERTY(QString codec MEMBER m_codec NOTIFY codecChanged)
Q_PROPERTY(QString codecTag MEMBER m_codecTag NOTIFY codecTagChanged)
Q_PROPERTY(QString language MEMBER m_language NOTIFY languageChanged)
Q_PROPERTY(QString displayTitle MEMBER m_displayTitle NOTIFY displayTitleChanged)
Q_PROPERTY(MediaStreamType type MEMBER m_type NOTIFY typeChanged)
Q_PROPERTY(int index MEMBER m_index NOTIFY indexChanged)
signals:
void codecChanged(const QString &newCodec);
void codecTagChanged(const QString &newCodecTag);
void languageChanged(const QString &newLanguage);
void displayTitleChanged(const QString &newDisplayTitle);
void typeChanged(MediaStreamType newType);
void indexChanged(int newIndex);
private:
QString m_codec;
QString m_codecTag;
QString m_language;
QString m_displayTitle;
MediaStreamType m_type = Undefined;
int m_index = -1;
};
}
}
#endif // JELLYFIN_DTO_MEDIASTREAM_H

View file

@ -0,0 +1,50 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_NAMEDGUIDPAIR_H
#define JELLYFIN_DTO_NAMEDGUIDPAIR_H
#include <QObject>
#include <QString>
#include "dto.h"
namespace Jellyfin {
namespace DTO {
class NameGuidPair : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE NameGuidPair(QObject *parent = nullptr);
Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
// Once again the Jellyfin id workaround
Q_PROPERTY(QString jellyfinId MEMBER m_id NOTIFY jellyfinIdChanged)
signals:
void nameChanged(const QString &newName);
void jellyfinIdChanged(const QString &newJellyfinId);
private:
QString m_name;
QString m_id;
};
} // NS DTO
} // NS JELLYFIN
#endif // JELLYFIN_DTO_NAMEDGUIDPAIR_H

View file

@ -0,0 +1,41 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_TYPES_H
#define JELLYFIN_DTO_TYPES_H
#include "dto.h"
#include "item.h"
#include "mediastream.h"
#include "namedguidpair.h"
#include "user.h"
#include "userdata.h"
namespace Jellyfin {
namespace DTO {
/**
* @brief registerTypes Registers all DTO types to the QML type system
* @param uri The uri to register the items under.
*/
void registerTypes(const char *uri);
} // NS DTO
} // NS Jellyfin
#endif // JELLYFIN_DTO_TYPES_H

View file

@ -0,0 +1,61 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_USER_H
#define JELLYFIN_DTO_USER_H
#include <QObject>
#include <QString>
#include "dto.h"
namespace Jellyfin {
namespace DTO {
class User : public RemoteData {
Q_OBJECT
public:
Q_INVOKABLE User(QObject *parent = nullptr);
Q_PROPERTY(QString userId MEMBER m_userId WRITE setUserId NOTIFY userIdChanged)
Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
Q_PROPERTY(QString primaryImageTag MEMBER m_primaryImageTag NOTIFY primaryImageTagChanged)
void setUserId(const QString &newUserId) {
this->m_userId = newUserId;
emit userIdChanged(newUserId);
reload();
}
signals:
void userIdChanged(const QString &newUserId);
void nameChanged(const QString &newName);
void primaryImageTagChanged(const QString &newPrimaryImageTag);
protected:
QString getDataUrl() const override;
bool canReload() const override;
private:
QString m_userId;
QString m_name;
QString m_primaryImageTag;
};
} // NS DTO
} // NS Jellyfin
#endif // JELLYFIN_DTO_USER

View file

@ -0,0 +1,83 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_DTO_USERDATA
#define JELLYFIN_DTO_USERDATA
#include <QObject>
#include <QSharedPointer>
#include <QString>
#include "dto.h"
namespace Jellyfin {
namespace DTO {
class UserData : public JsonSerializable {
Q_OBJECT
public:
Q_INVOKABLE explicit UserData(QObject *parent = nullptr);
Q_PROPERTY(double playedPercentage READ playedPercentage WRITE setPlayedPercentage RESET resetPlayedPercentage NOTIFY playedPercentageChanged)
Q_PROPERTY(qint64 playbackPositionTicks READ playbackPositionTicks WRITE setPlaybackPositionTicks NOTIFY playbackPositionTicksChanged)
Q_PROPERTY(bool isFavorite READ isFavorite WRITE setIsFavorite NOTIFY isFavoriteChanged)
Q_PROPERTY(bool likes READ likes WRITE setLikes RESET resetLikes NOTIFY likesChanged)
Q_PROPERTY(bool played READ played WRITE setPlayed NOTIFY playedChanged)
Q_PROPERTY(QString itemId READ itemId MEMBER m_itemId)
double playedPercentage() const { return m_playedPercentage.value_or(0.0); }
void setPlayedPercentage(double newPlayedPercentage) { m_playedPercentage = newPlayedPercentage; emit playedPercentageChanged(newPlayedPercentage); }
void resetPlayedPercentage() { m_playedPercentage = std::nullopt; emit playedPercentageChanged(0.0); updateOnServer(); }
qint64 playbackPositionTicks() const { return m_playbackPositionTicks; }
void setPlaybackPositionTicks(qint64 newPlaybackPositionTicks) { m_playbackPositionTicks = newPlaybackPositionTicks; emit playbackPositionTicksChanged(newPlaybackPositionTicks); }
bool played() const { return m_played; }
void setPlayed(bool newPlayed) { m_played = newPlayed; emit playedChanged(newPlayed); updateOnServer(); }
bool likes() const { return m_likes.value_or(false); }
void setLikes(bool newLikes) { m_likes = newLikes; emit likesChanged(newLikes); }
void resetLikes() { m_likes = std::nullopt; emit likesChanged(false); updateOnServer(); }
bool isFavorite() const { return m_isFavorite; }
void setIsFavorite(bool newIsFavorite) { m_isFavorite = newIsFavorite; emit isFavoriteChanged(newIsFavorite); updateOnServer(); }
const QString &itemId() const { return m_itemId; }
signals:
void playedPercentageChanged(double newPlayedPercentage);
void playbackPositionTicksChanged(qint64 playbackPositionTicks);
void isFavoriteChanged(bool newIsFavorite);
void likesChanged(bool newLikes);
void playedChanged(bool newPlayed);
public slots:
void updateOnServer();
void onUpdated(QSharedPointer<UserData> other);
private:
std::optional<double> m_playedPercentage = std::nullopt;
qint64 m_playbackPositionTicks = 0;
bool m_isFavorite = false;
std::optional<bool> m_likes = std::nullopt;
bool m_played;
QString m_itemId;
};
}
}
#endif // JELLYFIN_DTO_USERDATA

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -37,15 +37,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <QUrlQuery>
#include "credentialmanager.h"
#include "jellyfindeviceprofile.h"
#include "jellyfinitem.h"
#include "jellyfinplaybackmanager.h"
#include "jellyfinwebsocket.h"
#include "deviceprofile.h"
#include "websocket.h"
namespace Jellyfin {
class MediaSource;
class WebSocket;
class PlaybackManager;
namespace DTO {
class UserData; // Keep it as an opaque pointer
}
using namespace DTO;
/**
* @brief An Api client for Jellyfin. Handles requests and authentication.
*

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -29,10 +29,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <QtQml>
#include <QVariant>
#include "jellyfinapiclient.h"
#include "apiclient.h"
#include "jsonhelper.h"
namespace Jellyfin {
namespace DTO {
class JsonSerializable;
}
class SortOptions : public QObject{
Q_OBJECT
public:
@ -267,7 +271,7 @@ class ItemModel : public ApiModel {
public:
explicit ItemModel (QString path, bool responseHasRecords, bool replaceUser, QObject *parent = nullptr);
public slots:
void onUserDataChanged(const QString &itemId, QSharedPointer<UserData> userData);
void onUserDataChanged(const QString &itemId, QSharedPointer<DTO::UserData> userData);
};
class UserViewModel : public ApiModel {

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

View file

@ -1,13 +1,38 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_H
#define JELLYFIN_H
#include <QtQml>
#include "JellyfinQt/jellyfinapiclient.h"
#include "JellyfinQt/jellyfinapimodel.h"
#include "JellyfinQt/jellyfinitem.h"
#include "JellyfinQt/serverdiscoverymodel.h"
#include "JellyfinQt/jellyfinplaybackmanager.h"
#include "DTO/dto.h"
#include "DTO/item.h"
#include "DTO/mediastream.h"
#include "DTO/namedguidpair.h"
#include "DTO/types.h"
#include "DTO/user.h"
#include "DTO/userdata.h"
#include "apiclient.h"
#include "apimodel.h"
#include "serverdiscoverymodel.h"
#include "playbackmanager.h"
namespace Jellyfin {
void registerTypes(const char *uri = "nl.netsoj.chris.Jellyfin");

View file

@ -1,3 +1,21 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JSON_SERIALIZER_H
#define JSON_SERIALIZER_H

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -30,16 +30,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <QtMultimedia/QMediaPlayer>
#include "JellyfinQt/DTO/item.h"
#include "jellyfinapiclient.h"
#include "jellyfinitem.h"
#include "apiclient.h"
namespace Jellyfin {
// Forward declaration of Jellyfin::Item found in jellyfinitem.h
class Item;
// Forward declaration of Jellyfin::ApiClient found in jellyfinapiclient.h
class ApiClient;
using namespace DTO;
/**
* @brief The PlaybackManager class manages the playback of Jellyfin items. It fetches streams based on Jellyfin items, posts
@ -95,6 +94,16 @@ public slots:
* @param itemId The id of the item to play.
*/
void playItem(const QString &itemId);
/**
* @brief previous Play the previous track in the current playlist.
*/
void previous();
/**
* @brief next Play the next track in the current playlist.
*/
void next();
private slots:
void mediaPlayerStateChanged(QMediaPlayer::State newState);
void mediaPlayerPositionChanged(qint64 position);

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -31,12 +31,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <QtWebSockets/QWebSocket>
#include "jellyfinapiclient.h"
#include "jellyfinitem.h"
#include "apiclient.h"
namespace Jellyfin {
class ApiClient;
namespace DTO {
class UserData;
}
/**
* @brief Keeps a connection with the Jellyfin server to receive real time updates.
*