diff --git a/src/RoomList.cpp b/src/RoomList.cpp
index 6feb4f76..1c7c340d 100644
--- a/src/RoomList.cpp
+++ b/src/RoomList.cpp
@@ -16,6 +16,7 @@
*/
#include <limits>
+#include <set>
#include <QObject>
#include <QPainter>
@@ -26,11 +27,13 @@
#include "MainWindow.h"
#include "RoomInfoListItem.h"
#include "RoomList.h"
+#include "UserSettingsPage.h"
#include "Utils.h"
#include "ui/OverlayModal.h"
-RoomList::RoomList(QWidget *parent)
+RoomList::RoomList(QSharedPointer<UserSettings> userSettings, QWidget *parent)
: QWidget(parent)
+ , settings(userSettings)
{
topLayout_ = new QVBoxLayout(this);
topLayout_->setSpacing(0);
@@ -62,12 +65,16 @@ RoomList::RoomList(QWidget *parent)
topLayout_->addWidget(scrollArea_);
connect(this, &RoomList::updateRoomAvatarCb, this, &RoomList::updateRoomAvatar);
+ connect(userSettings.data(),
+ &UserSettings::roomSortingChanged,
+ this,
+ &RoomList::sortRoomsByLastMessage);
}
void
RoomList::addRoom(const QString &room_id, const RoomInfo &info)
{
- auto room_item = new RoomInfoListItem(room_id, info, scrollArea_);
+ auto room_item = new RoomInfoListItem(room_id, info, settings, scrollArea_);
room_item->setRoomName(QString::fromStdString(std::move(info.name)));
connect(room_item, &RoomInfoListItem::clicked, this, &RoomList::highlightSelectedRoom);
@@ -122,6 +129,8 @@ RoomList::updateUnreadMessageCount(const QString &roomid, int count, int highlig
rooms_[roomid]->updateUnreadMessageCount(count, highlightedCount);
calculateUnreadMessageCount();
+
+ sortRoomsByLastMessage();
}
void
@@ -328,30 +337,51 @@ 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);
@@ -468,7 +498,7 @@ RoomList::updateRoom(const QString &room_id, const RoomInfo &info)
void
RoomList::addInvitedRoom(const QString &room_id, const RoomInfo &info)
{
- auto room_item = new RoomInfoListItem(room_id, info, scrollArea_);
+ auto room_item = new RoomInfoListItem(room_id, info, settings, scrollArea_);
connect(room_item, &RoomInfoListItem::acceptInvite, this, &RoomList::acceptInvite);
connect(room_item, &RoomInfoListItem::declineInvite, this, &RoomList::declineInvite);
|