File indexing completed on 2024-06-02 05:00:33

0001 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #include "peertubeinstancesmodel.h"
0005 
0006 #include "plasmatube.h"
0007 
0008 #include <QUrlQuery>
0009 
0010 using namespace Qt::Literals::StringLiterals;
0011 
0012 PeerTubeInstancesModel::PeerTubeInstancesModel(QObject *parent)
0013     : QAbstractListModel(parent)
0014 {
0015     fill();
0016 }
0017 
0018 QVariant PeerTubeInstancesModel::data(const QModelIndex &index, int role) const
0019 {
0020     Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
0021 
0022     const auto &instance = m_instances[index.row()];
0023 
0024     switch (role) {
0025     case URLRole:
0026         return instance.url;
0027     default:
0028         return {};
0029     }
0030 }
0031 
0032 bool PeerTubeInstancesModel::loading() const
0033 {
0034     return m_loading;
0035 }
0036 
0037 void PeerTubeInstancesModel::setLoading(bool loading)
0038 {
0039     if (m_loading == loading) {
0040         return;
0041     }
0042     m_loading = loading;
0043     Q_EMIT loadingChanged();
0044 }
0045 
0046 int PeerTubeInstancesModel::rowCount(const QModelIndex &parent) const
0047 {
0048     return parent.isValid() ? 0 : static_cast<int>(m_instances.size());
0049 }
0050 
0051 QHash<int, QByteArray> PeerTubeInstancesModel::roleNames() const
0052 {
0053     return {{URLRole, "url"}};
0054 }
0055 
0056 void PeerTubeInstancesModel::setFilterString(const QString &filterString)
0057 {
0058     if (filterString != m_filterString) {
0059         m_filterString = filterString;
0060         Q_EMIT filterStringChanged();
0061 
0062         beginResetModel();
0063         m_instances.clear();
0064         endResetModel();
0065 
0066         fill();
0067     }
0068 }
0069 
0070 QString PeerTubeInstancesModel::filterString() const
0071 {
0072     return m_filterString;
0073 }
0074 
0075 void PeerTubeInstancesModel::fill()
0076 {
0077     if (m_loading) {
0078         return;
0079     }
0080     setLoading(true);
0081 
0082     QUrlQuery query;
0083     query.addQueryItem(QStringLiteral("count"), QString::number(10));
0084     if (!m_filterString.isEmpty()) {
0085         query.addQueryItem(QStringLiteral("search"), m_filterString);
0086     }
0087 
0088     QUrl url(QStringLiteral("https://instances.joinpeertube.org/api/v1/instances"));
0089     url.setQuery(query);
0090 
0091     auto reply = m_netManager.get(QNetworkRequest(url));
0092     connect(reply, &QNetworkReply::finished, this, [this, reply] {
0093         const auto doc = QJsonDocument::fromJson(reply->readAll());
0094         auto instances = doc["data"_L1].toArray().toVariantList();
0095 
0096         if (!instances.isEmpty()) {
0097             QList<PeerTubeInstance> fetchedInstances;
0098 
0099             std::transform(instances.cbegin(), instances.cend(), std::back_inserter(fetchedInstances), [=](const QVariant &value) -> auto {
0100                 return fromSourceData(value.toJsonObject());
0101             });
0102             beginInsertRows({}, m_instances.size(), m_instances.size() + fetchedInstances.size() - 1);
0103             m_instances += fetchedInstances;
0104             endInsertRows();
0105         }
0106 
0107         setLoading(false);
0108     });
0109 }
0110 
0111 PeerTubeInstancesModel::PeerTubeInstance PeerTubeInstancesModel::fromSourceData(const QJsonObject &obj) const
0112 {
0113     PeerTubeInstance instance;
0114     instance.url = obj["host"_L1].toString();
0115 
0116     return instance;
0117 }
0118 
0119 #include "moc_peertubeinstancesmodel.cpp"