File indexing completed on 2024-05-12 05:04:16
0001 // SPDX-FileCopyrightText: 2023 Shubham Arora <shubhamarora@protonmail.com> 0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0003 0004 #include "tagsmodel.h" 0005 0006 #include <KLocalizedString> 0007 0008 TagsModel::TagsModel(QObject *parent) 0009 : AbstractListModel(parent) 0010 { 0011 connect(this, &AbstractListModel::nameChanged, this, &TagsModel::onNameChanged); 0012 } 0013 0014 void TagsModel::onNameChanged() 0015 { 0016 fillTimeline(); 0017 } 0018 0019 QString TagsModel::displayName() const 0020 { 0021 return i18n("Trending"); 0022 } 0023 0024 void TagsModel::fetchMore(const QModelIndex &parent) 0025 { 0026 Q_UNUSED(parent); 0027 if (shouldLoadMore()) { 0028 fillTimeline(); 0029 } else { 0030 setShouldLoadMore(true); 0031 } 0032 } 0033 0034 bool TagsModel::canFetchMore(const QModelIndex &parent) const 0035 { 0036 Q_UNUSED(parent); 0037 return !m_next.isEmpty(); 0038 } 0039 0040 void TagsModel::fillTimeline(const QString &fromId) 0041 { 0042 Q_UNUSED(fromId); 0043 0044 if (!account() || loading() || name() != QStringLiteral("trending")) { 0045 return; 0046 } 0047 0048 QUrlQuery q; 0049 q.addQueryItem(QStringLiteral("limit"), QStringLiteral("20")); 0050 QUrl uri; 0051 if (m_next.isEmpty()) { 0052 if (name() == QStringLiteral("trending")) { 0053 uri = account()->apiUrl(QStringLiteral("/api/v1/trends/tags")); 0054 uri.setQuery(q); 0055 } 0056 } else { 0057 uri = m_next; 0058 } 0059 0060 setLoading(true); 0061 account()->get( 0062 uri, 0063 false, 0064 this, 0065 [this, uri](QNetworkReply *reply) { 0066 const auto data = reply->readAll(); 0067 const auto doc = QJsonDocument::fromJson(data); 0068 if (!doc.isArray()) { 0069 return; 0070 } 0071 static QRegularExpression re(QStringLiteral("<(.*)>; rel=\"next\"")); 0072 const auto next = reply->rawHeader(QByteArrayLiteral("Link")); 0073 const auto match = re.match(QString::fromUtf8(next)); 0074 m_next = QUrl::fromUserInput(match.captured(1)); 0075 const auto values = doc.array(); 0076 0077 QList<Tag> tags; 0078 std::transform(values.cbegin(), values.cend(), std::back_inserter(tags), [](const QJsonValue &value) { 0079 return Tag(value.toObject()); 0080 }); 0081 0082 beginInsertRows({}, m_tags.size(), m_tags.size() + tags.size() - 1); 0083 m_tags += tags; 0084 endInsertRows(); 0085 setLoading(false); 0086 }, 0087 [this](QNetworkReply *reply) { 0088 Q_UNUSED(reply); 0089 setLoading(false); 0090 }); 0091 } 0092 0093 QHash<int, QByteArray> TagsModel::roleNames() const 0094 { 0095 return { 0096 {CustomRoles::NameRole, "name"}, 0097 {CustomRoles::UrlRole, "url"}, 0098 {CustomRoles::HistoryRole, "history"}, 0099 }; 0100 } 0101 0102 QVariant TagsModel::data(const QModelIndex &index, int role) const 0103 { 0104 Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)); 0105 0106 switch (role) { 0107 case CustomRoles::NameRole: 0108 return m_tags[index.row()].name(); 0109 case CustomRoles::UrlRole: 0110 return m_tags[index.row()].url(); 0111 case CustomRoles::HistoryRole: 0112 return QVariant::fromValue<QList<History>>(m_tags[index.row()].history()); 0113 default: 0114 return {}; 0115 } 0116 } 0117 0118 int TagsModel::rowCount(const QModelIndex &parent) const 0119 { 0120 Q_UNUSED(parent) 0121 return m_tags.size(); 0122 } 0123 0124 #include "moc_tagsmodel.cpp"