summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-05-21 21:19:03 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-05-21 21:19:03 +0200
commitcd67046f6011f0838b5ed4621fb3ee9b846e63a0 (patch)
tree91ea6ecd1273b69b97717076ec9387ddea6936da /src/timeline
parentSome basic room list (diff)
downloadnheko-cd67046f6011f0838b5ed4621fb3ee9b846e63a0.tar.xz
Make roomlist look nice
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/RoomlistModel.cpp107
-rw-r--r--src/timeline/RoomlistModel.h20
-rw-r--r--src/timeline/TimelineModel.cpp30
-rw-r--r--src/timeline/TimelineModel.h14
4 files changed, 160 insertions, 11 deletions
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(), diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h
index 44fcf032..c4c9d9ba 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h
@@ -22,8 +22,11 @@ public: { AvatarUrl = Qt::UserRole, RoomName, + RoomId, LastMessage, + Timestamp, HasUnreadMessages, + HasLoudNotification, NotificationCount, }; @@ -47,6 +50,21 @@ public slots: void initializeRooms(const std::vector<QString> &roomids); void sync(const mtx::responses::Rooms &rooms); void clear(); + int roomidToIndex(QString roomid) + { + for (int i = 0; i < (int)roomids.size(); i++) { + if (roomids[i] == roomid) + return i; + } + + return -1; + } + +private slots: + void updateReadStatus(const std::map<QString, bool> roomReadStatus_); + +signals: + void totalUnreadMessageCountUpdated(int unreadMessages); private: void addRoom(const QString &room_id, bool suppressInsertNotification = false); @@ -54,5 +72,5 @@ private: TimelineViewManager *manager = nullptr; std::vector<QString> roomids; QHash<QString, QSharedPointer<TimelineModel>> models; + std::map<QString, bool> roomReadStatus; }; - diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 8df17457..19c3fb30 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -724,6 +724,20 @@ TimelineModel::fetchMore(const QModelIndex &) } void +TimelineModel::sync(const mtx::responses::JoinedRoom &room) +{ + this->syncState(room.state); + this->addEvents(room.timeline); + + if (room.unread_notifications.highlight_count != highlight_count || + room.unread_notifications.notification_count != notification_count) { + notification_count = room.unread_notifications.notification_count; + highlight_count = room.unread_notifications.highlight_count; + emit notificationsChanged(); + } +} + +void TimelineModel::syncState(const mtx::responses::State &s) { using namespace mtx::events; @@ -866,14 +880,18 @@ TimelineModel::updateLastMessage() if (std::visit([](const auto &e) -> bool { return isYourJoin(e); }, *event)) { auto time = mtx::accessors::origin_server_ts(*event); uint64_t ts = time.toMSecsSinceEpoch(); - emit manager_->updateRoomsLastMessage( - room_id_, + auto description = DescInfo{QString::fromStdString(mtx::accessors::event_id(*event)), QString::fromStdString(http::client()->user_id().to_string()), tr("You joined this room."), utils::descriptiveTime(time), ts, - time}); + time}; + if (description != lastMessage_) { + lastMessage_ = description; + emit manager_->updateRoomsLastMessage(room_id_, lastMessage_); + emit lastMessageChanged(); + } return; } if (!std::visit([](const auto &e) -> bool { return isMessage(e); }, *event)) @@ -884,7 +902,11 @@ TimelineModel::updateLastMessage() QString::fromStdString(http::client()->user_id().to_string()), cache::displayName(room_id_, QString::fromStdString(mtx::accessors::sender(*event)))); - emit manager_->updateRoomsLastMessage(room_id_, description); + if (description != lastMessage_) { + lastMessage_ = description; + emit manager_->updateRoomsLastMessage(room_id_, description); + emit lastMessageChanged(); + } return; } } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 92fccd2d..5c1065cb 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -14,6 +14,7 @@ #include <mtxclient/http/errors.hpp> #include "CacheCryptoStructs.h" +#include "CacheStructs.h" #include "EventStore.h" #include "InputBar.h" #include "Permissions.h" @@ -253,12 +254,15 @@ public: } void updateLastMessage(); + void sync(const mtx::responses::JoinedRoom &room); void addEvents(const mtx::responses::Timeline &events); void syncState(const mtx::responses::State &state); template<class T> void sendMessageEvent(const T &content, mtx::events::EventType eventType); RelatedInfo relatedInfo(QString id); + DescInfo lastMessage() const { return lastMessage_; } + public slots: void setCurrentIndex(int index); int currentIndex() const { return idToIndex(currentId); } @@ -309,6 +313,9 @@ public slots: QString roomAvatarUrl() const; QString roomId() const { return room_id_; } + bool hasMentions() { return highlight_count > 0; } + int notificationCount() { return notification_count; } + QString scrollTarget() const; private slots: @@ -328,6 +335,9 @@ signals: void newCallEvent(const mtx::events::collections::TimelineEvents &event); void scrollToIndex(int index); + void lastMessageChanged(); + void notificationsChanged(); + void openRoomSettingsDialog(RoomSettings *settings); void newMessageToSend(mtx::events::collections::TimelineEvents event); @@ -372,7 +382,11 @@ private: QString eventIdToShow; int showEventTimerCounter = 0; + DescInfo lastMessage_; + friend struct SendMessageVisitor; + + int notification_count = 0, highlight_count = 0; }; template<class T>