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