File indexing completed on 2024-12-08 07:33:45
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 = QString(); 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 Q_EMIT loadingChanged(); 0045 } 0046 0047 if (m_connection) { 0048 next(); 0049 } 0050 0051 Q_EMIT connectionChanged(); 0052 Q_EMIT serverChanged(); 0053 Q_EMIT hasMoreChanged(); 0054 } 0055 0056 QString PublicRoomListModel::server() const 0057 { 0058 return m_server; 0059 } 0060 0061 void PublicRoomListModel::setServer(const QString &value) 0062 { 0063 if (m_server == value) { 0064 return; 0065 } 0066 0067 m_server = value; 0068 0069 beginResetModel(); 0070 0071 nextBatch = QString(); 0072 attempted = false; 0073 rooms.clear(); 0074 Q_EMIT loadingChanged(); 0075 0076 endResetModel(); 0077 0078 if (job) { 0079 job->abandon(); 0080 job = nullptr; 0081 Q_EMIT loadingChanged(); 0082 } 0083 0084 if (m_connection) { 0085 next(); 0086 } 0087 0088 Q_EMIT serverChanged(); 0089 Q_EMIT hasMoreChanged(); 0090 } 0091 0092 QString PublicRoomListModel::keyword() const 0093 { 0094 return m_keyword; 0095 } 0096 0097 void PublicRoomListModel::setKeyword(const QString &value) 0098 { 0099 if (m_keyword == value) { 0100 return; 0101 } 0102 0103 m_keyword = value; 0104 0105 beginResetModel(); 0106 0107 nextBatch = QString(); 0108 attempted = false; 0109 rooms.clear(); 0110 0111 endResetModel(); 0112 0113 if (job) { 0114 job->abandon(); 0115 job = nullptr; 0116 Q_EMIT loadingChanged(); 0117 } 0118 0119 if (m_connection) { 0120 next(); 0121 } 0122 0123 Q_EMIT keywordChanged(); 0124 Q_EMIT hasMoreChanged(); 0125 } 0126 0127 bool PublicRoomListModel::showOnlySpaces() const 0128 { 0129 return m_showOnlySpaces; 0130 } 0131 0132 void PublicRoomListModel::setShowOnlySpaces(bool showOnlySpaces) 0133 { 0134 if (showOnlySpaces == m_showOnlySpaces) { 0135 return; 0136 } 0137 m_showOnlySpaces = showOnlySpaces; 0138 Q_EMIT showOnlySpacesChanged(); 0139 } 0140 0141 void PublicRoomListModel::next(int count) 0142 { 0143 if (count < 1) { 0144 return; 0145 } 0146 0147 if (job) { 0148 qDebug() << "PublicRoomListModel: Other jobs running, ignore"; 0149 0150 return; 0151 } 0152 0153 QStringList roomTypes; 0154 if (m_showOnlySpaces) { 0155 roomTypes += QLatin1String("m.space"); 0156 } 0157 job = m_connection->callApi<QueryPublicRoomsJob>(m_server, count, nextBatch, QueryPublicRoomsJob::Filter{m_keyword, roomTypes}); 0158 Q_EMIT loadingChanged(); 0159 0160 connect(job, &BaseJob::finished, this, [this] { 0161 attempted = true; 0162 0163 if (job->status() == BaseJob::Success) { 0164 nextBatch = job->nextBatch(); 0165 0166 this->beginInsertRows({}, rooms.count(), rooms.count() + job->chunk().count() - 1); 0167 rooms.append(job->chunk()); 0168 this->endInsertRows(); 0169 0170 if (job->nextBatch().isEmpty()) { 0171 Q_EMIT hasMoreChanged(); 0172 } 0173 } 0174 0175 this->job = nullptr; 0176 Q_EMIT loadingChanged(); 0177 }); 0178 } 0179 0180 QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const 0181 { 0182 if (!index.isValid()) { 0183 return QVariant(); 0184 } 0185 0186 if (index.row() >= rooms.count()) { 0187 qDebug() << "PublicRoomListModel, something's wrong: index.row() >= " 0188 "rooms.count()"; 0189 return {}; 0190 } 0191 auto room = rooms.at(index.row()); 0192 if (role == DisplayNameRole) { 0193 auto displayName = room.name; 0194 if (!displayName.isEmpty()) { 0195 return displayName; 0196 } 0197 0198 displayName = room.canonicalAlias; 0199 if (!displayName.isEmpty()) { 0200 return displayName; 0201 } 0202 0203 if (!displayName.isEmpty()) { 0204 return displayName; 0205 } 0206 0207 return room.roomId; 0208 } 0209 if (role == AvatarUrlRole) { 0210 auto avatarUrl = room.avatarUrl; 0211 if (avatarUrl.isEmpty() || !m_connection) { 0212 return QUrl(); 0213 } 0214 return m_connection->makeMediaUrl(avatarUrl); 0215 } 0216 if (role == TopicRole) { 0217 return room.topic; 0218 } 0219 if (role == RoomIdRole) { 0220 return room.roomId; 0221 } 0222 if (role == AliasRole) { 0223 if (!room.canonicalAlias.isEmpty()) { 0224 return room.canonicalAlias; 0225 } 0226 return {}; 0227 } 0228 if (role == MemberCountRole) { 0229 return room.numJoinedMembers; 0230 } 0231 if (role == AllowGuestsRole) { 0232 return room.guestCanJoin; 0233 } 0234 if (role == WorldReadableRole) { 0235 return room.worldReadable; 0236 } 0237 if (role == IsJoinedRole) { 0238 if (!m_connection) { 0239 return {}; 0240 } 0241 0242 return m_connection->room(room.roomId, JoinState::Join) != nullptr; 0243 } 0244 0245 return {}; 0246 } 0247 0248 QHash<int, QByteArray> PublicRoomListModel::roleNames() const 0249 { 0250 QHash<int, QByteArray> roles; 0251 0252 roles[DisplayNameRole] = "displayName"; 0253 roles[AvatarUrlRole] = "avatarUrl"; 0254 roles[TopicRole] = "topic"; 0255 roles[RoomIdRole] = "roomId"; 0256 roles[MemberCountRole] = "memberCount"; 0257 roles[AllowGuestsRole] = "allowGuests"; 0258 roles[WorldReadableRole] = "worldReadable"; 0259 roles[IsJoinedRole] = "isJoined"; 0260 roles[AliasRole] = "alias"; 0261 0262 return roles; 0263 } 0264 0265 int PublicRoomListModel::rowCount(const QModelIndex &parent) const 0266 { 0267 if (parent.isValid()) { 0268 return 0; 0269 } 0270 0271 return rooms.count(); 0272 } 0273 0274 bool PublicRoomListModel::hasMore() const 0275 { 0276 return !(attempted && nextBatch.isEmpty()); 0277 } 0278 0279 bool PublicRoomListModel::loading() const 0280 { 0281 return job != nullptr; 0282 } 0283 0284 #include "moc_publicroomlistmodel.cpp"