diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index 2d1dd49d..2d60dcb3 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -17,978 +17,947 @@ RoomlistModel::RoomlistModel(TimelineViewManager *parent)
: QAbstractListModel(parent)
, manager(parent)
{
- [[maybe_unused]] static auto id = qRegisterMetaType<RoomPreview>();
-
- connect(ChatPage::instance(), &ChatPage::decryptSidebarChanged, this, [this]() {
- auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar();
- QHash<QString, QSharedPointer<TimelineModel>>::iterator i;
- for (i = models.begin(); i != models.end(); ++i) {
- auto ptr = i.value();
-
- if (!ptr.isNull()) {
- ptr->setDecryptDescription(decrypt);
- ptr->updateLastMessage();
- }
- }
- });
-
- connect(this,
- &RoomlistModel::totalUnreadMessageCountUpdated,
- ChatPage::instance(),
- &ChatPage::unreadMessages);
-
- connect(
- this,
- &RoomlistModel::fetchedPreview,
- this,
- [this](QString roomid, RoomInfo info) {
- if (this->previewedRooms.contains(roomid)) {
- this->previewedRooms.insert(roomid, std::move(info));
- auto idx = this->roomidToIndex(roomid);
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::RoomName,
- Roles::AvatarUrl,
- Roles::IsSpace,
- Roles::IsPreviewFetched,
- Qt::DisplayRole,
- });
- }
- },
- Qt::QueuedConnection);
+ [[maybe_unused]] static auto id = qRegisterMetaType<RoomPreview>();
+
+ connect(ChatPage::instance(), &ChatPage::decryptSidebarChanged, this, [this]() {
+ auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar();
+ QHash<QString, QSharedPointer<TimelineModel>>::iterator i;
+ for (i = models.begin(); i != models.end(); ++i) {
+ auto ptr = i.value();
+
+ if (!ptr.isNull()) {
+ ptr->setDecryptDescription(decrypt);
+ ptr->updateLastMessage();
+ }
+ }
+ });
+
+ connect(this,
+ &RoomlistModel::totalUnreadMessageCountUpdated,
+ ChatPage::instance(),
+ &ChatPage::unreadMessages);
+
+ connect(
+ this,
+ &RoomlistModel::fetchedPreview,
+ this,
+ [this](QString roomid, RoomInfo info) {
+ if (this->previewedRooms.contains(roomid)) {
+ this->previewedRooms.insert(roomid, std::move(info));
+ auto idx = this->roomidToIndex(roomid);
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::RoomName,
+ Roles::AvatarUrl,
+ Roles::IsSpace,
+ Roles::IsPreviewFetched,
+ Qt::DisplayRole,
+ });
+ }
+ },
+ Qt::QueuedConnection);
}
QHash<int, QByteArray>
RoomlistModel::roleNames() const
{
- return {
- {AvatarUrl, "avatarUrl"},
- {RoomName, "roomName"},
- {RoomId, "roomId"},
- {LastMessage, "lastMessage"},
- {Time, "time"},
- {Timestamp, "timestamp"},
- {HasUnreadMessages, "hasUnreadMessages"},
- {HasLoudNotification, "hasLoudNotification"},
- {NotificationCount, "notificationCount"},
- {IsInvite, "isInvite"},
- {IsSpace, "isSpace"},
- {Tags, "tags"},
- {ParentSpaces, "parentSpaces"},
- {IsDirect, "isDirect"},
- {DirectChatOtherUserId, "directChatOtherUserId"},
- };
+ return {
+ {AvatarUrl, "avatarUrl"},
+ {RoomName, "roomName"},
+ {RoomId, "roomId"},
+ {LastMessage, "lastMessage"},
+ {Time, "time"},
+ {Timestamp, "timestamp"},
+ {HasUnreadMessages, "hasUnreadMessages"},
+ {HasLoudNotification, "hasLoudNotification"},
+ {NotificationCount, "notificationCount"},
+ {IsInvite, "isInvite"},
+ {IsSpace, "isSpace"},
+ {Tags, "tags"},
+ {ParentSpaces, "parentSpaces"},
+ {IsDirect, "isDirect"},
+ {DirectChatOtherUserId, "directChatOtherUserId"},
+ };
}
QVariant
RoomlistModel::data(const QModelIndex &index, int role) const
{
- if (index.row() >= 0 && static_cast<size_t>(index.row()) < roomids.size()) {
- auto roomid = roomids.at(index.row());
-
- if (role == Roles::ParentSpaces) {
- auto parents = cache::client()->getParentRoomIds(roomid.toStdString());
- QStringList list;
- for (const auto &t : parents)
- list.push_back(QString::fromStdString(t));
- return list;
- } else if (role == Roles::RoomId) {
- return roomid;
- }
+ if (index.row() >= 0 && static_cast<size_t>(index.row()) < roomids.size()) {
+ auto roomid = roomids.at(index.row());
+
+ if (role == Roles::ParentSpaces) {
+ auto parents = cache::client()->getParentRoomIds(roomid.toStdString());
+ QStringList list;
+ for (const auto &t : parents)
+ list.push_back(QString::fromStdString(t));
+ return list;
+ } else if (role == Roles::RoomId) {
+ return roomid;
+ }
- if (models.contains(roomid)) {
- auto room = models.value(roomid);
- switch (role) {
- case Roles::AvatarUrl:
- return room->roomAvatarUrl();
- case Roles::RoomName:
- return room->plainRoomName();
- case Roles::LastMessage:
- return room->lastMessage().body;
- case Roles::Time:
- return room->lastMessage().descriptiveTime;
- case Roles::Timestamp:
- return QVariant(
- static_cast<quint64>(room->lastMessage().timestamp));
- case Roles::HasUnreadMessages:
- return this->roomReadStatus.count(roomid) &&
- this->roomReadStatus.at(roomid);
- case Roles::HasLoudNotification:
- return room->hasMentions();
- case Roles::NotificationCount:
- return room->notificationCount();
- case Roles::IsInvite:
- return false;
- case Roles::IsSpace:
- return room->isSpace();
- case Roles::IsPreview:
- return false;
- case Roles::Tags: {
- auto info = cache::singleRoomInfo(roomid.toStdString());
- QStringList list;
- for (const auto &t : info.tags)
- list.push_back(QString::fromStdString(t));
- return list;
- }
- case Roles::IsDirect:
- return room->isDirect();
- case Roles::DirectChatOtherUserId:
- return room->directChatOtherUserId();
- default:
- return {};
- }
- } else if (invites.contains(roomid)) {
- auto room = invites.value(roomid);
- switch (role) {
- case Roles::AvatarUrl:
- return QString::fromStdString(room.avatar_url);
- case Roles::RoomName:
- return QString::fromStdString(room.name);
- case Roles::LastMessage:
- return tr("Pending invite.");
- case Roles::Time:
- return QString();
- case Roles::Timestamp:
- return QVariant(static_cast<quint64>(0));
- case Roles::HasUnreadMessages:
- case Roles::HasLoudNotification:
- return false;
- case Roles::NotificationCount:
- return 0;
- case Roles::IsInvite:
- return true;
- case Roles::IsSpace:
- return false;
- case Roles::IsPreview:
- return false;
- case Roles::Tags:
- return QStringList();
- case Roles::IsDirect:
- // The list of users from the room doesn't contain the invited
- // users, so we won't factor the invite into the count
- return room.member_count == 1;
- case Roles::DirectChatOtherUserId:
- return cache::getMembersFromInvite(roomid.toStdString(), 0, 1)
- .front()
- .user_id;
- default:
- return {};
- }
- } else if (previewedRooms.contains(roomid) &&
- previewedRooms.value(roomid).has_value()) {
- auto room = previewedRooms.value(roomid).value();
- switch (role) {
- case Roles::AvatarUrl:
- return QString::fromStdString(room.avatar_url);
- case Roles::RoomName:
- return QString::fromStdString(room.name);
- case Roles::LastMessage:
- return tr("Previewing this room");
- case Roles::Time:
- return QString();
- case Roles::Timestamp:
- return QVariant(static_cast<quint64>(0));
- case Roles::HasUnreadMessages:
- case Roles::HasLoudNotification:
- return false;
- case Roles::NotificationCount:
- return 0;
- case Roles::IsInvite:
- return false;
- case Roles::IsSpace:
- return room.is_space;
- case Roles::IsPreview:
- return true;
- case Roles::IsPreviewFetched:
- return true;
- case Roles::Tags:
- return QStringList();
- case Roles::IsDirect:
- return false;
- case Roles::DirectChatOtherUserId:
- return QString{}; // should never be reached
- default:
- return {};
- }
- } else {
- if (role == Roles::IsPreview)
- return true;
- else if (role == Roles::IsPreviewFetched)
- return false;
-
- fetchPreview(roomid);
- switch (role) {
- case Roles::AvatarUrl:
- return QString();
- case Roles::RoomName:
- return tr("No preview available");
- case Roles::LastMessage:
- return QString();
- case Roles::Time:
- return QString();
- case Roles::Timestamp:
- return QVariant(static_cast<quint64>(0));
- case Roles::HasUnreadMessages:
- case Roles::HasLoudNotification:
- return false;
- case Roles::NotificationCount:
- return 0;
- case Roles::IsInvite:
- return false;
- case Roles::IsSpace:
- return false;
- case Roles::Tags:
- return QStringList();
- default:
- return {};
- }
- }
+ if (models.contains(roomid)) {
+ auto room = models.value(roomid);
+ switch (role) {
+ case Roles::AvatarUrl:
+ return room->roomAvatarUrl();
+ case Roles::RoomName:
+ return room->plainRoomName();
+ case Roles::LastMessage:
+ return room->lastMessage().body;
+ case Roles::Time:
+ return room->lastMessage().descriptiveTime;
+ case Roles::Timestamp:
+ return QVariant(static_cast<quint64>(room->lastMessage().timestamp));
+ case Roles::HasUnreadMessages:
+ return this->roomReadStatus.count(roomid) && this->roomReadStatus.at(roomid);
+ case Roles::HasLoudNotification:
+ return room->hasMentions();
+ case Roles::NotificationCount:
+ return room->notificationCount();
+ case Roles::IsInvite:
+ return false;
+ case Roles::IsSpace:
+ return room->isSpace();
+ case Roles::IsPreview:
+ return false;
+ case Roles::Tags: {
+ auto info = cache::singleRoomInfo(roomid.toStdString());
+ QStringList list;
+ for (const auto &t : info.tags)
+ list.push_back(QString::fromStdString(t));
+ return list;
+ }
+ case Roles::IsDirect:
+ return room->isDirect();
+ case Roles::DirectChatOtherUserId:
+ return room->directChatOtherUserId();
+ default:
+ return {};
+ }
+ } else if (invites.contains(roomid)) {
+ auto room = invites.value(roomid);
+ switch (role) {
+ case Roles::AvatarUrl:
+ return QString::fromStdString(room.avatar_url);
+ case Roles::RoomName:
+ return QString::fromStdString(room.name);
+ case Roles::LastMessage:
+ return tr("Pending invite.");
+ case Roles::Time:
+ return QString();
+ case Roles::Timestamp:
+ return QVariant(static_cast<quint64>(0));
+ case Roles::HasUnreadMessages:
+ case Roles::HasLoudNotification:
+ return false;
+ case Roles::NotificationCount:
+ return 0;
+ case Roles::IsInvite:
+ return true;
+ case Roles::IsSpace:
+ return false;
+ case Roles::IsPreview:
+ return false;
+ case Roles::Tags:
+ return QStringList();
+ case Roles::IsDirect:
+ // The list of users from the room doesn't contain the invited
+ // users, so we won't factor the invite into the count
+ return room.member_count == 1;
+ case Roles::DirectChatOtherUserId:
+ return cache::getMembersFromInvite(roomid.toStdString(), 0, 1).front().user_id;
+ default:
+ return {};
+ }
+ } else if (previewedRooms.contains(roomid) && previewedRooms.value(roomid).has_value()) {
+ auto room = previewedRooms.value(roomid).value();
+ switch (role) {
+ case Roles::AvatarUrl:
+ return QString::fromStdString(room.avatar_url);
+ case Roles::RoomName:
+ return QString::fromStdString(room.name);
+ case Roles::LastMessage:
+ return tr("Previewing this room");
+ case Roles::Time:
+ return QString();
+ case Roles::Timestamp:
+ return QVariant(static_cast<quint64>(0));
+ case Roles::HasUnreadMessages:
+ case Roles::HasLoudNotification:
+ return false;
+ case Roles::NotificationCount:
+ return 0;
+ case Roles::IsInvite:
+ return false;
+ case Roles::IsSpace:
+ return room.is_space;
+ case Roles::IsPreview:
+ return true;
+ case Roles::IsPreviewFetched:
+ return true;
+ case Roles::Tags:
+ return QStringList();
+ case Roles::IsDirect:
+ return false;
+ case Roles::DirectChatOtherUserId:
+ return QString{}; // should never be reached
+ default:
+ return {};
+ }
} else {
+ if (role == Roles::IsPreview)
+ return true;
+ else if (role == Roles::IsPreviewFetched)
+ return false;
+
+ fetchPreview(roomid);
+ switch (role) {
+ case Roles::AvatarUrl:
+ return QString();
+ case Roles::RoomName:
+ return tr("No preview available");
+ case Roles::LastMessage:
+ return QString();
+ case Roles::Time:
+ return QString();
+ case Roles::Timestamp:
+ return QVariant(static_cast<quint64>(0));
+ case Roles::HasUnreadMessages:
+ case Roles::HasLoudNotification:
+ return false;
+ case Roles::NotificationCount:
+ return 0;
+ case Roles::IsInvite:
+ return false;
+ case Roles::IsSpace:
+ return false;
+ case Roles::Tags:
+ return QStringList();
+ default:
return {};
+ }
}
+ } else {
+ return {};
+ }
}
void
RoomlistModel::updateReadStatus(const std::map<QString, bool> roomReadStatus_)
{
- std::vector<int> roomsToUpdate;
- roomsToUpdate.resize(roomReadStatus_.size());
- for (const auto &[roomid, roomUnread] : roomReadStatus_) {
- if (roomUnread != roomReadStatus[roomid]) {
- roomsToUpdate.push_back(this->roomidToIndex(roomid));
- }
-
- this->roomReadStatus[roomid] = roomUnread;
+ std::vector<int> roomsToUpdate;
+ roomsToUpdate.resize(roomReadStatus_.size());
+ for (const auto &[roomid, roomUnread] : roomReadStatus_) {
+ if (roomUnread != roomReadStatus[roomid]) {
+ roomsToUpdate.push_back(this->roomidToIndex(roomid));
}
- for (auto idx : roomsToUpdate) {
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::HasUnreadMessages,
- });
- }
+ this->roomReadStatus[roomid] = roomUnread;
+ }
+
+ for (auto idx : roomsToUpdate) {
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::HasUnreadMessages,
+ });
+ }
}
void
RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification)
{
- if (!models.contains(room_id)) {
- // ensure we get read status updates and are only connected once
- connect(cache::client(),
- &Cache::roomReadStatus,
- this,
- &RoomlistModel::updateReadStatus,
- Qt::UniqueConnection);
-
- QSharedPointer<TimelineModel> newRoom(new TimelineModel(manager, room_id));
- newRoom->setDecryptDescription(
- ChatPage::instance()->userSettings()->decryptSidebar());
-
- connect(newRoom.data(),
- &TimelineModel::newEncryptedImage,
- manager->imageProvider(),
- &MxcImageProvider::addEncryptionInfo);
- connect(newRoom.data(),
- &TimelineModel::forwardToRoom,
- manager,
- &TimelineViewManager::forwardMessageToRoom);
- connect(
- newRoom.data(), &TimelineModel::lastMessageChanged, this, [room_id, this]() {
- auto idx = this->roomidToIndex(room_id);
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::HasLoudNotification,
- Roles::LastMessage,
- Roles::Timestamp,
- Roles::NotificationCount,
- Qt::DisplayRole,
- });
- });
- connect(
- newRoom.data(), &TimelineModel::roomAvatarUrlChanged, this, [room_id, this]() {
- auto idx = this->roomidToIndex(room_id);
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::AvatarUrl,
- });
- });
- connect(newRoom.data(), &TimelineModel::roomNameChanged, this, [room_id, this]() {
- auto idx = this->roomidToIndex(room_id);
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::RoomName,
- });
- });
- connect(
- newRoom.data(), &TimelineModel::notificationsChanged, this, [room_id, this]() {
- auto idx = this->roomidToIndex(room_id);
- emit dataChanged(index(idx),
- index(idx),
- {
- Roles::HasLoudNotification,
- Roles::NotificationCount,
- Qt::DisplayRole,
- });
-
- int total_unread_msgs = 0;
-
- for (const auto &room : models) {
- if (!room.isNull())
- total_unread_msgs += room->notificationCount();
- }
-
- emit totalUnreadMessageCountUpdated(total_unread_msgs);
- });
-
- newRoom->updateLastMessage();
-
- std::vector<QString> previewsToAdd;
- if (newRoom->isSpace()) {
- auto childs = cache::client()->getChildRoomIds(room_id.toStdString());
- for (const auto &c : childs) {
- auto id = QString::fromStdString(c);
- if (!(models.contains(id) || invites.contains(id) ||
- previewedRooms.contains(id))) {
- previewsToAdd.push_back(std::move(id));
- }
- }
- }
+ if (!models.contains(room_id)) {
+ // ensure we get read status updates and are only connected once
+ connect(cache::client(),
+ &Cache::roomReadStatus,
+ this,
+ &RoomlistModel::updateReadStatus,
+ Qt::UniqueConnection);
+
+ QSharedPointer<TimelineModel> newRoom(new TimelineModel(manager, room_id));
+ newRoom->setDecryptDescription(ChatPage::instance()->userSettings()->decryptSidebar());
+
+ connect(newRoom.data(),
+ &TimelineModel::newEncryptedImage,
+ manager->imageProvider(),
+ &MxcImageProvider::addEncryptionInfo);
+ connect(newRoom.data(),
+ &TimelineModel::forwardToRoom,
+ manager,
+ &TimelineViewManager::forwardMessageToRoom);
+ connect(newRoom.data(), &TimelineModel::lastMessageChanged, this, [room_id, this]() {
+ auto idx = this->roomidToIndex(room_id);
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::HasLoudNotification,
+ Roles::LastMessage,
+ Roles::Timestamp,
+ Roles::NotificationCount,
+ Qt::DisplayRole,
+ });
+ });
+ connect(newRoom.data(), &TimelineModel::roomAvatarUrlChanged, this, [room_id, this]() {
+ auto idx = this->roomidToIndex(room_id);
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::AvatarUrl,
+ });
+ });
+ connect(newRoom.data(), &TimelineModel::roomNameChanged, this, [room_id, this]() {
+ auto idx = this->roomidToIndex(room_id);
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::RoomName,
+ });
+ });
+ connect(newRoom.data(), &TimelineModel::notificationsChanged, this, [room_id, this]() {
+ auto idx = this->roomidToIndex(room_id);
+ emit dataChanged(index(idx),
+ index(idx),
+ {
+ Roles::HasLoudNotification,
+ Roles::NotificationCount,
+ Qt::DisplayRole,
+ });
+
+ int total_unread_msgs = 0;
+
+ for (const auto &room : models) {
+ if (!room.isNull())
+ total_unread_msgs += room->notificationCount();
+ }
+
+ emit totalUnreadMessageCountUpdated(total_unread_msgs);
+ });
- bool wasInvite = invites.contains(room_id);
- bool wasPreview = previewedRooms.contains(room_id);
- if (!suppressInsertNotification &&
- ((!wasInvite && !wasPreview) || !previewedRooms.empty()))
- // if the old room was already in the list, don't add it. Also add all
- // previews at the same time.
- beginInsertRows(QModelIndex(),
- (int)roomids.size(),
- (int)(roomids.size() + previewsToAdd.size() -
- ((wasInvite || wasPreview) ? 1 : 0)));
-
- models.insert(room_id, std::move(newRoom));
- if (wasInvite) {
- auto idx = roomidToIndex(room_id);
- invites.remove(room_id);
- emit dataChanged(index(idx), index(idx));
- } else if (wasPreview) {
- auto idx = roomidToIndex(room_id);
- previewedRooms.remove(room_id);
- emit dataChanged(index(idx), index(idx));
- } else {
- roomids.push_back(room_id);
- }
+ newRoom->updateLastMessage();
- if ((wasInvite || wasPreview) && currentRoomPreview_ &&
- currentRoomPreview_->roomid() == room_id) {
- currentRoom_ = models.value(room_id);
- currentRoomPreview_.reset();
- emit currentRoomChanged();
+ std::vector<QString> previewsToAdd;
+ if (newRoom->isSpace()) {
+ auto childs = cache::client()->getChildRoomIds(room_id.toStdString());
+ for (const auto &c : childs) {
+ auto id = QString::fromStdString(c);
+ if (!(models.contains(id) || invites.contains(id) || previewedRooms.contains(id))) {
+ previewsToAdd.push_back(std::move(id));
}
+ }
+ }
- for (auto p : previewsToAdd) {
- previewedRooms.insert(p, std::nullopt);
- roomids.push_back(std::move(p));
- }
+ bool wasInvite = invites.contains(room_id);
+ bool wasPreview = previewedRooms.contains(room_id);
+ if (!suppressInsertNotification && ((!wasInvite && !wasPreview) || !previewedRooms.empty()))
+ // if the old room was already in the list, don't add it. Also add all
+ // previews at the same time.
+ beginInsertRows(
+ QModelIndex(),
+ (int)roomids.size(),
+ (int)(roomids.size() + previewsToAdd.size() - ((wasInvite || wasPreview) ? 1 : 0)));
+
+ models.insert(room_id, std::move(newRoom));
+ if (wasInvite) {
+ auto idx = roomidToIndex(room_id);
+ invites.remove(room_id);
+ emit dataChanged(index(idx), index(idx));
+ } else if (wasPreview) {
+ auto idx = roomidToIndex(room_id);
+ previewedRooms.remove(room_id);
+ emit dataChanged(index(idx), index(idx));
+ } else {
+ roomids.push_back(room_id);
+ }
- if (!suppressInsertNotification &&
- ((!wasInvite && !wasPreview) || !previewedRooms.empty()))
- endInsertRows();
+ if ((wasInvite || wasPreview) && currentRoomPreview_ &&
+ currentRoomPreview_->roomid() == room_id) {
+ currentRoom_ = models.value(room_id);
+ currentRoomPreview_.reset();
+ emit currentRoomChanged();
+ }
- emit ChatPage::instance()->newRoom(room_id);
+ for (auto p : previewsToAdd) {
+ previewedRooms.insert(p, std::nullopt);
+ roomids.push_back(std::move(p));
}
+
+ if (!suppressInsertNotification && ((!wasInvite && !wasPreview) || !previewedRooms.empty()))
+ endInsertRows();
+
+ emit ChatPage::instance()->newRoom(room_id);
+ }
}
void
RoomlistModel::fetchPreview(QString roomid_) const
{
- std::string roomid = roomid_.toStdString();
- http::client()->get_state_event<mtx::events::state::Create>(
- roomid,
- "",
- [this, roomid](const mtx::events::state::Create &c, mtx::http::RequestErr err) {
- bool is_space = false;
- if (!err) {
- is_space = c.type == mtx::events::state::room_type::space;
- }
-
- http::client()->get_state_event<mtx::events::state::Avatar>(
- roomid,
- "",
- [this, roomid, is_space](const mtx::events::state::Avatar &a,
- mtx::http::RequestErr) {
- auto avatar_url = a.url;
-
- http::client()->get_state_event<mtx::events::state::Topic>(
- roomid,
- "",
- [this, roomid, avatar_url, is_space](
- const mtx::events::state::Topic &t, mtx::http::RequestErr) {
- auto topic = t.topic;
- http::client()->get_state_event<mtx::events::state::Name>(
- roomid,
- "",
- [this, roomid, topic, avatar_url, is_space](
- const mtx::events::state::Name &n,
- mtx::http::RequestErr err) {
- if (err) {
- nhlog::net()->warn(
- "Failed to fetch name event to "
- "create preview for {}",
- roomid);
- }
-
- // don't even add a preview, if we got not a single
- // response
- if (n.name.empty() && avatar_url.empty() &&
- topic.empty())
- return;
-
- RoomInfo info{};
- info.name = n.name;
- info.is_space = is_space;
- info.avatar_url = avatar_url;
- info.topic = topic;
-
- const_cast<RoomlistModel *>(this)->fetchedPreview(
- QString::fromStdString(roomid), info);
- });
- });
- });
- });
+ std::string roomid = roomid_.toStdString();
+ http::client()->get_state_event<mtx::events::state::Create>(
+ roomid, "", [this, roomid](const mtx::events::state::Create &c, mtx::http::RequestErr err) {
+ bool is_space = false;
+ if (!err) {
+ is_space = c.type == mtx::events::state::room_type::space;
+ }
+
+ http::client()->get_state_event<mtx::events::state::Avatar>(
+ roomid,
+ "",
+ [this, roomid, is_space](const mtx::events::state::Avatar &a, mtx::http::RequestErr) {
+ auto avatar_url = a.url;
+
+ http::client()->get_state_event<mtx::events::state::Topic>(
+ roomid,
+ "",
+ [this, roomid, avatar_url, is_space](const mtx::events::state::Topic &t,
+ mtx::http::RequestErr) {
+ auto topic = t.topic;
+ http::client()->get_state_event<mtx::events::state::Name>(
+ roomid,
+ "",
+ [this, roomid, topic, avatar_url, is_space](
+ const mtx::events::state::Name &n, mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::net()->warn("Failed to fetch name event to "
+ "create preview for {}",
+ roomid);
+ }
+
+ // don't even add a preview, if we got not a single
+ // response
+ if (n.name.empty() && avatar_url.empty() && topic.empty())
+ return;
+
+ RoomInfo info{};
+ info.name = n.name;
+ info.is_space = is_space;
+ info.avatar_url = avatar_url;
+ info.topic = topic;
+
+ const_cast<RoomlistModel *>(this)->fetchedPreview(
+ QString::fromStdString(roomid), info);
+ });
+ });
+ });
+ });
}
void
RoomlistModel::sync(const mtx::responses::Rooms &rooms)
{
- for (const auto &[room_id, room] : rooms.join) {
- auto qroomid = QString::fromStdString(room_id);
-
- // addRoom will only add the room, if it doesn't exist
- addRoom(qroomid);
- const auto &room_model = models.value(qroomid);
- room_model->sync(room);
- // room_model->addEvents(room.timeline);
- connect(room_model.data(),
- &TimelineModel::newCallEvent,
- manager->callManager(),
- &CallManager::syncEvent,
- Qt::UniqueConnection);
-
- if (ChatPage::instance()->userSettings()->typingNotifications()) {
- for (const auto &ev : room.ephemeral.events) {
- if (auto t = std::get_if<
- mtx::events::EphemeralEvent<mtx::events::ephemeral::Typing>>(
- &ev)) {
- std::vector<QString> typing;
- typing.reserve(t->content.user_ids.size());
- for (const auto &user : t->content.user_ids) {
- if (user != http::client()->user_id().to_string())
- typing.push_back(
- QString::fromStdString(user));
- }
- room_model->updateTypingUsers(typing);
- }
- }
+ for (const auto &[room_id, room] : rooms.join) {
+ auto qroomid = QString::fromStdString(room_id);
+
+ // addRoom will only add the room, if it doesn't exist
+ addRoom(qroomid);
+ const auto &room_model = models.value(qroomid);
+ room_model->sync(room);
+ // room_model->addEvents(room.timeline);
+ connect(room_model.data(),
+ &TimelineModel::newCallEvent,
+ manager->callManager(),
+ &CallManager::syncEvent,
+ Qt::UniqueConnection);
+
+ if (ChatPage::instance()->userSettings()->typingNotifications()) {
+ for (const auto &ev : room.ephemeral.events) {
+ if (auto t =
+ std::get_if<mtx::events::EphemeralEvent<mtx::events::ephemeral::Typing>>(
+ &ev)) {
+ std::vector<QString> typing;
+ typing.reserve(t->content.user_ids.size());
+ for (const auto &user : t->content.user_ids) {
+ if (user != http::client()->user_id().to_string())
+ typing.push_back(QString::fromStdString(user));
+ }
+ room_model->updateTypingUsers(typing);
}
+ }
}
-
- for (const auto &[room_id, room] : rooms.leave) {
- (void)room;
- auto qroomid = QString::fromStdString(room_id);
-
- if ((currentRoom_ && currentRoom_->roomId() == qroomid) ||
- (currentRoomPreview_ && currentRoomPreview_->roomid() == qroomid))
- resetCurrentRoom();
-
- auto idx = this->roomidToIndex(qroomid);
- if (idx != -1) {
- beginRemoveRows(QModelIndex(), idx, idx);
- roomids.erase(roomids.begin() + idx);
- if (models.contains(qroomid))
- models.remove(qroomid);
- else if (invites.contains(qroomid))
- invites.remove(qroomid);
- endRemoveRows();
- }
+ }
+
+ for (const auto &[room_id, room] : rooms.leave) {
+ (void)room;
+ auto qroomid = QString::fromStdString(room_id);
+
+ if ((currentRoom_ && currentRoom_->roomId() == qroomid) ||
+ (currentRoomPreview_ && currentRoomPreview_->roomid() == qroomid))
+ resetCurrentRoom();
+
+ auto idx = this->roomidToIndex(qroomid);
+ if (idx != -1) {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ roomids.erase(roomids.begin() + idx);
+ if (models.contains(qroomid))
+ models.remove(qroomid);
+ else if (invites.contains(qroomid))
+ invites.remove(qroomid);
+ endRemoveRows();
}
+ }
- for (const auto &[room_id, room] : rooms.invite) {
- (void)room;
- auto qroomid = QString::fromStdString(room_id);
-
- auto invite = cache::client()->invite(room_id);
- if (!invite)
- continue;
-
- if (invites.contains(qroomid)) {
- invites[qroomid] = *invite;
- auto idx = roomidToIndex(qroomid);
- emit dataChanged(index(idx), index(idx));
- } else {
- beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size());
- invites.insert(qroomid, *invite);
- roomids.push_back(std::move(qroomid));
- endInsertRows();
- }
+ for (const auto &[room_id, room] : rooms.invite) {
+ (void)room;
+ auto qroomid = QString::fromStdString(room_id);
+
+ auto invite = cache::client()->invite(room_id);
+ if (!invite)
+ continue;
+
+ if (invites.contains(qroomid)) {
+ invites[qroomid] = *invite;
+ auto idx = roomidToIndex(qroomid);
+ emit dataChanged(index(idx), index(idx));
+ } else {
+ beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size());
+ invites.insert(qroomid, *invite);
+ roomids.push_back(std::move(qroomid));
+ endInsertRows();
}
+ }
}
void
RoomlistModel::initializeRooms()
{
- beginResetModel();
- models.clear();
- roomids.clear();
- invites.clear();
- currentRoom_ = nullptr;
+ beginResetModel();
+ models.clear();
+ roomids.clear();
+ invites.clear();
+ currentRoom_ = nullptr;
- invites = cache::client()->invites();
- for (const auto &id : invites.keys())
- roomids.push_back(id);
+ invites = cache::client()->invites();
+ for (const auto &id : invites.keys())
+ roomids.push_back(id);
- for (const auto &id : cache::client()->roomIds())
- addRoom(id, true);
+ for (const auto &id : cache::client()->roomIds())
+ addRoom(id, true);
- nhlog::db()->info("Restored {} rooms from cache", rowCount());
+ nhlog::db()->info("Restored {} rooms from cache", rowCount());
- endResetModel();
+ endResetModel();
}
void
RoomlistModel::clear()
{
- beginResetModel();
- models.clear();
- invites.clear();
- roomids.clear();
- currentRoom_ = nullptr;
- emit currentRoomChanged();
- endResetModel();
+ beginResetModel();
+ models.clear();
+ invites.clear();
+ roomids.clear();
+ currentRoom_ = nullptr;
+ emit currentRoomChanged();
+ endResetModel();
}
void
RoomlistModel::joinPreview(QString roomid, QString parentSpace)
{
- if (previewedRooms.contains(roomid)) {
- auto child = cache::client()->getStateEvent<mtx::events::state::space::Child>(
- parentSpace.toStdString(), roomid.toStdString());
- ChatPage::instance()->joinRoomVia(roomid.toStdString(),
- (child && child->content.via)
- ? child->content.via.value()
- : std::vector<std::string>{},
- false);
- }
+ if (previewedRooms.contains(roomid)) {
+ auto child = cache::client()->getStateEvent<mtx::events::state::space::Child>(
+ parentSpace.toStdString(), roomid.toStdString());
+ ChatPage::instance()->joinRoomVia(
+ roomid.toStdString(),
+ (child && child->content.via) ? child->content.via.value() : std::vector<std::string>{},
+ false);
+ }
}
void
RoomlistModel::acceptInvite(QString roomid)
{
- if (invites.contains(roomid)) {
- // Don't remove invite yet, so that we can switch to it
- ChatPage::instance()->joinRoom(roomid);
- }
+ if (invites.contains(roomid)) {
+ // Don't remove invite yet, so that we can switch to it
+ ChatPage::instance()->joinRoom(roomid);
+ }
}
void
RoomlistModel::declineInvite(QString roomid)
{
- if (invites.contains(roomid)) {
- auto idx = roomidToIndex(roomid);
-
- if (idx != -1) {
- beginRemoveRows(QModelIndex(), idx, idx);
- roomids.erase(roomids.begin() + idx);
- invites.remove(roomid);
- endRemoveRows();
- ChatPage::instance()->leaveRoom(roomid);
- }
+ if (invites.contains(roomid)) {
+ auto idx = roomidToIndex(roomid);
+
+ if (idx != -1) {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ roomids.erase(roomids.begin() + idx);
+ invites.remove(roomid);
+ endRemoveRows();
+ ChatPage::instance()->leaveRoom(roomid);
}
+ }
}
void
RoomlistModel::leave(QString roomid)
{
- if (models.contains(roomid)) {
- auto idx = roomidToIndex(roomid);
-
- if (idx != -1) {
- beginRemoveRows(QModelIndex(), idx, idx);
- roomids.erase(roomids.begin() + idx);
- models.remove(roomid);
- endRemoveRows();
- ChatPage::instance()->leaveRoom(roomid);
- }
+ if (models.contains(roomid)) {
+ auto idx = roomidToIndex(roomid);
+
+ if (idx != -1) {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ roomids.erase(roomids.begin() + idx);
+ models.remove(roomid);
+ endRemoveRows();
+ ChatPage::instance()->leaveRoom(roomid);
}
+ }
}
void
RoomlistModel::setCurrentRoom(QString roomid)
{
- if ((currentRoom_ && currentRoom_->roomId() == roomid) ||
- (currentRoomPreview_ && currentRoomPreview_->roomid() == roomid))
- return;
+ if ((currentRoom_ && currentRoom_->roomId() == roomid) ||
+ (currentRoomPreview_ && currentRoomPreview_->roomid() == roomid))
+ return;
+
+ nhlog::ui()->debug("Trying to switch to: {}", roomid.toStdString());
+ if (models.contains(roomid)) {
+ currentRoom_ = models.value(roomid);
+ currentRoomPreview_.reset();
+ emit currentRoomChanged();
+ nhlog::ui()->debug("Switched to: {}", roomid.toStdString());
+ } else if (invites.contains(roomid) || previewedRooms.contains(roomid)) {
+ currentRoom_ = nullptr;
+ std::optional<RoomInfo> i;
- nhlog::ui()->debug("Trying to switch to: {}", roomid.toStdString());
- if (models.contains(roomid)) {
- currentRoom_ = models.value(roomid);
- currentRoomPreview_.reset();
- emit currentRoomChanged();
- nhlog::ui()->debug("Switched to: {}", roomid.toStdString());
- } else if (invites.contains(roomid) || previewedRooms.contains(roomid)) {
- currentRoom_ = nullptr;
- std::optional<RoomInfo> i;
-
- RoomPreview p;
-
- if (invites.contains(roomid)) {
- i = invites.value(roomid);
- p.isInvite_ = true;
- } else {
- i = previewedRooms.value(roomid);
- p.isInvite_ = false;
- }
+ RoomPreview p;
- if (i) {
- p.roomid_ = roomid;
- p.roomName_ = QString::fromStdString(i->name);
- p.roomTopic_ = QString::fromStdString(i->topic);
- p.roomAvatarUrl_ = QString::fromStdString(i->avatar_url);
- currentRoomPreview_ = std::move(p);
- }
+ if (invites.contains(roomid)) {
+ i = invites.value(roomid);
+ p.isInvite_ = true;
+ } else {
+ i = previewedRooms.value(roomid);
+ p.isInvite_ = false;
+ }
- emit currentRoomChanged();
- nhlog::ui()->debug("Switched to: {}", roomid.toStdString());
+ if (i) {
+ p.roomid_ = roomid;
+ p.roomName_ = QString::fromStdString(i->name);
+ p.roomTopic_ = QString::fromStdString(i->topic);
+ p.roomAvatarUrl_ = QString::fromStdString(i->avatar_url);
+ currentRoomPreview_ = std::move(p);
}
+
+ emit currentRoomChanged();
+ nhlog::ui()->debug("Switched to: {}", roomid.toStdString());
+ }
}
namespace {
enum NotificationImportance : short
{
- ImportanceDisabled = -3,
- NoPreview = -2,
- Preview = -1,
- AllEventsRead = 0,
- NewMessage = 1,
- NewMentions = 2,
- Invite = 3,
- SubSpace = 4,
- CurrentSpace = 5,
+ ImportanceDisabled = -3,
+ NoPreview = -2,
+ Preview = -1,
+ AllEventsRead = 0,
+ NewMessage = 1,
+ NewMentions = 2,
+ Invite = 3,
+ SubSpace = 4,
+ CurrentSpace = 5,
};
}
short int
FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const
{
- // Returns the degree of importance of the unread messages in the room.
- // If sorting by importance is disabled in settings, this only ever
- // returns ImportanceDisabled or Invite
- if (sourceModel()->data(idx, RoomlistModel::IsSpace).toBool()) {
- if (filterType == FilterBy::Space &&
- filterStr == sourceModel()->data(idx, RoomlistModel::RoomId).toString())
- return CurrentSpace;
- else
- return SubSpace;
- } else if (sourceModel()->data(idx, RoomlistModel::IsPreview).toBool()) {
- if (sourceModel()->data(idx, RoomlistModel::IsPreviewFetched).toBool())
- return Preview;
- else
- return NoPreview;
- } else if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) {
- return Invite;
- } else if (!this->sortByImportance) {
- return ImportanceDisabled;
- } else if (sourceModel()->data(idx, RoomlistModel::HasLoudNotification).toBool()) {
- return NewMentions;
- } else if (sourceModel()->data(idx, RoomlistModel::NotificationCount).toInt() > 0) {
- return NewMessage;
- } else {
- return AllEventsRead;
- }
+ // Returns the degree of importance of the unread messages in the room.
+ // If sorting by importance is disabled in settings, this only ever
+ // returns ImportanceDisabled or Invite
+ if (sourceModel()->data(idx, RoomlistModel::IsSpace).toBool()) {
+ if (filterType == FilterBy::Space &&
+ filterStr == sourceModel()->data(idx, RoomlistModel::RoomId).toString())
+ return CurrentSpace;
+ else
+ return SubSpace;
+ } else if (sourceModel()->data(idx, RoomlistModel::IsPreview).toBool()) {
+ if (sourceModel()->data(idx, RoomlistModel::IsPreviewFetched).toBool())
+ return Preview;
+ else
+ return NoPreview;
+ } else if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) {
+ return Invite;
+ } else if (!this->sortByImportance) {
+ return ImportanceDisabled;
+ } else if (sourceModel()->data(idx, RoomlistModel::HasLoudNotification).toBool()) {
+ return NewMentions;
+ } else if (sourceModel()->data(idx, RoomlistModel::NotificationCount).toInt() > 0) {
+ return NewMessage;
+ } else {
+ return AllEventsRead;
+ }
}
bool
FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
- QModelIndex const left_idx = sourceModel()->index(left.row(), 0, QModelIndex());
- QModelIndex const right_idx = sourceModel()->index(right.row(), 0, QModelIndex());
-
- // Sort by "importance" (i.e. invites before mentions before
- // notifs before new events before old events), then secondly
- // by recency.
-
- // Checking importance first
- const auto a_importance = calculateImportance(left_idx);
- const auto b_importance = calculateImportance(right_idx);
- if (a_importance != b_importance) {
- return a_importance > b_importance;
- }
-
- // Now sort by recency
- // Zero if empty, otherwise the time that the event occured
- uint64_t a_recency = sourceModel()->data(left_idx, RoomlistModel::Timestamp).toULongLong();
- uint64_t b_recency = sourceModel()->data(right_idx, RoomlistModel::Timestamp).toULongLong();
-
- if (a_recency != b_recency)
- return a_recency > b_recency;
- else
- return left.row() < right.row();
+ QModelIndex const left_idx = sourceModel()->index(left.row(), 0, QModelIndex());
+ QModelIndex const right_idx = sourceModel()->index(right.row(), 0, QModelIndex());
+
+ // Sort by "importance" (i.e. invites before mentions before
+ // notifs before new events before old events), then secondly
+ // by recency.
+
+ // Checking importance first
+ const auto a_importance = calculateImportance(left_idx);
+ const auto b_importance = calculateImportance(right_idx);
+ if (a_importance != b_importance) {
+ return a_importance > b_importance;
+ }
+
+ // Now sort by recency
+ // Zero if empty, otherwise the time that the event occured
+ uint64_t a_recency = sourceModel()->data(left_idx, RoomlistModel::Timestamp).toULongLong();
+ uint64_t b_recency = sourceModel()->data(right_idx, RoomlistModel::Timestamp).toULongLong();
+
+ if (a_recency != b_recency)
+ return a_recency > b_recency;
+ else
+ return left.row() < right.row();
}
FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *parent)
: QSortFilterProxyModel(parent)
, roomlistmodel(model)
{
- this->sortByImportance = UserSettings::instance()->sortByImportance();
- setSourceModel(model);
- setDynamicSortFilter(true);
-
- QObject::connect(UserSettings::instance().get(),
- &UserSettings::roomSortingChanged,
- this,
- [this](bool sortByImportance_) {
- this->sortByImportance = sortByImportance_;
- invalidate();
- });
-
- connect(roomlistmodel,
- &RoomlistModel::currentRoomChanged,
- this,
- &FilteredRoomlistModel::currentRoomChanged);
-
- sort(0);
+ this->sortByImportance = UserSettings::instance()->sortByImportance();
+ setSourceModel(model);
+ setDynamicSortFilter(true);
+
+ QObject::connect(UserSettings::instance().get(),
+ &UserSettings::roomSortingChanged,
+ this,
+ [this](bool sortByImportance_) {
+ this->sortByImportance = sortByImportance_;
+ invalidate();
+ });
+
+ connect(roomlistmodel,
+ &RoomlistModel::currentRoomChanged,
+ this,
+ &FilteredRoomlistModel::currentRoomChanged);
+
+ sort(0);
}
void
FilteredRoomlistModel::updateHiddenTagsAndSpaces()
{
- hiddenTags.clear();
- hiddenSpaces.clear();
- for (const auto &t : UserSettings::instance()->hiddenTags()) {
- if (t.startsWith("tag:"))
- hiddenTags.push_back(t.mid(4));
- else if (t.startsWith("space:"))
- hiddenSpaces.push_back(t.mid(6));
- }
-
- invalidateFilter();
+ hiddenTags.clear();
+ hiddenSpaces.clear();
+ for (const auto &t : UserSettings::instance()->hiddenTags()) {
+ if (t.startsWith("tag:"))
+ hiddenTags.push_back(t.mid(4));
+ else if (t.startsWith("space:"))
+ hiddenSpaces.push_back(t.mid(6));
+ }
+
+ invalidateFilter();
}
bool
FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const
{
- if (filterType == FilterBy::Nothing) {
- if (sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview)
- .toBool()) {
- return false;
- }
+ if (filterType == FilterBy::Nothing) {
+ if (sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview)
+ .toBool()) {
+ return false;
+ }
- if (sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
- .toBool()) {
- return false;
- }
+ if (sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
+ .toBool()) {
+ return false;
+ }
- if (!hiddenTags.empty()) {
- auto tags =
- sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
- .toStringList();
+ if (!hiddenTags.empty()) {
+ auto tags = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
+ .toStringList();
- for (const auto &t : tags)
- if (hiddenTags.contains(t))
- return false;
- }
+ for (const auto &t : tags)
+ if (hiddenTags.contains(t))
+ return false;
+ }
- if (!hiddenSpaces.empty()) {
- auto parents =
- sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
- .toStringList();
- for (const auto &t : parents)
- if (hiddenSpaces.contains(t))
- return false;
- }
+ if (!hiddenSpaces.empty()) {
+ auto parents = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
+ .toStringList();
+ for (const auto &t : parents)
+ if (hiddenSpaces.contains(t))
+ return false;
+ }
- return true;
- } else if (filterType == FilterBy::Tag) {
- if (sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview)
- .toBool()) {
- return false;
- }
+ return true;
+ } else if (filterType == FilterBy::Tag) {
+ if (sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview)
+ .toBool()) {
+ return false;
+ }
- if (sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
- .toBool()) {
- return false;
- }
+ if (sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
+ .toBool()) {
+ return false;
+ }
- auto tags = sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
- .toStringList();
+ auto tags = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
+ .toStringList();
- if (!tags.contains(filterStr))
- return false;
+ if (!tags.contains(filterStr))
+ return false;
- if (!hiddenTags.empty()) {
- for (const auto &t : tags)
- if (t != filterStr && hiddenTags.contains(t))
- return false;
- }
+ if (!hiddenTags.empty()) {
+ for (const auto &t : tags)
+ if (t != filterStr && hiddenTags.contains(t))
+ return false;
+ }
- if (!hiddenSpaces.empty()) {
- auto parents =
- sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
- .toStringList();
- for (const auto &t : parents)
- if (hiddenSpaces.contains(t))
- return false;
- }
+ if (!hiddenSpaces.empty()) {
+ auto parents = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
+ .toStringList();
+ for (const auto &t : parents)
+ if (hiddenSpaces.contains(t))
+ return false;
+ }
- return true;
- } else if (filterType == FilterBy::Space) {
- if (filterStr == sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId)
- .toString())
- return true;
-
- auto parents =
- sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
- .toStringList();
-
- if (!parents.contains(filterStr))
- return false;
-
- if (!hiddenTags.empty()) {
- auto tags =
- sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
- .toStringList();
-
- for (const auto &t : tags)
- if (hiddenTags.contains(t))
- return false;
- }
+ return true;
+ } else if (filterType == FilterBy::Space) {
+ if (filterStr == sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId)
+ .toString())
+ return true;
- if (!hiddenSpaces.empty()) {
- for (const auto &t : parents)
- if (hiddenSpaces.contains(t))
- return false;
- }
+ auto parents = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces)
+ .toStringList();
- if (sourceModel()
- ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
- .toBool() &&
- !parents.contains(filterStr)) {
- return false;
- }
+ if (!parents.contains(filterStr))
+ return false;
- return true;
- } else {
- return true;
+ if (!hiddenTags.empty()) {
+ auto tags = sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags)
+ .toStringList();
+
+ for (const auto &t : tags)
+ if (hiddenTags.contains(t))
+ return false;
+ }
+
+ if (!hiddenSpaces.empty()) {
+ for (const auto &t : parents)
+ if (hiddenSpaces.contains(t))
+ return false;
+ }
+
+ if (sourceModel()
+ ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace)
+ .toBool() &&
+ !parents.contains(filterStr)) {
+ return false;
}
+
+ return true;
+ } else {
+ return true;
+ }
}
void
FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on)
{
- if (on) {
- http::client()->put_tag(
- roomid.toStdString(), tag.toStdString(), {}, [tag](mtx::http::RequestErr err) {
- if (err) {
- nhlog::ui()->error("Failed to add tag: {}, {}",
- tag.toStdString(),
- err->matrix_error.error);
- }
- });
- } else {
- http::client()->delete_tag(
- roomid.toStdString(), tag.toStdString(), [tag](mtx::http::RequestErr err) {
- if (err) {
- nhlog::ui()->error("Failed to delete tag: {}, {}",
- tag.toStdString(),
- err->matrix_error.error);
- }
- });
- }
+ if (on) {
+ http::client()->put_tag(
+ roomid.toStdString(), tag.toStdString(), {}, [tag](mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::ui()->error(
+ "Failed to add tag: {}, {}", tag.toStdString(), err->matrix_error.error);
+ }
+ });
+ } else {
+ http::client()->delete_tag(
+ roomid.toStdString(), tag.toStdString(), [tag](mtx::http::RequestErr err) {
+ if (err) {
+ nhlog::ui()->error(
+ "Failed to delete tag: {}, {}", tag.toStdString(), err->matrix_error.error);
+ }
+ });
+ }
}
void
FilteredRoomlistModel::nextRoomWithActivity()
{
- int roomWithMention = -1;
- int roomWithNotification = -1;
- int roomWithUnreadMessage = -1;
- auto r = currentRoom();
- int currentRoomIdx = r ? roomidToIndex(r->roomId()) : -1;
- // first look for mentions
- for (int i = 0; i < (int)roomlistmodel->roomids.size(); i++) {
- if (i == currentRoomIdx)
- continue;
- if (this->data(index(i, 0), RoomlistModel::HasLoudNotification).toBool()) {
- roomWithMention = i;
- break;
- }
- if (roomWithNotification == -1 &&
- this->data(index(i, 0), RoomlistModel::NotificationCount).toInt() > 0) {
- roomWithNotification = i;
- // don't break, we must continue looking for rooms with mentions
- }
- if (roomWithNotification == -1 && roomWithUnreadMessage == -1 &&
- this->data(index(i, 0), RoomlistModel::HasUnreadMessages).toBool()) {
- roomWithUnreadMessage = i;
- // don't break, we must continue looking for rooms with mentions
- }
+ int roomWithMention = -1;
+ int roomWithNotification = -1;
+ int roomWithUnreadMessage = -1;
+ auto r = currentRoom();
+ int currentRoomIdx = r ? roomidToIndex(r->roomId()) : -1;
+ // first look for mentions
+ for (int i = 0; i < (int)roomlistmodel->roomids.size(); i++) {
+ if (i == currentRoomIdx)
+ continue;
+ if (this->data(index(i, 0), RoomlistModel::HasLoudNotification).toBool()) {
+ roomWithMention = i;
+ break;
}
- QString targetRoomId = nullptr;
- if (roomWithMention != -1) {
- targetRoomId =
- this->data(index(roomWithMention, 0), RoomlistModel::RoomId).toString();
- nhlog::ui()->debug("choosing {} for mentions", targetRoomId.toStdString());
- } else if (roomWithNotification != -1) {
- targetRoomId =
- this->data(index(roomWithNotification, 0), RoomlistModel::RoomId).toString();
- nhlog::ui()->debug("choosing {} for notifications", targetRoomId.toStdString());
- } else if (roomWithUnreadMessage != -1) {
- targetRoomId =
- this->data(index(roomWithUnreadMessage, 0), RoomlistModel::RoomId).toString();
- nhlog::ui()->debug("choosing {} for unread messages", targetRoomId.toStdString());
+ if (roomWithNotification == -1 &&
+ this->data(index(i, 0), RoomlistModel::NotificationCount).toInt() > 0) {
+ roomWithNotification = i;
+ // don't break, we must continue looking for rooms with mentions
}
- if (targetRoomId != nullptr) {
- setCurrentRoom(targetRoomId);
+ if (roomWithNotification == -1 && roomWithUnreadMessage == -1 &&
+ this->data(index(i, 0), RoomlistModel::HasUnreadMessages).toBool()) {
+ roomWithUnreadMessage = i;
+ // don't break, we must continue looking for rooms with mentions
}
+ }
+ QString targetRoomId = nullptr;
+ if (roomWithMention != -1) {
+ targetRoomId = this->data(index(roomWithMention, 0), RoomlistModel::RoomId).toString();
+ nhlog::ui()->debug("choosing {} for mentions", targetRoomId.toStdString());
+ } else if (roomWithNotification != -1) {
+ targetRoomId = this->data(index(roomWithNotification, 0), RoomlistModel::RoomId).toString();
+ nhlog::ui()->debug("choosing {} for notifications", targetRoomId.toStdString());
+ } else if (roomWithUnreadMessage != -1) {
+ targetRoomId =
+ this->data(index(roomWithUnreadMessage, 0), RoomlistModel::RoomId).toString();
+ nhlog::ui()->debug("choosing {} for unread messages", targetRoomId.toStdString());
+ }
+ if (targetRoomId != nullptr) {
+ setCurrentRoom(targetRoomId);
+ }
}
void
FilteredRoomlistModel::nextRoom()
{
- auto r = currentRoom();
-
- if (r) {
- int idx = roomidToIndex(r->roomId());
- idx++;
- if (idx < rowCount()) {
- setCurrentRoom(
- data(index(idx, 0), RoomlistModel::Roles::RoomId).toString());
- }
+ auto r = currentRoom();
+
+ if (r) {
+ int idx = roomidToIndex(r->roomId());
+ idx++;
+ if (idx < rowCount()) {
+ setCurrentRoom(data(index(idx, 0), RoomlistModel::Roles::RoomId).toString());
}
+ }
}
void
FilteredRoomlistModel::previousRoom()
{
- auto r = currentRoom();
-
- if (r) {
- int idx = roomidToIndex(r->roomId());
- idx--;
- if (idx >= 0) {
- setCurrentRoom(
- data(index(idx, 0), RoomlistModel::Roles::RoomId).toString());
- }
+ auto r = currentRoom();
+
+ if (r) {
+ int idx = roomidToIndex(r->roomId());
+ idx--;
+ if (idx >= 0) {
+ setCurrentRoom(data(index(idx, 0), RoomlistModel::Roles::RoomId).toString());
}
+ }
}
|