diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-09-19 18:59:49 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-09-19 18:59:49 +0900 |
commit | 68c3727db0e2fd4cc6d08d3969f3494a906ef4d4 (patch) | |
tree | d1650a66d0136edbc165ae100262b37e4947ae1b | |
parent | 35ef29ead1da906e4978dcd908e7c1513ac9bfd3 (diff) | |
download | libquotient-68c3727db0e2fd4cc6d08d3969f3494a906ef4d4.tar.gz libquotient-68c3727db0e2fd4cc6d08d3969f3494a906ef4d4.zip |
Room: Fixed a special case with invalid-read-marker-becoming-valid
It's a case when the last-read-event id refers to an event that was outside the loaded timeline and has just arrived. Depending on what messages follow the discovered last-read one, we might need to promote the read marker and update unreadMessages flag. The latter is especially relevant in our current situation when empty timelines upon the application startup are a norm.
-rw-r--r-- | room.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -117,7 +117,8 @@ class Room::Private void dropDuplicateEvents(RoomEvents* events) const; void setLastReadEvent(User* u, const QString& eventId); - rev_iter_pair_t promoteReadMarker(User* u, rev_iter_t newMarker); + rev_iter_pair_t promoteReadMarker(User* u, rev_iter_t newMarker, + bool force = false); QJsonObject toJson() const; @@ -208,13 +209,14 @@ void Room::Private::setLastReadEvent(User* u, const QString& eventId) } Room::Private::rev_iter_pair_t -Room::Private::promoteReadMarker(User* u, Room::rev_iter_t newMarker) +Room::Private::promoteReadMarker(User* u, Room::rev_iter_t newMarker, + bool force) { Q_ASSERT_X(u, __FUNCTION__, "User* should not be nullptr"); Q_ASSERT(newMarker >= timeline.crbegin() && newMarker <= timeline.crend()); const auto prevMarker = q->readMarker(u); - if (prevMarker <= newMarker) // Remember, we deal with reverse iterators + if (!force && prevMarker <= newMarker) // Remember, we deal with reverse iterators return { prevMarker, prevMarker }; Q_ASSERT(newMarker < timeline.crend()); @@ -687,9 +689,22 @@ void Room::addHistoricalMessageEvents(RoomEvents events) void Room::doAddHistoricalMessageEvents(const RoomEvents& events) { Q_ASSERT(!events.empty()); + + const bool thereWasNoReadMarker = readMarker() == timelineEdge(); // Historical messages arrive in newest-to-oldest order for (auto e: events) d->prependEvent(e); + + // Catch a special case when the last read event id refers to an event + // that was outside the loaded timeline and has just arrived. Depending on + // other messages next to the last read one, we might need to promote + // the read marker and update unreadMessages flag. + const auto curReadMarker = readMarker(); + if (thereWasNoReadMarker && curReadMarker != timelineEdge()) + { + qCDebug(MAIN) << "Discovered last read event in a historical batch"; + d->promoteReadMarker(localUser(), curReadMarker, true); + } qCDebug(MAIN) << "Room" << displayName() << "received" << events.size() << "past events; the oldest event is now" << d->timeline.front(); } |