File indexing completed on 2024-05-12 16:25:06

0001 // SPDX-FileCopyrightText: 2019-2020 Black Hat <bhat@encom.eu.org>
0002 // SPDX-License-Identifier: GPL-3.0-only
0003 
0004 #include "publicroomlistmodel.h"
0005 
0006 #include <Quotient/connection.h>
0007 
0008 using namespace Quotient;
0009 
0010 PublicRoomListModel::PublicRoomListModel(QObject *parent)
0011     : QAbstractListModel(parent)
0012 {
0013 }
0014 
0015 Quotient::Connection *PublicRoomListModel::connection() const
0016 {
0017     return m_connection;
0018 }
0019 
0020 void PublicRoomListModel::setConnection(Connection *conn)
0021 {
0022     if (m_connection == conn) {
0023         return;
0024     }
0025 
0026     beginResetModel();
0027 
0028     nextBatch = "";
0029     attempted = false;
0030     rooms.clear();
0031     m_server.clear();
0032 
0033     if (m_connection) {
0034         m_connection->disconnect(this);
0035     }
0036 
0037     endResetModel();
0038 
0039     m_connection = conn;
0040 
0041     if (job) {
0042         job->abandon();
0043         job = nullptr;
0044     }
0045 
0046     if (m_connection) {
0047         next();
0048     }
0049 
0050     Q_EMIT connectionChanged();
0051     Q_EMIT serverChanged();
0052     Q_EMIT hasMoreChanged();
0053 }
0054 
0055 QString PublicRoomListModel::server() const
0056 {
0057     return m_server;
0058 }
0059 
0060 void PublicRoomListModel::setServer(const QString &value)
0061 {
0062     if (m_server == value) {
0063         return;
0064     }
0065 
0066     m_server = value;
0067 
0068     beginResetModel();
0069 
0070     nextBatch = "";
0071     attempted = false;
0072     rooms.clear();
0073 
0074     endResetModel();
0075 
0076     if (job) {
0077         job->abandon();
0078         job = nullptr;
0079     }
0080 
0081     if (m_connection) {
0082         next();
0083     }
0084 
0085     Q_EMIT serverChanged();
0086     Q_EMIT hasMoreChanged();
0087 }
0088 
0089 QString PublicRoomListModel::keyword() const
0090 {
0091     return m_keyword;
0092 }
0093 
0094 void PublicRoomListModel::setKeyword(const QString &value)
0095 {
0096     if (m_keyword == value) {
0097         return;
0098     }
0099 
0100     m_keyword = value;
0101 
0102     beginResetModel();
0103 
0104     nextBatch = "";
0105     attempted = false;
0106     rooms.clear();
0107 
0108     endResetModel();
0109 
0110     if (job) {
0111         job->abandon();
0112         job = nullptr;
0113     }
0114 
0115     if (m_connection) {
0116         next();
0117     }
0118 
0119     Q_EMIT keywordChanged();
0120     Q_EMIT hasMoreChanged();
0121 }
0122 
0123 void PublicRoomListModel::next(int count)
0124 {
0125     if (count < 1) {
0126         return;
0127     }
0128 
0129     if (job) {
0130         qDebug() << "PublicRoomListModel: Other jobs running, ignore";
0131 
0132         return;
0133     }
0134 
0135     job = m_connection->callApi<QueryPublicRoomsJob>(m_server, count, nextBatch, QueryPublicRoomsJob::Filter{m_keyword, {}});
0136 
0137     connect(job, &BaseJob::finished, this, [this] {
0138         attempted = true;
0139 
0140         if (job->status() == BaseJob::Success) {
0141             nextBatch = job->nextBatch();
0142 
0143             this->beginInsertRows({}, rooms.count(), rooms.count() + job->chunk().count() - 1);
0144             rooms.append(job->chunk());
0145             this->endInsertRows();
0146 
0147             if (job->nextBatch().isEmpty()) {
0148                 Q_EMIT hasMoreChanged();
0149             }
0150         }
0151 
0152         this->job = nullptr;
0153     });
0154 }
0155 
0156 QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const
0157 {
0158     if (!index.isValid()) {
0159         return QVariant();
0160     }
0161 
0162     if (index.row() >= rooms.count()) {
0163         qDebug() << "PublicRoomListModel, something's wrong: index.row() >= "
0164                     "rooms.count()";
0165         return {};
0166     }
0167     auto room = rooms.at(index.row());
0168     if (role == NameRole) {
0169         auto displayName = room.name;
0170         if (!displayName.isEmpty()) {
0171             return displayName;
0172         }
0173 
0174         displayName = room.canonicalAlias;
0175         if (!displayName.isEmpty()) {
0176             return displayName;
0177         }
0178 
0179         if (!displayName.isEmpty()) {
0180             return displayName;
0181         }
0182 
0183         return room.roomId;
0184     }
0185     if (role == AvatarRole) {
0186         auto avatarUrl = room.avatarUrl;
0187 
0188         if (avatarUrl.isEmpty()) {
0189             return "";
0190         }
0191         return avatarUrl.url().remove(0, 6);
0192     }
0193     if (role == TopicRole) {
0194         return room.topic;
0195     }
0196     if (role == RoomIDRole) {
0197         return room.roomId;
0198     }
0199     if (role == AliasRole) {
0200         if (!room.canonicalAlias.isEmpty()) {
0201             return room.canonicalAlias;
0202         }
0203         return {};
0204     }
0205     if (role == MemberCountRole) {
0206         return room.numJoinedMembers;
0207     }
0208     if (role == AllowGuestsRole) {
0209         return room.guestCanJoin;
0210     }
0211     if (role == WorldReadableRole) {
0212         return room.worldReadable;
0213     }
0214     if (role == IsJoinedRole) {
0215         if (!m_connection) {
0216             return {};
0217         }
0218 
0219         return m_connection->room(room.roomId, JoinState::Join) != nullptr;
0220     }
0221 
0222     return {};
0223 }
0224 
0225 QHash<int, QByteArray> PublicRoomListModel::roleNames() const
0226 {
0227     QHash<int, QByteArray> roles;
0228 
0229     roles[NameRole] = "name";
0230     roles[AvatarRole] = "avatar";
0231     roles[TopicRole] = "topic";
0232     roles[RoomIDRole] = "roomID";
0233     roles[MemberCountRole] = "memberCount";
0234     roles[AllowGuestsRole] = "allowGuests";
0235     roles[WorldReadableRole] = "worldReadable";
0236     roles[IsJoinedRole] = "isJoined";
0237     roles[AliasRole] = "alias";
0238 
0239     return roles;
0240 }
0241 
0242 int PublicRoomListModel::rowCount(const QModelIndex &parent) const
0243 {
0244     if (parent.isValid()) {
0245         return 0;
0246     }
0247 
0248     return rooms.count();
0249 }
0250 
0251 bool PublicRoomListModel::hasMore() const
0252 {
0253     return !(attempted && nextBatch.isEmpty());
0254 }
0255 
0256 #include "moc_publicroomlistmodel.cpp"