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();
}
|