Since the unread notification count does not consider threads, a client is unable to separate the unread message counts into threads (as defined by MSC3440) without iterating over every missing message. Without this, clients are unable to:
- Let users know that a thread has new messages since they last read it.
- Accurately display a count of unread messages in a room (or a thread).
When an event which is part of a thread matches a push rule which results in a
notify
action then the homeserver should partition the resulting notification
count per-thread. (This is needed for the
proposed /sync
changes).
It is recommended that at least 3 relations are traversed when attempting to find a thread, implementations should be careful to not infinitely recurse.1
Similar behavior should be applied for an event which results in notify
action
with a highlight
tweak set.
This MSC does not propose any changes to the payload sent to push gateways.
Threaded clients can opt into receiving unread thread notifications by passing
a new unread_thread_notifications
parameter
as part of the RoomEventFilter
.
(This is similar to lazy_load_members
,
but only applies to the /sync
endpoint.):
unread_thread_notifications
: Iftrue
, enables partitioning of unread notification counts by thread. Defaults to false.
If this flag is set to true
, for each "Joined Room" in the /sync
response
a new field is added:
unread_thread_notifications
: Counts of unread thread notifications for this room, an object which maps thread ID (the parent event ID) toUnread Notification Counts
.
Additionally, the unread_notifications
dictionary is modified to only include
unread notifications from events which are not part of a thread.
An example of a joined room from a sync response:
{
"account_data": {
// ...
},
"ephemeral": {
// ...
},
"state": {
// ...
},
"summary": {
// ...
},
"timeline": {
"events": [
{
"event_id": "$143273582443PhrSn:example.org",
// other fields ...
},
{
"event_id": "$SGNxGPGUopcPBUoTTL:example.org",
"m.relates_to": {
"event_id": "$143273582443PhrSn:example.org",
"rel_type": "m.thread"
}
// other fields ...
}
]
},
"unread_notifications": {
"highlight_count": 2,
"notification_count": 18
},
"unread_thread_notifications": {
"$143273582443PhrSn:example.org": {
"highlight_count": 0,
"notification_count": 1
}
}
}
Rooms with many unread threads could cause some downsides:
- The size of the
/sync
response would increase without bound. - The effort to generate and process the receipts for each room would increase without bound.
This is not dissimilar to rooms which are never read, however, as their unread
counts are continually tracked and returned as part of the /sync
response.
This MSC does not attempt to modify how unread notifications (for a thread or otherwise) are cleared. It currently assumes the rules set forth by read receipts still apply. This will cause some flakiness with unread notifications, as the current receipt infrastructure assumes that a room's timeline is linear, which is no longer true.
MSC3771 is a potential solution for this.
It might seem that a new push rule action
(or tweak
) should be used to control
the behavior of whether an event generates a notification for a thread or the
room itself. There are issues with either approach though:
A new action
(e.g. notify_thread
) would mean that additional logic would
need to be defined and added for events which aren't part of a thread but attempt
to use this action. It also conflicts with MSC3768,
which attempts to define another action
which should also work fine for threads.
A new tweak
(e.g. threaded
) was discarded as an option since there is no need to
pass this through to the push server, which is at odds with the current tweaks
mechanism.
Regardless, the main issue with using push rules is that it becomes necessary to define rules which match threaded events. Whenever adding a new rule, matching rules would need to be added, but as a thread-specific version.
N/A
While this feature is in development the following unstable prefixes should be used:
unread_thread_notifications
-->org.matrix.msc3773.unread_thread_notifications
To detect server support, clients can either rely on the spec version (when stable)
or the presence of a org.matrix.msc3773
flag in unstable_features
on /versions
.
N/A
Footnotes
-
Three relations is relatively arbitrary, but is meant to cover an edit or reaction to a thread (to an event with no relations, i.e. the root of a thread):
A<--[m.thread]--B<--[m.annotation]--C
. With an additional leftover for future improvements. This is considered reasonable since threads cannot fork, edits cannot modify relation information, and generally annotations to annotations are ignored by user interfaces. ↩