summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorHiers <47784553+Hiers@users.noreply.github.com>2022-09-11 23:05:20 +0000
committerGitHub <noreply@github.com>2022-09-11 23:05:20 +0000
commit8071b192b8cecf0b0f422d74678038dd3afbe3bc (patch)
treee5340dccf4ad742a86199e82758a9de5eff038fb /src/timeline
parentMerge pull request #1163 from foresto/log-options (diff)
downloadnheko-8071b192b8cecf0b0f422d74678038dd3afbe3bc.tar.xz
Line to indicate first unread message (#1147)
* First draft of unread line feature.

* Minor visual fix.

* Removed unnecessary ternary operator.

* Extended unread line functionality to work on minimised window or focusing another window.

* Fix for unread line not showing when last read message is hidden.

* Minor performance improvement. Fix for misbehaving event2order DB at application start.

* Fix for possible performance issues when user has joined a large number of rooms.

* Fix for breaking macos and clazy builds.

* Changed on windows focus function to refresh unread line if room is unread.

* Unread line is removed when user sends a message.

* Linting.

* Fixed unread line to work in standalone room windows.

* Switch isRoomUnread for index 0.

* Merged try/catch blocks.

* Fix for crash on opening a room invite.

* Call fullyReadEventId function when used instead of storing it and passing it through.

* Function that was meant to sync the unread line was relying on an async function, oops.

* Linting again.

* More linting...

* Minor changes.
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/RoomlistModel.cpp18
-rw-r--r--src/timeline/RoomlistModel.h6
-rw-r--r--src/timeline/TimelineModel.cpp47
-rw-r--r--src/timeline/TimelineModel.h9
4 files changed, 72 insertions, 8 deletions
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp

index 03abd3d5..6e95ef8e 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp
@@ -283,6 +283,14 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) QSharedPointer<TimelineModel> newRoom(new TimelineModel(manager, room_id)); newRoom->setDecryptDescription(ChatPage::instance()->userSettings()->decryptSidebar()); + connect(this, + &RoomlistModel::currentRoomChanged, + newRoom.data(), + &TimelineModel::updateLastReadId); + connect(MainWindow::instance(), + &MainWindow::activeChanged, + newRoom.data(), + &TimelineModel::lastReadIdOnWindowFocus); connect(newRoom.data(), &TimelineModel::newEncryptedImage, MainWindow::instance()->imageProvider(), @@ -383,7 +391,7 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) currentRoomPreview_->roomid() == room_id) { currentRoom_ = models.value(room_id); currentRoomPreview_.reset(); - emit currentRoomChanged(); + emit currentRoomChanged(room_id); } for (auto p : previewsToAdd) { @@ -644,7 +652,7 @@ RoomlistModel::clear() invites.clear(); roomids.clear(); currentRoom_ = nullptr; - emit currentRoomChanged(); + emit currentRoomChanged(""); endResetModel(); } @@ -743,14 +751,14 @@ RoomlistModel::setCurrentRoom(QString roomid) if (roomid.isEmpty()) { currentRoom_ = nullptr; currentRoomPreview_ = {}; - emit currentRoomChanged(); + emit currentRoomChanged(""); } nhlog::ui()->debug("Trying to switch to: {}", roomid.toStdString()); if (models.contains(roomid)) { currentRoom_ = models.value(roomid); currentRoomPreview_.reset(); - emit currentRoomChanged(); + emit currentRoomChanged(currentRoom_->roomId()); nhlog::ui()->debug("Switched to: {}", roomid.toStdString()); } else if (invites.contains(roomid) || previewedRooms.contains(roomid)) { currentRoom_ = nullptr; @@ -781,7 +789,7 @@ RoomlistModel::setCurrentRoom(QString roomid) currentRoomPreview_->roomid_.toStdString()); } - emit currentRoomChanged(); + emit currentRoomChanged(""); } } diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h
index 61bf2e7c..2f2ea066 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h
@@ -116,7 +116,7 @@ public slots: { currentRoom_ = nullptr; currentRoomPreview_.reset(); - emit currentRoomChanged(); + emit currentRoomChanged(""); } private slots: @@ -124,7 +124,7 @@ private slots: signals: void totalUnreadMessageCountUpdated(int unreadMessages); - void currentRoomChanged(); + void currentRoomChanged(QString currentRoomId); void fetchedPreview(QString roomid, RoomInfo info); private: @@ -218,7 +218,7 @@ public slots: void updateHiddenTagsAndSpaces(); signals: - void currentRoomChanged(); + void currentRoomChanged(QString currentRoomId); private: short int calculateImportance(const QModelIndex &idx) const; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index b7122db1..eaf85b2a 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -427,6 +427,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj setPaginationInProgress(false); updateLastMessage(); }); + connect(&events, &EventStore::fetchedMore, this, &TimelineModel::checkAfterFetch); connect(&events, &EventStore::startDMVerification, this, @@ -977,6 +978,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) emit encryptionChanged(); } } + updateLastMessage(); } @@ -1370,6 +1372,48 @@ TimelineModel::markEventsAsRead(const std::vector<QString> &event_ids) } } +void +TimelineModel::updateLastReadId(QString currentRoomId) +{ + if (currentRoomId == room_id_) { + last_event_id = cache::getFullyReadEventId(room_id_.toStdString()); + auto lastVisibleEventIndexAndId = + cache::lastVisibleEvent(room_id_.toStdString(), last_event_id); + if (lastVisibleEventIndexAndId) { + fullyReadEventId_ = lastVisibleEventIndexAndId->second; + emit fullyReadEventIdChanged(); + } + } +} + +void +TimelineModel::lastReadIdOnWindowFocus() +{ + /* this stops it from removing the line when focusing another window + * and from removing the line when refocusing nheko */ + if (ChatPage::instance()->isRoomActive(room_id_) && + cache::calculateRoomReadStatus(room_id_.toStdString())) { + updateLastReadId(room_id_); + } +} + +/* + * if the event2order db didn't have the messages we needed when the room was opened + * try again after these new messages were fetched + */ +void +TimelineModel::checkAfterFetch() +{ + if (fullyReadEventId_.empty()) { + auto lastVisibleEventIndexAndId = + cache::lastVisibleEvent(room_id_.toStdString(), last_event_id); + if (lastVisibleEventIndexAndId) { + fullyReadEventId_ = lastVisibleEventIndexAndId->second; + emit fullyReadEventIdChanged(); + } + } +} + template<typename T> void TimelineModel::sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events::EventType eventType) @@ -1550,6 +1594,9 @@ TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event) event); std::visit(SendMessageVisitor{this}, event); + + fullyReadEventId_ = this->EventId; + emit fullyReadEventIdChanged(); } void diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 47fd27f1..295bc69b 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -189,6 +189,7 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QStringList widgetLinks READ widgetLinks NOTIFY widgetLinksChanged) Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) Q_PROPERTY(bool isEncrypted READ isEncrypted NOTIFY encryptionChanged) + Q_PROPERTY(QString fullyReadEventId READ fullyReadEventId NOTIFY fullyReadEventIdChanged) Q_PROPERTY(bool isSpace READ isSpace CONSTANT) Q_PROPERTY(int trustlevel READ trustlevel NOTIFY trustlevelChanged) Q_PROPERTY(bool isDirect READ isDirect NOTIFY isDirectChanged) @@ -325,6 +326,7 @@ public: bool isSpace() const { return isSpace_; } bool isEncrypted() const { return isEncrypted_; } + QString fullyReadEventId() const { return QString::fromStdString(fullyReadEventId_); } crypto::Trust trustlevel() const; int roomMemberCount() const; bool isDirect() const { return roomMemberCount() <= 2; } @@ -344,6 +346,9 @@ public slots: int currentIndex() const { return idToIndex(currentId); } void eventShown(); void markEventsAsRead(const std::vector<QString> &event_ids); + void updateLastReadId(QString currentRoomId); + void lastReadIdOnWindowFocus(); + void checkAfterFetch(); QVariantMap getDump(const QString &eventId, const QString &relatedTo) const; void updateTypingUsers(const std::vector<QString> &users) { @@ -427,6 +432,7 @@ signals: void updateFlowEventId(std::string event_id); void encryptionChanged(); + void fullyReadEventIdChanged(); void trustlevelChanged(); void roomNameChanged(); void roomTopicChanged(); @@ -480,6 +486,8 @@ private: bool m_paginationInProgress = false; bool isSpace_ = false; bool isEncrypted_ = false; + std::string last_event_id; + std::string fullyReadEventId_; }; template<class T> @@ -497,6 +505,7 @@ TimelineModel::sendMessageEvent(const T &content, mtx::events::EventType eventTy msgCopy.type = eventType; emit newMessageToSend(msgCopy); } + resetReply(); resetEdit(); }