File indexing completed on 2024-06-23 08:24:57

0001 // SPDX-FileCopyrightText: 2021 kaniini <https://git.pleroma.social/kaniini>
0002 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0003 // SPDX-License-Identifier: GPL-3.0-only
0004 
0005 #pragma once
0006 
0007 #include "poll.h"
0008 
0009 #include <QImage>
0010 
0011 class Post;
0012 class Identity;
0013 class AbstractAccount;
0014 
0015 class Application
0016 {
0017     Q_GADGET
0018 
0019     Q_PROPERTY(QString name READ name)
0020     Q_PROPERTY(QUrl website READ website)
0021 
0022 public:
0023     Application() = default;
0024     explicit Application(QJsonObject application);
0025 
0026     QString name() const;
0027     QUrl website() const;
0028 
0029 private:
0030     QJsonObject m_application;
0031 };
0032 
0033 class Card
0034 {
0035     Q_GADGET
0036 
0037     Q_PROPERTY(QString authorName READ authorName)
0038     Q_PROPERTY(QString authorUrl READ authorUrl)
0039     Q_PROPERTY(QString blurhash READ blurhash)
0040     Q_PROPERTY(QString description READ description)
0041     Q_PROPERTY(QString embedUrl READ embedUrl)
0042     Q_PROPERTY(int width READ width)
0043     Q_PROPERTY(int height READ height)
0044     Q_PROPERTY(QString html READ html)
0045     Q_PROPERTY(QString image READ image)
0046     Q_PROPERTY(QString providerName READ providerName)
0047     Q_PROPERTY(QString providerUrl READ providerUrl)
0048     Q_PROPERTY(QString title READ title)
0049     Q_PROPERTY(QUrl url READ url)
0050 
0051 public:
0052     Card() = default;
0053     explicit Card(QJsonObject card);
0054 
0055     QString authorName() const;
0056     QString authorUrl() const;
0057     QString blurhash() const;
0058     QString description() const;
0059     QString embedUrl() const;
0060     int width() const;
0061     int height() const;
0062     QString html() const;
0063     QString image() const;
0064     QString providerName() const;
0065     QString providerUrl() const;
0066     QString title() const;
0067     QUrl url() const;
0068 
0069 private:
0070     QJsonObject m_card;
0071 };
0072 
0073 /// Post's attachment object.
0074 /// TODO make it possible to fetch the images with a Qml image provider.
0075 /// TODO use getter and setter
0076 class Attachment : public QObject
0077 {
0078     Q_OBJECT
0079     QML_ELEMENT
0080     QML_UNCREATABLE("Access via Post")
0081 
0082     Q_PROPERTY(QString id MEMBER m_id CONSTANT)
0083     Q_PROPERTY(AttachmentType attachmentType MEMBER m_type CONSTANT)
0084     Q_PROPERTY(int type READ isVideo CONSTANT)
0085     Q_PROPERTY(QString previewUrl MEMBER m_preview_url CONSTANT)
0086     Q_PROPERTY(QString source MEMBER m_url CONSTANT)
0087     Q_PROPERTY(QString remoteUrl MEMBER m_remote_url CONSTANT)
0088     Q_PROPERTY(QString caption READ description CONSTANT)
0089     Q_PROPERTY(QString tempSource READ tempSource CONSTANT)
0090     Q_PROPERTY(int sourceWidth MEMBER m_sourceWidth CONSTANT)
0091     Q_PROPERTY(int sourceHeight MEMBER m_sourceHeight CONSTANT)
0092     Q_PROPERTY(double focusX READ focusX WRITE setFocusX NOTIFY focusXChanged)
0093     Q_PROPERTY(double focusY READ focusY WRITE setFocusY NOTIFY focusYChanged)
0094 
0095 public:
0096     explicit Attachment(QObject *parent = nullptr);
0097     explicit Attachment(const QJsonObject &object, QObject *parent = nullptr);
0098 
0099     enum AttachmentType {
0100         Unknown,
0101         Image,
0102         GifV,
0103         Video,
0104     };
0105     Q_ENUM(AttachmentType);
0106 
0107     Post *m_parent = nullptr;
0108 
0109     QString m_id;
0110     AttachmentType m_type = AttachmentType::Unknown;
0111     QString m_preview_url;
0112     QString m_url;
0113     QString m_remote_url;
0114     int m_sourceWidth = -1;
0115     int m_sourceHeight = -1;
0116 
0117     QString id() const;
0118 
0119     void setDescription(const QString &description);
0120     QString description() const;
0121 
0122     /// Used exclusively in Maximize component to tell it whether or not an attachment is a video
0123     int isVideo() const;
0124 
0125     QString tempSource() const;
0126 
0127     double focusX() const;
0128     void setFocusX(double value);
0129 
0130     double focusY() const;
0131     void setFocusY(double value);
0132 
0133 Q_SIGNALS:
0134     void focusXChanged();
0135     void focusYChanged();
0136 
0137 private:
0138     void fromJson(const QJsonObject &object);
0139 
0140     QString m_description;
0141     QString m_blurhash;
0142     double m_focusX = 0.0f;
0143     double m_focusY = 0.0f;
0144 };
0145 
0146 class Notification
0147 {
0148     Q_GADGET
0149 
0150 public:
0151     Notification() = default;
0152     explicit Notification(AbstractAccount *account, const QJsonObject &obj, QObject *parent = nullptr);
0153 
0154     enum Type { Mention, Follow, Repeat, Favorite, Poll, FollowRequest, Update, Status };
0155     Q_ENUM(Type);
0156 
0157     int id() const;
0158     AbstractAccount *account() const;
0159     Type type() const;
0160     Post *post() const;
0161     std::shared_ptr<Identity> identity() const;
0162 
0163 private:
0164     int m_id = 0;
0165 
0166     AbstractAccount *m_account = nullptr;
0167     Post *m_post = nullptr;
0168     Type m_type = Type::Favorite;
0169     std::shared_ptr<Identity> m_identity;
0170 
0171     Post *createPost(AbstractAccount *account, const QJsonObject &obj, QObject *parent);
0172 };
0173 
0174 class Post : public QObject
0175 {
0176     Q_OBJECT
0177     QML_ELEMENT
0178     QML_UNCREATABLE("Posts should be accessed via models")
0179 
0180     Q_PROPERTY(QString spoilerText READ spoilerText WRITE setSpoilerText NOTIFY spoilerTextChanged)
0181     Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)
0182     Q_PROPERTY(QString contentType READ contentType WRITE setContentType NOTIFY contentTypeChanged)
0183     Q_PROPERTY(bool sensitive READ sensitive WRITE setSensitive NOTIFY sensitiveChanged)
0184     Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
0185     Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
0186     Q_PROPERTY(QString inReplyTo READ inReplyTo WRITE setInReplyTo NOTIFY inReplyToChanged)
0187     Q_PROPERTY(QStringList mentions READ mentions WRITE setMentions NOTIFY mentionsChanged)
0188     Q_PROPERTY(Poll *poll READ poll NOTIFY pollChanged)
0189     Q_PROPERTY(QStringList filters READ filters CONSTANT)
0190     Q_PROPERTY(Identity *authorIdentity READ getAuthorIdentity CONSTANT)
0191     Q_PROPERTY(QQmlListProperty<Attachment> attachments READ attachmentList CONSTANT)
0192     Q_PROPERTY(QString relativeTime READ relativeTime CONSTANT)
0193     Q_PROPERTY(QString absoluteTime READ absoluteTime CONSTANT)
0194     Q_PROPERTY(Card *card READ getCard CONSTANT)
0195     Q_PROPERTY(QString type READ type CONSTANT)
0196     Q_PROPERTY(QString editedAt READ editedAt CONSTANT)
0197     Q_PROPERTY(bool wasEdited READ wasEdited CONSTANT)
0198     Q_PROPERTY(QList<QString> standaloneTags READ standaloneTags NOTIFY contentChanged)
0199 
0200 public:
0201     Post() = delete;
0202     Post(const Post &) = delete;
0203     explicit Post(AbstractAccount *account, QObject *parent = nullptr);
0204     Post(AbstractAccount *account, QJsonObject obj, QObject *parent = nullptr);
0205 
0206     enum Visibility { Public, Unlisted, Private, Direct, Local };
0207     Q_ENUM(Visibility)
0208 
0209     AbstractAccount *m_parent;
0210 
0211     QString type() const;
0212     void fromJson(QJsonObject obj);
0213 
0214     Identity *getAuthorIdentity() const;
0215     std::shared_ptr<Identity> authorIdentity() const;
0216     std::shared_ptr<Identity> boostIdentity() const;
0217     std::shared_ptr<Identity> replyIdentity() const;
0218     bool boosted() const;
0219 
0220     /// Returns the post id of the status itself
0221     QString postId() const;
0222     QString originalPostId() const;
0223     QUrl url() const;
0224 
0225     /// Returns the spoiler text (subject) of the status
0226     QString spoilerText() const;
0227     void setSpoilerText(const QString &spoilerText);
0228 
0229     QString content() const;
0230     void setContent(const QString &content);
0231     QVector<QString> standaloneTags() const;
0232     QString contentType() const;
0233     void setContentType(const QString &contentType);
0234     bool sensitive() const;
0235     void setSensitive(bool isSensitive);
0236     Visibility visibility() const;
0237     void setVisibility(Visibility visibility);
0238     QString language() const;
0239     void setLanguage(const QString &language);
0240     QString inReplyTo() const;
0241     void setInReplyTo(const QString &inReplyTo);
0242     QStringList mentions() const;
0243     void setMentions(const QStringList &mentions);
0244     std::optional<Card> card() const;
0245     Card *getCard() const;
0246     void setCard(std::optional<Card> card);
0247     std::optional<Application> application() const;
0248     void setApplication(std::optional<Application> application);
0249     void setPollJson(const QJsonObject &object);
0250     Poll *poll() const;
0251     QStringList filters() const;
0252 
0253     void addAttachment(const QJsonObject &attachment);
0254 
0255     /// Returns the published/creation time of this status.
0256     QDateTime publishedAt() const;
0257 
0258     /// Returns a locale-aware relative time.
0259     QString relativeTime() const;
0260 
0261     // Returns absolute locale-aware time
0262     QString absoluteTime() const;
0263 
0264     /// Returns the time this post was last edited
0265     QString editedAt() const;
0266 
0267     /// Returns if the post was edited at all
0268     bool wasEdited() const;
0269 
0270     /// Returns whether the user favorited this status.
0271     bool favourited() const;
0272     /// Set this post as favourited.
0273     void setFavourited(bool favourited);
0274     /// Returns whether the user reblogged this status.
0275     bool reblogged() const;
0276     /// Set this post as reblogged.
0277     void setReblogged(bool reblogged);
0278     /// Returns whether the user muted this status.
0279     bool muted() const;
0280     /// Set this post as muted.
0281     void setMuted(bool muted);
0282     /// Returns whether the user bookmarked this status.
0283     bool bookmarked() const;
0284     /// Set this post as bookmarked.
0285     void setBookmarked(bool bookmarked);
0286     /// Returns whether the user pinned this status.
0287     bool pinned() const;
0288     /// Set this status as pinned
0289     void setPinned(bool pinned);
0290     /// Returns whether the user filtered this status.
0291     bool filtered() const;
0292 
0293     /// Returns the number of time this status has been boosted.
0294     int reblogsCount() const;
0295     /// Returns the number of time this status has been favorited.
0296     int favouritesCount() const;
0297     /// Returns the number of time this status has been replied.
0298     int repliesCount() const;
0299 
0300     /// Returns whether this status is empty
0301     bool isEmpty() const;
0302 
0303     Q_INVOKABLE void addAttachments(const QJsonArray &attachments);
0304     void setDirtyAttachment();
0305     void updateAttachment(Attachment *a);
0306     QList<Attachment *> attachments() const;
0307     QQmlListProperty<Attachment> attachmentList() const;
0308     bool attachmentsVisible() const;
0309     void setAttachmentsVisible(bool attachmentsVisible);
0310 
0311     bool hidden() const
0312     {
0313         return m_hidden;
0314     }
0315 
0316     /// Parses a HTML body and returns a processed body and a list of tags respectively.
0317     /// The returned body does not have the tags included and is cleaned up.
0318     static QPair<QString, QList<QString>> parseContent(const QString &html);
0319 
0320 Q_SIGNALS:
0321     void spoilerTextChanged();
0322     void contentChanged();
0323     void contentTypeChanged();
0324     void sensitiveChanged();
0325     void visibilityChanged();
0326     void languageChanged();
0327     void inReplyToChanged();
0328     void mentionsChanged();
0329     void attachmentUploaded();
0330     void pollChanged();
0331     void replyIdentityChanged();
0332 
0333 private:
0334     bool m_attachments_visible = true;
0335     QDateTime m_publishedAt;
0336     QString m_postId;
0337     QString m_originalPostId;
0338     QUrl m_url;
0339     QString m_content;
0340     QString m_spoilerText;
0341     QString m_author;
0342     QString m_reply_to_author;
0343     QString m_content_type;
0344     QStringList m_mentions;
0345     QString m_language;
0346     QDateTime m_editedAt;
0347     QVector<QString> m_standaloneTags;
0348 
0349     QString m_replyTargetId;
0350     QStringList m_filters;
0351     std::optional<Card> m_card;
0352     std::optional<Application> m_application;
0353     std::shared_ptr<Identity> m_authorIdentity;
0354     QList<Attachment *> m_attachments;
0355     QQmlListProperty<Attachment> m_attachmentList;
0356     std::unique_ptr<Poll> m_poll;
0357 
0358     bool m_sensitive = false;
0359     Visibility m_visibility;
0360 
0361     bool m_boosted = false;
0362     std::shared_ptr<Identity> m_boostIdentity;
0363 
0364     std::shared_ptr<Identity> m_replyIdentity;
0365 
0366     bool m_favourited = false;
0367     bool m_reblogged = false;
0368     bool m_muted = false;
0369     bool m_bookmarked = false;
0370     bool m_filtered = false;
0371     bool m_hidden = false;
0372     bool m_pinned = false;
0373 
0374     int m_reblogsCount = 0;
0375     int m_favouritesCount = 0;
0376     int m_repliesCount = 0;
0377 };