diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index 61fb5e47..78718285 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -324,6 +324,15 @@ RoomInfoListItem::updateUnreadMessageCount(int count, int highlightedCount) update(); } +unsigned short int +RoomInfoListItem::calculateImportance() const +{ + return (hasUnreadMessages_) + + (unreadMsgCount_ != 0) + + (unreadHighlightedMsgCount_ != 0) + + (isInvite()) * 4; +} + void RoomInfoListItem::setPressedState(bool state) { diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h index c1ee533d..a246e487 100644 --- a/src/RoomInfoListItem.h +++ b/src/RoomInfoListItem.h @@ -68,6 +68,8 @@ public: void updateUnreadMessageCount(int count, int highlightedCount); void clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); }; + unsigned short int calculateImportance() const; + QString roomId() { return roomId_; } bool isPressed() const { return isPressed_; } int unreadMessageCount() const { return unreadMsgCount_; } @@ -128,7 +130,7 @@ public: roomType_ = RoomType::Joined; } - bool isInvite() { return roomType_ == RoomType::Invited; } + bool isInvite() const { return roomType_ == RoomType::Invited; } void setReadState(bool hasUnreadMessages) { if (hasUnreadMessages_ != hasUnreadMessages) { diff --git a/src/RoomList.cpp b/src/RoomList.cpp index 6feb4f76..977cac99 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -328,30 +329,47 @@ RoomList::updateRoomDescription(const QString &roomid, const DescInfo &info) emit sortRoomsByLastMessage(); } +struct room_sort { + bool operator() (const RoomInfoListItem * a, const RoomInfoListItem * b) const { + // 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 = a->calculateImportance(); + const auto b_importance = b->calculateImportance(); + if(a_importance != b_importance) { + return a_importance > b_importance; + } + + // Now sort by recency + // Zero if empty, otherwise the time that the event occured + const uint64_t a_recency = a->lastMessageInfo().userid.isEmpty() ? 0 : + a->lastMessageInfo().datetime.toMSecsSinceEpoch(); + const uint64_t b_recency = b->lastMessageInfo().userid.isEmpty() ? 0 : + b->lastMessageInfo().datetime.toMSecsSinceEpoch(); + return a_recency > b_recency; + } +}; + void RoomList::sortRoomsByLastMessage() { isSortPending_ = false; - std::multimap> times; + std::multiset times; for (int ii = 0; ii < contentsLayout_->count(); ++ii) { auto room = qobject_cast(contentsLayout_->itemAt(ii)->widget()); if (!room) continue; - - // Not a room message. - if (room->isInvite()) - times.emplace(std::numeric_limits::max(), room); - else if (room->lastMessageInfo().userid.isEmpty()) - times.emplace(0, room); else - times.emplace(room->lastMessageInfo().datetime.toMSecsSinceEpoch(), room); + times.insert(room); } for (auto it = times.cbegin(); it != times.cend(); ++it) { - const auto roomWidget = it->second; + const auto roomWidget = *it; const auto currentIndex = contentsLayout_->indexOf(roomWidget); const auto newIndex = std::distance(times.cbegin(), it);