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<int, QByteArray>
@@ -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<size_t>(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 {};
}
@@ -65,9 +82,37 @@ RoomlistModel::data(const QModelIndex &index, int role) const
}
void
+RoomlistModel::updateReadStatus(const std::map<QString, bool> roomReadStatus_)
+{
+ std::vector<int> 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<TimelineModel> 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(),
|