summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEmi Simpson <emi@alchemi.dev>2020-03-13 19:30:50 -0400
committerEmi Simpson <emi@alchemi.dev>2020-03-13 19:30:50 -0400
commit08125e8c448b43201319242d1f5f4e96ab7c3911 (patch)
treeb28a21b2fa2100d20a176bdf4a67acd6a0be115e /src
parentMerge pull request #137 from Nheko-Reborn/blurhash (diff)
downloadnheko-08125e8c448b43201319242d1f5f4e96ab7c3911.tar.xz
Sort room list by room priority
Diffstat (limited to 'src')
-rw-r--r--src/RoomInfoListItem.cpp9
-rw-r--r--src/RoomInfoListItem.h4
-rw-r--r--src/RoomList.cpp36
3 files changed, 39 insertions, 10 deletions
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 <limits>
+#include <set>
 
 #include <QObject>
 #include <QPainter>
@@ -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<uint64_t, RoomInfoListItem *, std::greater<uint64_t>> times;
+        std::multiset<RoomInfoListItem *, room_sort> times;
 
         for (int ii = 0; ii < contentsLayout_->count(); ++ii) {
                 auto room = qobject_cast<RoomInfoListItem *>(contentsLayout_->itemAt(ii)->widget());
 
                 if (!room)
                         continue;
-
-                // Not a room message.
-                if (room->isInvite())
-                        times.emplace(std::numeric_limits<uint64_t>::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);