From cd67046f6011f0838b5ed4621fb3ee9b846e63a0 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 21 May 2021 21:19:03 +0200 Subject: Make roomlist look nice --- src/timeline/RoomlistModel.cpp | 107 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 6 deletions(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 6a1fc3c5..5fc4dc65 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -4,6 +4,7 @@ #include "RoomlistModel.h" +#include "Cache_p.h" #include "ChatPage.h" #include "MatrixClient.h" #include "MxcImageProvider.h" @@ -26,6 +27,11 @@ RoomlistModel::RoomlistModel(TimelineViewManager *parent) } } }); + + connect(this, + &RoomlistModel::totalUnreadMessageCountUpdated, + ChatPage::instance(), + &ChatPage::unreadMessages); } QHash @@ -34,8 +40,11 @@ RoomlistModel::roleNames() const return { {AvatarUrl, "avatarUrl"}, {RoomName, "roomName"}, + {RoomId, "roomId"}, {LastMessage, "lastMessage"}, + {Timestamp, "timestamp"}, {HasUnreadMessages, "hasUnreadMessages"}, + {HasLoudNotification, "hasLoudNotification"}, {NotificationCount, "notificationCount"}, }; } @@ -44,18 +53,26 @@ QVariant RoomlistModel::data(const QModelIndex &index, int role) const { if (index.row() >= 0 && static_cast(index.row()) < roomids.size()) { - auto room = models.value(roomids.at(index.row())); + auto roomid = roomids.at(index.row()); + auto room = models.value(roomid); switch (role) { case Roles::AvatarUrl: return room->roomAvatarUrl(); case Roles::RoomName: return room->roomName(); + case Roles::RoomId: + return room->roomId(); case Roles::LastMessage: - return QString("Nico: Hahaha, this is funny!"); + return room->lastMessage().body; + case Roles::Timestamp: + return room->lastMessage().descriptiveTime; case Roles::HasUnreadMessages: - return true; + return this->roomReadStatus.count(roomid) && + this->roomReadStatus.at(roomid); + case Roles::HasLoudNotification: + return room->hasMentions(); case Roles::NotificationCount: - return 5; + return room->notificationCount(); default: return {}; } @@ -64,10 +81,38 @@ RoomlistModel::data(const QModelIndex &index, int role) const } } +void +RoomlistModel::updateReadStatus(const std::map roomReadStatus_) +{ + std::vector roomsToUpdate; + roomsToUpdate.resize(roomReadStatus_.size()); + for (const auto &[roomid, roomUnread] : roomReadStatus_) { + if (roomUnread != roomReadStatus[roomid]) { + roomsToUpdate.push_back(this->roomidToIndex(roomid)); + } + } + + this->roomReadStatus = roomReadStatus_; + + for (auto idx : roomsToUpdate) { + emit dataChanged(index(idx), + index(idx), + { + Roles::HasUnreadMessages, + }); + } +}; void RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) { if (!models.contains(room_id)) { + // ensure we get read status updates and are only connected once + connect(cache::client(), + &Cache::roomReadStatus, + this, + &RoomlistModel::updateReadStatus, + Qt::UniqueConnection); + QSharedPointer newRoom(new TimelineModel(manager, room_id)); newRoom->setDecryptDescription( ChatPage::instance()->userSettings()->decryptSidebar()); @@ -80,6 +125,56 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) &TimelineModel::forwardToRoom, manager, &TimelineViewManager::forwardMessageToRoom); + connect( + newRoom.data(), &TimelineModel::lastMessageChanged, this, [room_id, this]() { + auto idx = this->roomidToIndex(room_id); + emit dataChanged(index(idx), + index(idx), + { + Roles::HasLoudNotification, + Roles::LastMessage, + Roles::Timestamp, + Roles::NotificationCount, + }); + }); + connect( + newRoom.data(), &TimelineModel::roomAvatarUrlChanged, this, [room_id, this]() { + auto idx = this->roomidToIndex(room_id); + emit dataChanged(index(idx), + index(idx), + { + Roles::AvatarUrl, + }); + }); + connect(newRoom.data(), &TimelineModel::roomNameChanged, this, [room_id, this]() { + auto idx = this->roomidToIndex(room_id); + emit dataChanged(index(idx), + index(idx), + { + Roles::RoomName, + }); + }); + connect( + newRoom.data(), &TimelineModel::notificationsChanged, this, [room_id, this]() { + auto idx = this->roomidToIndex(room_id); + emit dataChanged(index(idx), + index(idx), + { + Roles::HasLoudNotification, + Roles::NotificationCount, + }); + + int total_unread_msgs = 0; + + for (const auto &room : models) { + if (!room.isNull()) + total_unread_msgs += room->notificationCount(); + } + + emit totalUnreadMessageCountUpdated(total_unread_msgs); + }); + + newRoom->updateLastMessage(); if (!suppressInsertNotification) beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size()); @@ -97,8 +192,8 @@ RoomlistModel::sync(const mtx::responses::Rooms &rooms) // addRoom will only add the room, if it doesn't exist addRoom(QString::fromStdString(room_id)); const auto &room_model = models.value(QString::fromStdString(room_id)); - room_model->syncState(room.state); - room_model->addEvents(room.timeline); + room_model->sync(room); + // room_model->addEvents(room.timeline); connect(room_model.data(), &TimelineModel::newCallEvent, manager->callManager(), -- cgit 1.5.1