aboutsummaryrefslogtreecommitdiff
path: root/lib/room.cpp
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-21 06:55:09 +0100
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-21 07:07:00 +0100
commitbf5f209d2d237301c65cc0973f1707b9386f3110 (patch)
tree17eadba44dd3c8950acb22169b66b3c10286984c /lib/room.cpp
parent52e640bce5a8931330fa6d653212e524e7baa2eb (diff)
downloadlibquotient-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.cpp43
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;