-
Notifications
You must be signed in to change notification settings - Fork 380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSC2867: Marking rooms as unread #2867
Merged
Merged
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
fee6f86
marking rooms as unread
Bubu cf41881
Add alternative suggestion by @turt2live
Bubu 50308eb
mention that this msc lacks thread support
Bubu 30808e8
typo fix
Bubu 4fa6ed3
clarify type of notification we are referring to
Bubu f1db2b1
fix some small typos
anoadragon453 f897922
Update proposals/2867-rooms_marked_unread.md
Bubu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# MSC2867: Marking rooms as unread | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
There is currently no way to mark a room for later attention. A common use-case is receiving a | ||
notification on the go and opening the corresponding room but then deciding to deal with it at a later time. | ||
|
||
This MSC introduces an option to manually mark an room as *Unread*. | ||
|
||
In the above use-case the user would just mark the room as unread and when later opening a matrix | ||
client on their desktop PC that room would appear prominently in their room list waiting for attention. | ||
|
||
A related use-case solved by this proposal is wanting to mute a room's notifications while there's an | ||
ongoing discussion but still flag it for catching up later. | ||
|
||
Both WhatsApp and Telegram offer this functionality. | ||
|
||
## Proposal | ||
|
||
We add a [room account data](https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-user-userid-rooms-roomid-account-data-type) | ||
field `m.marked_unread` which just stores the following: | ||
|
||
```json | ||
{ | ||
"unread": true | false | ||
} | ||
``` | ||
|
||
When this is true a client should show the room with an indeterminate unread marker. This marker should | ||
be of similar visual importance to a non-highlight notification badge without the notification count. For example if | ||
you have a red circle with small numbers inside for counting notifications next to a room, then a room | ||
without notifications but marked as unread should have just the red circle. If a client gets new | ||
notifications after marking a room as unread the notification count should be displayed instead as normal. | ||
|
||
The `m.fully_read` marker should not be touched when marking a room as unread to keep the users read position | ||
in the room. | ||
|
||
Marking a room as read, if a client implements such a functionality, now involves sending a read receipt for the last | ||
event, as well as setting `m.marked_unread` to false. | ||
|
||
The unread flag should be cleared when opening the room again. | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Potential issues | ||
|
||
Client not aware of this feature will not clear the unread flag, when reading the room. In addition they'll obviously | ||
not show the room with a special badge. This seems preferable to the alternative of clearing the unread flag of a room | ||
without intending to because it didn't actually show up as unread. | ||
|
||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This proposal has no support for marking threads as unread, this should be handled in a future MSC. | ||
Bubu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Alternatives | ||
|
||
There are multiple possible alternatives here: | ||
|
||
* Marking individual messages as unread as discussed [here](https://github.com/matrix-org/matrix-doc/issues/2506): | ||
This is a far more complex feature that has possible interactions with server-side implementations and notification | ||
counts. This proposal aims to be a far more lightweight alternative. Looking at other messengers marking a room as | ||
unread is a more common operation than marking messages as unread, so it could be argued that others already found | ||
this to strike a good balance of complexity and use-cases covered. | ||
* Modifying the `m.fully_read` marker instead of introducing a new `m.marked_unread` field: | ||
Another idea was setting the `m.fully_read` marker to some earlier event which would then cause clients to show | ||
unread messages again. This has two problems: | ||
* It makes it harder to distinguish between rooms which happen to have unread messages that you don't necessarily | ||
care about and rooms which were manually marked as such and thus should be shown much more prominently. | ||
* When trying to work around this, by setting the marker at a special location like the room creation event, we completely | ||
lose the user's actual read position in a room whenever they use this feature. | ||
* Read receipts could be allowed to go "backwards" to restore notification | ||
counts, though this is likely to be riddled with bugs and unexpected | ||
behaviour for users. It's better for everyone to keep read receipts linearly | ||
progressing forwards. | ||
|
||
Bubu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
## Security considerations | ||
|
||
None. | ||
|
||
## Unstable prefix | ||
|
||
While this feature is not yet fully specced, implementers can use the `com.famedly.marked_unread` room | ||
account data type. | ||
|
||
Implementations using this unstable prefix in a released version should automatically migrate | ||
a users unread rooms to `m.marked_unread` when this is released as stable. | ||
This ensures the users unread rooms are not lost. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alphapapa says
My chief objection, again, is that there are already multiple criteria to apply to determine whether a room is "unread," and this proposal would make that more complicated, making a new criteria which may appear to conflict with existing ones, and bloat the spec by adding new metadata to offer a feature which could be offered using existing metadata.
I don't understand your question. I explained how it could work. Do you have a specific question about it?
Sure:
I think the non-fully-read marker would still work. In my client, both markers work (not that it's an easy concept for the user to grok).
That seems true. However, I would argue that, for that purpose, this proposal conflates two things: "unread" and "need to deal with something here later." Other systems, such as Slack, offer "save for later" and "remind me later" features that don't conflate "unread" with "task" or "remember this." Instead, they are offered as distinct actions in menus and distinct statuses, as well as distinct lists of unread channels and saved-for-later events.
So I would suggest, for that purpose, that a new proposal be written to offer a way to mark certain event IDs as "saved for later," "bookmarked," "to-do," etc. without having anything to do with "unread" status. The marked-for-later events could be displayed by a client when the user views the room, regardless of what other events have arrived since then. They could also be displayed in a global saved-for-later list across rooms.
Since message events can already be linked to by URL, this should be a natural way to remind the user about certain events in a room that are significant to the user. Also, it would effectively mirror the relevant features of Slack, which seems like a good idea anyway, if Matrix is to compete with it.
In contrast with this proposal, this alternative would enable more powerful features that would be worth "bloating the spec" for. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I've worked through the thread here, and I understand the concern that this could be implemented by moving back the read markers to some prior point to make it seem that the room is unread. I also understand that there's a separate related feature of "flag this room" or "flag these messages" for future reference feature.
I've tried to imagine how a typical client would implement this using read markers. The user story is presumably that they have opened a room (thus marking it as read), so their
m.read
will point to the most recent event, and them.fully_read
will either point to the most recent event (if less than a page of msgs has arrived since they last fully read the room), or some previous page.So, if the user manually marks the room as unread, it's not clear where the client should move the
m.read
andm.fully_read
markers to. For typical client UX, it's not an option to let users manually select which events they want to point the markers at (although it's cool that ement.el supports it) - typical users expect a "mark room as unread" button much as they'd get on WhatsApp or similar.The best I can come up with is that the client would have to remember and persist the value of
m.read
(andm.fully_read
, i guess) at the point of opening the unread room, and reset the markers to their previous values if the user subsequently marks the room as unread.This already feels quite fiddly for a client to manage. But for it to work in a predictable manner cross-device, you'd need to persist the previous read marker state somewhere shared between clients. That means either account_data, or possibly new read marker types (
m.old_read
andm.old_fully_read
or something). Otherwise if you try to mark a room as unread on a different client to the one where you read a room, it'll reset the read state to some irrelevant ancient place, which would be an unpleasantly broken UX.At this point, the implementation complexity (including storing state on the server to synchronise between clients) feels at least as fiddly than the "check for
m.marked_unread
in room account_data" logic proposed in the original MSC. Yes, it's an additional check to apply, but semantically it preserves the actual data of where the user has really read up to (rather than discarding it), and it avoids the implementer having to wrestle with deciding where to move read markers to. Especially given how error-prone moving read-markers are, as we've seen with stuck notifications.So, i'm afraid my inclination is to go with the proposed MSC. I'll point the rest of the SCT at this thread to encourage them to reconsider their FCP checkboxes if necessary though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to parse the thread to figure out whether the goal is to reverse
m.fully_read
orm.read
, but I don't think either option works:Receipts (
m.read
) are currently not reversible. Making them reversible would be very complicated on the server side, which is why it's not considered an option. This is already mentioned in the alternatives section.As for
m.fully_read
: it does not affect whether a room is read (at least in most clients). AFAIK the goal ofm.fully_read
is to allow users to keep their scrollback position even after marking a room as read, which is incompatible with using it to determine if a room is unread.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discord has only the feature to "mark as unread from this message on" and not "mark this room as unread". The feature does make sense on Discord and that platform can be known for having a lot of chats and a lot of messages, and we do want to enable these use cases on Matrix. If the conversation is very long, it makes sense to be able to jump to the first message that you need to read, whether it is because you haven't seen it yet, or because you accidentally opened the conversation and then marked it as unread, or because you intend to return to it again. Here is a video demonstrating the feature: https://www.youtube.com/watch?v=rX9cOGFrzMQ.
On the other hand, simpler clients such as Signal, WhatsApp etc only allow you to mark a whole conversation as unread (as described in the MSC itself):
In the case of Discord, the clients make no distinction between "unread messages that you don't necessarily care about and rooms which were manually marked as such", and I don't think such distinction is necessary to show.
That being said, as a user, I'd really like to see this feature at all on the spec and ultimately on clients, but I don't feel inclined much towards either option as long as the feature lands without having to wait more years.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tulir What is the use of being able to keep your scrollback position on a room that you've already read? Are there any clients currently implementing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's implemented in some Elements at least, it can simultaneously enable three things:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several clients already implement "fully read" markers according to the spec, which is what tulir is describing. Reference: https://spec.matrix.org/v1.10/client-server-api/#fully-read-markers
m.read
is a read receipt and has a specific protocol function relating to notifications.m.fully_read
is a user-only read marker to help the user understand where they last left off, regardless of their notification count/involvement in the room. The fully read marker in Element will be the green bar across the timeline, or the "jump up" button if the green line would not be shown to the user if rendered.This distinction is meant to provide the user with a better experience for managing unseen vs unread messages, and it's very unfortunate that the technical level has been made confused by using extremely similar terminology for both.
For this thread, if commenters could be careful to use "marker" and "receipt" appropriately, it would be appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ara4n Thanks for your considered reply. I understand why you don't think using the markers/receipts is a good way to implement this feature. I'd still suggest implementing something a bit more flexible and robust, more similar to Slack's features, than to implement this proposal, because this one seems like something less than a 50% solution to those features, which I think are needed for Matrix to be competitive; and if this were implemented first, it would mean clients' having to support a kind of "legacy" implementation as well as a more robust one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conversely, this feature has been asked for for years and while simple, I think it covers the majority of use cases. I vote for getting this in to people's hands. In the future we can always migrate to something more powerful if that ends up being warranted.
aka. let's avoid letting perfect be the enemy of good and iterate instead of blocking further.