|
|
|
@ -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); |
|
|
|
|