File indexing completed on 2024-05-12 05:04:08

0001 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #include "announcementmodel.h"
0005 
0006 #include "abstractaccount.h"
0007 #include "accountmanager.h"
0008 
0009 using namespace Qt::Literals::StringLiterals;
0010 
0011 AnnouncementModel::AnnouncementModel(QObject *parent)
0012     : QAbstractListModel(parent)
0013 {
0014     fillTimeline();
0015 }
0016 
0017 QVariant AnnouncementModel::data(const QModelIndex &index, int role) const
0018 {
0019     Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
0020 
0021     const auto &announcement = m_announcements[index.row()];
0022 
0023     switch (role) {
0024     case IdRole:
0025         return announcement.id;
0026     case ContentRole:
0027         return announcement.content;
0028     case PublishedAt:
0029         return announcement.publishedAt;
0030     default:
0031         return {};
0032     }
0033 }
0034 
0035 bool AnnouncementModel::loading() const
0036 {
0037     return m_loading;
0038 }
0039 
0040 void AnnouncementModel::setLoading(bool loading)
0041 {
0042     if (m_loading == loading) {
0043         return;
0044     }
0045     m_loading = loading;
0046     Q_EMIT loadingChanged();
0047 }
0048 
0049 int AnnouncementModel::rowCount(const QModelIndex &parent) const
0050 {
0051     return parent.isValid() ? 0 : m_announcements.size();
0052 }
0053 
0054 QHash<int, QByteArray> AnnouncementModel::roleNames() const
0055 {
0056     return {
0057         {IdRole, "id"},
0058         {ContentRole, "content"},
0059         {PublishedAt, "publishedAt"},
0060     };
0061 }
0062 
0063 void AnnouncementModel::fillTimeline()
0064 {
0065     const auto account = AccountManager::instance().selectedAccount();
0066 
0067     if (m_loading) {
0068         return;
0069     }
0070     setLoading(true);
0071 
0072     account->get(account->apiUrl(QStringLiteral("/api/v1/announcements")), true, this, [this](QNetworkReply *reply) {
0073         const auto doc = QJsonDocument::fromJson(reply->readAll());
0074         auto announcements = doc.array().toVariantList();
0075         std::reverse(announcements.begin(), announcements.end());
0076 
0077         if (!announcements.isEmpty()) {
0078             QList<Announcement> fetchedAnnouncements;
0079 
0080             std::transform(announcements.cbegin(), announcements.cend(), std::back_inserter(fetchedAnnouncements), [=](const QVariant &value) -> auto {
0081                 return fromSourceData(value.toJsonObject());
0082             });
0083             beginInsertRows({}, m_announcements.size(), m_announcements.size() + fetchedAnnouncements.size() - 1);
0084             m_announcements += fetchedAnnouncements;
0085             endInsertRows();
0086         }
0087 
0088         setLoading(false);
0089     });
0090 }
0091 
0092 AnnouncementModel::Announcement AnnouncementModel::fromSourceData(const QJsonObject &object) const
0093 {
0094     Announcement announcement;
0095     announcement.id = object["id"_L1].toString();
0096     announcement.content = object["content"_L1].toString();
0097     announcement.publishedAt = QDateTime::fromString(object["published_at"_L1].toString(), Qt::ISODate).toLocalTime();
0098 
0099     return announcement;
0100 }
0101 
0102 #include "moc_announcementmodel.cpp"