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

0001 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #include "commentsmodel.h"
0005 
0006 #include "plasmatube.h"
0007 
0008 using namespace Qt::Literals::StringLiterals;
0009 
0010 CommentsModel::CommentsModel(QObject *parent)
0011     : QAbstractListModel(parent)
0012 {
0013 }
0014 
0015 QVariant CommentsModel::data(const QModelIndex &index, int role) const
0016 {
0017     Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
0018 
0019     const auto &comment = m_comments[index.row()];
0020 
0021     switch (role) {
0022     case AuthorRole:
0023         return comment.author();
0024     case AuthorAvatarRole:
0025         return comment.authorAvatar();
0026     case ContentRole:
0027         return comment.content();
0028     default:
0029         return {};
0030     }
0031 }
0032 
0033 bool CommentsModel::loading() const
0034 {
0035     return m_loading;
0036 }
0037 
0038 void CommentsModel::setLoading(bool loading)
0039 {
0040     if (m_loading == loading) {
0041         return;
0042     }
0043     m_loading = loading;
0044     Q_EMIT loadingChanged();
0045 }
0046 
0047 int CommentsModel::rowCount(const QModelIndex &parent) const
0048 {
0049     return parent.isValid() ? 0 : static_cast<int>(m_comments.size());
0050 }
0051 
0052 QHash<int, QByteArray> CommentsModel::roleNames() const
0053 {
0054     return {
0055         {AuthorRole, "author"},
0056         {AuthorAvatarRole, "authorAvatar"},
0057         {ContentRole, "content"},
0058     };
0059 }
0060 
0061 void CommentsModel::fillComments(const QString &videoId)
0062 {
0063     if (!m_comments.isEmpty()) {
0064         beginResetModel();
0065         m_comments.clear();
0066         endResetModel();
0067     }
0068 
0069     m_continuation.clear();
0070     m_videoId = videoId;
0071     fill();
0072 }
0073 
0074 void CommentsModel::loadMore()
0075 {
0076     if (!m_continuation.isEmpty()) {
0077         fill();
0078     }
0079 }
0080 
0081 void CommentsModel::fill()
0082 {
0083     if (m_loading) {
0084         return;
0085     }
0086 
0087     setLoading(true);
0088 
0089     auto future = PlasmaTube::instance().sourceManager()->selectedSource()->api()->requestComments(m_videoId, m_continuation);
0090 
0091     m_futureWatcher = new QFutureWatcher<QInvidious::CommentsResult>();
0092     m_futureWatcher->setFuture(future);
0093 
0094     connect(m_futureWatcher, &QFutureWatcherBase::finished, this, [this] {
0095         if (m_futureWatcher->future().resultCount() != 0) {
0096             auto result = m_futureWatcher->result();
0097             if (auto comments = std::get_if<QInvidious::Comments>(&result)) {
0098                 const auto rows = rowCount({});
0099                 beginInsertRows({}, rows, rows + static_cast<int>(comments->comments.size()) - 1);
0100                 m_comments << (*comments).comments;
0101                 endInsertRows();
0102 
0103                 m_continuation = comments->continuation;
0104             } else if (auto error = std::get_if<QInvidious::Error>(&result)) {
0105                 // TODO: Log error
0106             }
0107         }
0108 
0109         m_futureWatcher->deleteLater();
0110         m_futureWatcher = nullptr;
0111         setLoading(false);
0112     });
0113 }
0114 
0115 #include "moc_commentsmodel.cpp"