diff options
-rw-r--r-- | lib/room.cpp | 59 | ||||
-rw-r--r-- | lib/room.h | 7 |
2 files changed, 39 insertions, 27 deletions
diff --git a/lib/room.cpp b/lib/room.cpp index 8b81bfb2..cdc7572a 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -212,12 +212,12 @@ class Room::Private */ void dropDuplicateEvents(RoomEvents& events) const; - void setLastReadEvent(User* u, QString eventId); + Changes setLastReadEvent(User* u, QString eventId); void updateUnreadCount(rev_iter_t from, rev_iter_t to); - void promoteReadMarker(User* u, rev_iter_t newMarker, - bool force = false); + Changes promoteReadMarker(User* u, rev_iter_t newMarker, + bool force = false); - void markMessagesAsRead(rev_iter_t upToMarker); + Changes markMessagesAsRead(rev_iter_t upToMarker); QString sendEvent(RoomEventPtr&& event); @@ -386,11 +386,11 @@ void Room::setJoinState(JoinState state) emit joinStateChanged(oldState, state); } -void Room::Private::setLastReadEvent(User* u, QString eventId) +Room::Changes Room::Private::setLastReadEvent(User* u, QString eventId) { auto& storedId = lastReadEventIds[u]; if (storedId == eventId) - return; + return Change::NoChange; eventIdReadUsers.remove(storedId, u); eventIdReadUsers.insert(eventId, u); swap(storedId, eventId); @@ -401,8 +401,9 @@ void Room::Private::setLastReadEvent(User* u, QString eventId) if (storedId != serverReadMarker) connection->callApi<PostReadMarkersJob>(id, storedId); emit q->readMarkerMoved(eventId, storedId); - connection->saveRoomState(q); + return Change::ReadMarkerChange; } + return Change::NoChange; } void Room::Private::updateUnreadCount(rev_iter_t from, rev_iter_t to) @@ -445,14 +446,15 @@ void Room::Private::updateUnreadCount(rev_iter_t from, rev_iter_t to) } } -void Room::Private::promoteReadMarker(User* u, rev_iter_t newMarker, bool force) +Room::Changes Room::Private::promoteReadMarker(User* u, 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 (!force && prevMarker <= newMarker) // Remember, we deal with reverse iterators - return; + return Change::NoChange; Q_ASSERT(newMarker < timeline.crend()); @@ -461,7 +463,7 @@ void Room::Private::promoteReadMarker(User* u, rev_iter_t newMarker, bool force) auto eagerMarker = find_if(newMarker.base(), timeline.cend(), [=](const TimelineItem& ti) { return ti->senderId() != u->id(); }); - setLastReadEvent(u, (*(eagerMarker - 1))->id()); + auto changes = setLastReadEvent(u, (*(eagerMarker - 1))->id()); if (isLocalUser(u)) { const auto oldUnreadCount = unreadMessages; @@ -485,14 +487,16 @@ void Room::Private::promoteReadMarker(User* u, rev_iter_t newMarker, bool force) qCDebug(MAIN) << "Room" << displayname << "still has" << unreadMessages << "unread message(s)"; emit q->unreadMessagesChanged(q); + changes |= Change::UnreadNotifsChange; } } + return changes; } -void Room::Private::markMessagesAsRead(rev_iter_t upToMarker) +Room::Changes Room::Private::markMessagesAsRead(rev_iter_t upToMarker) { const auto prevMarker = q->readMarker(); - promoteReadMarker(q->localUser(), upToMarker); + auto changes = promoteReadMarker(q->localUser(), upToMarker); if (prevMarker != upToMarker) qCDebug(MAIN) << "Marked messages as read until" << *q->readMarker(); @@ -508,6 +512,7 @@ void Room::Private::markMessagesAsRead(rev_iter_t upToMarker) break; } } + return changes; } void Room::markMessagesAsRead(QString uptoEventId) @@ -1151,7 +1156,7 @@ void Room::updateData(SyncRoomData&& data, bool fromCache) d->updateDisplayname(); for( auto&& ephemeralEvent: data.ephemeral ) - processEphemeralEvent(move(ephemeralEvent)); + roomChanges |= processEphemeralEvent(move(ephemeralEvent)); // See https://github.com/QMatrixClient/libqmatrixclient/wiki/unread_count if (data.unreadCount != -2 && data.unreadCount != d->unreadMessages) @@ -1716,9 +1721,9 @@ Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events) // clients historically expect. This may eventually change though if we // postulate that the current state is only current between syncs but not // within a sync. - Changes stateChanges = Change::NoChange; + Changes roomChanges = Change::NoChange; for (const auto& eptr: events) - stateChanges |= q->processStateEvent(*eptr); + roomChanges |= q->processStateEvent(*eptr); auto timelineSize = timeline.size(); auto totalInserted = 0; @@ -1778,16 +1783,17 @@ Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events) auto firstWriter = q->user((*from)->senderId()); if (q->readMarker(firstWriter) != timeline.crend()) { - promoteReadMarker(firstWriter, rev_iter_t(from) - 1); + roomChanges |= promoteReadMarker(firstWriter, rev_iter_t(from) - 1); qCDebug(MAIN) << "Auto-promoted read marker for" << firstWriter->id() << "to" << *q->readMarker(firstWriter); } updateUnreadCount(timeline.crbegin(), rev_iter_t(from)); + roomChanges |= Change::UnreadNotifsChange; } Q_ASSERT(timeline.size() == timelineSize + totalInserted); - return stateChanges; + return roomChanges; } void Room::Private::addHistoricalMessageEvents(RoomEvents&& events) @@ -1906,8 +1912,9 @@ Room::Changes Room::processStateEvent(const RoomEvent& e) ); } -void Room::processEphemeralEvent(EventPtr&& event) +Room::Changes Room::processEphemeralEvent(EventPtr&& event) { + Changes changes = NoChange; QElapsedTimer et; et.start(); if (auto* evt = eventCast<TypingEvent>(event)) { @@ -1946,7 +1953,7 @@ void Room::processEphemeralEvent(EventPtr&& event) continue; // FIXME, #185 auto u = user(r.userId); if (memberJoinState(u) == JoinState::Join) - d->promoteReadMarker(u, newMarker); + changes |= d->promoteReadMarker(u, newMarker); } } else { @@ -1963,7 +1970,7 @@ void Room::processEphemeralEvent(EventPtr&& event) auto u = user(r.userId); if (memberJoinState(u) == JoinState::Join && readMarker(u) == timelineEdge()) - d->setLastReadEvent(u, p.evtId); + changes |= d->setLastReadEvent(u, p.evtId); } } } @@ -1973,12 +1980,17 @@ void Room::processEphemeralEvent(EventPtr&& event) << evt->eventsWithReceipts().size() << "event(s) with" << totalReceipts << "receipt(s)," << et; } + return changes; } Room::Changes Room::processAccountDataEvent(EventPtr&& event) { + Changes changes = NoChange; if (auto* evt = eventCast<TagEvent>(event)) + { d->setTags(evt->tags()); + changes |= Change::TagsChange; + } if (auto* evt = eventCast<ReadMarkerEvent>(event)) { @@ -1986,10 +1998,9 @@ Room::Changes Room::processAccountDataEvent(EventPtr&& event) qCDebug(MAIN) << "Server-side read marker at" << readEventId; d->serverReadMarker = readEventId; const auto newMarker = findInTimeline(readEventId); - if (newMarker != timelineEdge()) - d->markMessagesAsRead(newMarker); - else - d->setLastReadEvent(localUser(), readEventId); + changes |= newMarker != timelineEdge() + ? d->markMessagesAsRead(newMarker) + : d->setLastReadEvent(localUser(), readEventId); } // For all account data events auto& currentData = d->accountData[event->matrixType()]; @@ -116,8 +116,9 @@ namespace QMatrixClient MembersChange = 0x80, EncryptionOn = 0x100, AccountDataChange = 0x200, - OtherChange = 0x1000, - AnyChange = 0x1FFF + ReadMarkerChange = 0x800, + OtherChange = 0x8000, + AnyChange = 0xFFFF }; Q_DECLARE_FLAGS(Changes, Change) Q_FLAG(Changes) @@ -459,7 +460,7 @@ namespace QMatrixClient protected: /// Returns true if any of room names/aliases has changed virtual Changes processStateEvent(const RoomEvent& e); - virtual void processEphemeralEvent(EventPtr&& event); + virtual Changes processEphemeralEvent(EventPtr&& event); virtual Changes processAccountDataEvent(EventPtr&& event); virtual void onAddNewTimelineEvents(timeline_iter_t /*from*/) { } virtual void onAddHistoricalTimelineEvents(rev_iter_t /*from*/) { } |