diff --git a/src/libneochat/enums/neochatroomtype.h b/src/libneochat/enums/neochatroomtype.h index 235beea20..8963eeec1 100644 --- a/src/libneochat/enums/neochatroomtype.h +++ b/src/libneochat/enums/neochatroomtype.h @@ -23,11 +23,11 @@ public: * @brief Defines the room list categories a room can be assigned. */ enum Types { - ServerNotice, /**< Official messages from the server. */ Invited, /**< The user has been invited to the room. */ Favorite, /**< The room is set as a favourite. */ Direct, /**< The room is a direct chat. */ Normal, /**< The default category for a joined room. */ + ServerNotice, /**< Official messages from the server. */ Deprioritized, /**< The room is set as low priority. */ Space, /**< The room is a space. */ AddDirect, /**< So we can show the add friend delegate. */ @@ -37,7 +37,7 @@ public: static NeoChatRoomType::Types typeForRoom(const NeoChatRoom *room) { - if (room->hasAccountData(u"m.tag"_s) && room->accountData(u"m.tag"_s)->contentPart(u"tags"_s).contains(u"m.server_notice"_s)) { + if (room->isServerNoticeRoom()) { return NeoChatRoomType::ServerNotice; } if (room->isSpace()) { diff --git a/src/rooms/models/roomtreemodel.cpp b/src/rooms/models/roomtreemodel.cpp index 03cf48aca..124af14bd 100644 --- a/src/rooms/models/roomtreemodel.cpp +++ b/src/rooms/models/roomtreemodel.cpp @@ -9,7 +9,9 @@ #include "enums/neochatroomtype.h" #include "eventhandler.h" #include "neochatconnection.h" +#include "neochatroom.h" #include "spacehierarchycache.h" +#include using namespace Quotient; @@ -170,6 +172,9 @@ void RoomTreeModel::connectRoomSignals(NeoChatRoom *room) }); connect(room, &Room::unreadStatsChanged, this, [this, room] { refreshRoomRoles(room, {ContextNotificationCountRole, HasHighlightNotificationsRole}); + if (room->isServerNoticeRoom()) { + Q_EMIT invalidateSort(); + } }); connect(room, &Room::avatarChanged, this, [this, room] { refreshRoomRoles(room, {AvatarRole}); diff --git a/src/rooms/models/roomtreemodel.h b/src/rooms/models/roomtreemodel.h index 5f8e07f78..a0bb6d925 100644 --- a/src/rooms/models/roomtreemodel.h +++ b/src/rooms/models/roomtreemodel.h @@ -80,6 +80,7 @@ public: Q_SIGNALS: void connectionChanged(); + void invalidateSort(); private: QPointer m_connection; diff --git a/src/rooms/models/sortfilterroomtreemodel.cpp b/src/rooms/models/sortfilterroomtreemodel.cpp index 98f113213..1ea1d93c2 100644 --- a/src/rooms/models/sortfilterroomtreemodel.cpp +++ b/src/rooms/models/sortfilterroomtreemodel.cpp @@ -11,6 +11,8 @@ #include "neochatroom.h" #include "spacehierarchycache.h" +#include + bool SortFilterRoomTreeModel::m_showAllRoomsInHome = false; SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QObject *parent) @@ -22,6 +24,7 @@ SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QOb setRecursiveFilteringEnabled(true); sort(0); connect(this, &SortFilterRoomTreeModel::filterTextChanged, this, &SortFilterRoomTreeModel::invalidateFilter); + connect(sourceModel, &RoomTreeModel::invalidateSort, this, &SortFilterRoomTreeModel::invalidate); connect(this, &SortFilterRoomTreeModel::sourceModelChanged, this, [this]() { this->sourceModel()->disconnect(this); connect(this->sourceModel(), &QAbstractItemModel::rowsInserted, this, &SortFilterRoomTreeModel::invalidateFilter); @@ -31,13 +34,21 @@ SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QOb bool SortFilterRoomTreeModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { - // Don't sort the top level categories. - if (!source_left.parent().isValid() || !source_right.parent().isValid()) { + const auto treeModel = dynamic_cast(sourceModel()); + if (treeModel == nullptr) { return false; } - const auto treeModel = dynamic_cast(sourceModel()); - if (treeModel == nullptr) { + // Don't sort the top level categories, unless there's a server notice with unread messages. + if (!source_left.parent().isValid() || !source_right.parent().isValid()) { + if (source_left.row() == NeoChatRoomType::ServerNotice) { + for (int i = 0; i < treeModel->rowCount(source_left); i++) { + auto room = treeModel->connection()->room(treeModel->index(i, 0, source_left).data(RoomTreeModel::RoomIdRole).toString()); + if (room && room->unreadStats().notableCount > 0) { + return true; + } + } + } return false; }