File indexing completed on 2025-02-23 04:35:15

0001 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #include "invidiousinstancesmodel.h"
0005 
0006 #include "plasmatube.h"
0007 
0008 using namespace Qt::Literals::StringLiterals;
0009 
0010 InvidiousInstancesModel::InvidiousInstancesModel(QObject *parent)
0011     : QAbstractListModel(parent)
0012 {
0013     fill();
0014 }
0015 
0016 QVariant InvidiousInstancesModel::data(const QModelIndex &index, int role) const
0017 {
0018     Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
0019 
0020     const auto &instance = m_instances[index.row()];
0021 
0022     switch (role) {
0023     case URLRole:
0024         return instance.url;
0025     default:
0026         return {};
0027     }
0028 }
0029 
0030 bool InvidiousInstancesModel::loading() const
0031 {
0032     return m_loading;
0033 }
0034 
0035 void InvidiousInstancesModel::setLoading(bool loading)
0036 {
0037     if (m_loading == loading) {
0038         return;
0039     }
0040     m_loading = loading;
0041     Q_EMIT loadingChanged();
0042 }
0043 
0044 int InvidiousInstancesModel::rowCount(const QModelIndex &parent) const
0045 {
0046     return parent.isValid() ? 0 : m_instances.size();
0047 }
0048 
0049 QHash<int, QByteArray> InvidiousInstancesModel::roleNames() const
0050 {
0051     return {{URLRole, "url"}};
0052 }
0053 
0054 void InvidiousInstancesModel::fill()
0055 {
0056     if (m_loading) {
0057         return;
0058     }
0059     setLoading(true);
0060 
0061     auto reply = m_netManager.get(QNetworkRequest(QUrl(QStringLiteral("https://api.invidious.io/instances.json"))));
0062     connect(reply, &QNetworkReply::finished, this, [this, reply] {
0063         const auto doc = QJsonDocument::fromJson(reply->readAll());
0064         auto instances = doc.array().toVariantList();
0065 
0066         if (!instances.isEmpty()) {
0067             QList<InvidiousInstance> fetchedInstances;
0068 
0069             std::transform(instances.cbegin(), instances.cend(), std::back_inserter(fetchedInstances), [=](const QVariant &value) -> auto {
0070                 return fromSourceData(value.toJsonArray());
0071             });
0072             beginInsertRows({}, m_instances.size(), m_instances.size() + fetchedInstances.size() - 1);
0073             m_instances += fetchedInstances;
0074             endInsertRows();
0075         }
0076 
0077         setLoading(false);
0078     });
0079 }
0080 
0081 InvidiousInstancesModel::InvidiousInstance InvidiousInstancesModel::fromSourceData(const QJsonArray &array) const
0082 {
0083     InvidiousInstance instance;
0084     instance.url = array[0].toString();
0085 
0086     return instance;
0087 }
0088 
0089 #include "moc_invidiousinstancesmodel.cpp"