diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2021-11-21 06:55:09 +0100 |
---|---|---|
committer | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2021-11-21 07:07:00 +0100 |
commit | bf5f209d2d237301c65cc0973f1707b9386f3110 (patch) | |
tree | 17eadba44dd3c8950acb22169b66b3c10286984c /lib/room.cpp | |
parent | 52e640bce5a8931330fa6d653212e524e7baa2eb (diff) | |
download | libquotient-bf5f209d2d237301c65cc0973f1707b9386f3110.tar.gz libquotient-bf5f209d2d237301c65cc0973f1707b9386f3110.zip |
Room: isEventNotable, notificationFor, checkForNotifications
Room::isEventNotable has been moved out from Room::Private and made
compliant with MSC2654.
The concept of Room::checkForNotifications is taken from Quaternion
where a method with the same name has been in QuaternionRoom for a long
time - however, actual body is a stub for now, always returning
{ Notification::None } (Quaternion's implementation is too crude to be
taken to the library). Now we really need a pushrules processor to fill
this method with something reasonably good. Internally the library now
calls checkForNotifications() on every event added to the timeline,
filling up the events-to-notifications map because it is anticipated
that calculation of notifications can be rather resource-intensive and
should only be done once for a given event.
Finally, Room::notificationsFor is an accessor into the mentioned map,
standing next to isEventNotable (but unlike isEventNotable, it's not
virtual; checkForNotifications is).
Diffstat (limited to 'lib/room.cpp')
-rw-r--r-- | lib/room.cpp | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/lib/room.cpp b/lib/room.cpp index a2ec228a..67f65472 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -116,6 +116,7 @@ public: QHash<QPair<QString, QString>, RelatedEvents> relations; QString displayname; Avatar avatar; + QHash<QString, Notification> notifications; int highlightCount = 0; int notificationCount = 0; members_map_t membersMap; @@ -241,13 +242,6 @@ public: // return EventT::content_type() // } - bool isEventNotable(const TimelineItem& ti) const - { - return !ti->isRedacted() && ti->senderId() != connection->userId() - && is<RoomMessageEvent>(*ti) - && ti.viewAs<RoomMessageEvent>()->replacedEvent().isEmpty(); - } - template <typename EventArrayT> Changes updateStateFrom(EventArrayT&& events) { @@ -709,7 +703,7 @@ Room::Changes Room::Private::updateUnreadCount(const rev_iter_t& from, et.start(); const auto newUnreadMessages = count_if(from, to, - std::bind(&Room::Private::isEventNotable, this, _1)); + std::bind(&Room::isEventNotable, q, _1)); if (et.nsecsElapsed() > profilerMinNsecs() / 10) qCDebug(PROFILER) << "Counting gained unread messages in" << q->objectName() << "took" << et; @@ -742,7 +736,7 @@ Room::Changes Room::Private::recalculateUnreadCount(bool force) et.start(); unreadMessages = int(count_if(timeline.crbegin(), q->fullyReadMarker(), - [this](const auto& ti) { return isEventNotable(ti); })); + [this](const auto& ti) { return q->isEventNotable(ti); })); if (et.nsecsElapsed() > profilerMinNsecs() / 10) qCDebug(PROFILER) << "Recounting unread messages in" << q->objectName() << "took" << et; @@ -837,6 +831,28 @@ bool Room::canSwitchVersions() const return true; } +bool Room::isEventNotable(const TimelineItem &ti) const +{ + const auto& evt = *ti; + const auto* rme = ti.viewAs<RoomMessageEvent>(); + return !evt.isRedacted() + && (is<RoomTopicEvent>(evt) || is<RoomNameEvent>(evt) + || is<RoomAvatarEvent>(evt) || is<RoomTombstoneEvent>(evt) + || (rme && rme->msgtype() != MessageEventType::Notice + && rme->replacedEvent().isEmpty())) + && evt.senderId() != localUser()->id(); +} + +Notification Room::notificationFor(const TimelineItem &ti) const +{ + return d->notifications.value(ti->id()); +} + +Notification Room::checkForNotifications(const TimelineItem &ti) +{ + return { Notification::None }; +} + bool Room::hasUnreadMessages() const { return unreadCount() >= 0; } int Room::unreadCount() const { return d->unreadMessages; } @@ -1548,11 +1564,12 @@ Room::Private::moveEventsToTimeline(RoomEventsRange events, !eventsIndex.contains(eId), __FUNCTION__, makeErrorStr(*e, "Event is already in the timeline; " "incoming events were not properly deduplicated")); - if (placement == Older) - timeline.emplace_front(move(e), --index); - else - timeline.emplace_back(move(e), ++index); + const auto& ti = placement == Older + ? timeline.emplace_front(move(e), --index) + : timeline.emplace_back(move(e), ++index); eventsIndex.insert(eId, index); + if (auto n = q->checkForNotifications(ti); n.type != Notification::None) + notifications.insert(e->id(), n); Q_ASSERT(q->findInTimeline(eId)->event()->id() == eId); } const auto insertedSize = (index - baseIndex) * placement; |