From beda89edc28e6a3a631677d82d95c54b5ccfa548 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 13 Oct 2021 17:22:06 +0100 Subject: [PATCH 01/72] Threading via relation --- proposals/3440-threading-via-relations.md | 162 ++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 proposals/3440-threading-via-relations.md diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md new file mode 100644 index 00000000000..5cb79a5eb4b --- /dev/null +++ b/proposals/3440-threading-via-relations.md @@ -0,0 +1,162 @@ +# MSC3440 Threading via `m.thread` relation + +## Problem + +Threading is a great way to create alternative timelines to group messages related to each other. This is particularly useful in high traffic rooms where multiple conversations can happen in parallel or when a single discussion might stretch over a very long period of time. + +The main goal when implementing threads is to create conversations that are easier to follow and smoother to read. + +There have been several experiments in threading for Matrix... + + - [MSC2326](https://github.com/matrix-org/matrix-doc/pull/2326): Label based filtering + - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): Threading by serverside traversal of relationships + - "Threads as rooms" + +...but none have yet been widely adopted due to the upheaval of implementing an entirely new Client-Server API construct in the core message sending/display path. + +Meanwhile, threading is very clearly a core requirement for any modern messaging solution, and Matrix uptake is suffering due to the lack of progress. + +## Proposal + +### Event format + +A new relation would be used to express that an event belongs to a thread. + +```json +"m.relates_to": { + "rel_type": "m.thread", + "event_id": "$thread_root" +} +``` +Where $thread_root is the event ID of the root message in the thread. + +A big advantage of relations over quote replies is that they can be server-side aggregated. It means that a client is not bound to download the entire history of a room to have a comprehensive list of events being part of a thread. + +It will have a custom aggregation which is a summary of the thread: the latest message, a list of participants and the total count of messages. I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root would include additional information in the `unsigned` field: + +```json +{ + "latest_event": { + "content": { ... }, + ... + }, + "senders": ["@john:example.com", ...], + "count": 7 +} +``` + +#### Quote replies in a thread + +No recommendation to modifying quote replies is made, this would still be handled via the `m.in_reply_to` field of `m.relates_to`. Thus you could quote a reply in a thread: + +```json +"m.relates_to": { + "rel_type": "m.thread", + "event_id": "$thread_root", + "m.in_reply_to": { + "event_id": "$event_target" + } +} +``` + +### Fetch all replies to a thread + +To fetch an entire thread, the `/relations` API can be used as defined in [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) + +``` +GET /_matrix/client/unstable/rooms/!room_id:domain/relations/$thread_root/m.thread +``` + +Where `$thread_root` is the event ID of the root message in the thread. + +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) would need to be clarified to ensure that returned messages include any bundled relations necessary for displaying the thread, e.g. reactions to the threaded events. + +### Fetch all threads in a room + +To fetch all threads in a room it is proposed to use the [`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) API and expand the room event filtering to include relations. The `RoomEventFilter` will take additional parameters: + +* `relation_types`: A list of relation types which must be bundled with the event to include it. If this list is absent then no filtering is done on relation types. +* `relation_senders`: A list of senders of relations... + +This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). + +``` +GET /_matrix/client/unstable/rooms/!room_id:domain/messages/filter=... +``` + +Where filter would be JSON and URL-encoded string include the above new fields: + +```json +{ + "types": ["m.room.message"], + "relation_senders": [...], + "relation_types": ["m.thread"] +} +``` + +### Limitations + +#### Read receipts + +Read receipts and read markers assume a single chronological timeline. Threading changes that assumption making the current API not very practical. + +Clients can synthetize read receipts but it is possible that some notification get lost upon a fresh start where the clients have to start off the `m.read` information received from the homeserver. + +Synchronising the synthesized notification count across devices will present its own challenges and is probably undesirable at this stage. The preferred route would be to create another MSC to make read receipts support multiple timelines in a single room. + +#### Single-layer event aggration + +Bundling only includes relations a single-layer deep, so it might return an event with `m.thread` relation, the `m.annotation` to that event and the `m.reference` relations to that event, but not the `m.annotation` to the `m.reference`. + +### Client considerations + +#### Display "m.thread" as "m.in_reply_to" + +It is possible for clients to provide a backwards compatible experience for users by treating the new relation `m.thread` the same way they would treat a `m.in_reply_to` event. + +Failing to do the above will still render the event in the room. It might create a disjointed experience as events might lack the original context for correct understanding. + +#### Sending `m.thread` before fully implementing threads + +To ensure maximum compability and continuity in the conversation it is recommend for clients who do not fully support threads yet to adapt the `m.relates_to` body to use the `m.thread` relation type when replying to a threaded event. + +This will help threads enabled clients to render the event in the place that gives the maximum context to the users. + +As a fallback, it is recommended that clients make clicking on a quote reply related to a threaded event open that thread and highlight the corresponding event + +## Alternatives + +[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", building on `m.in_reply_to` are the main alternatives here. The first two are non-overlapping with this MSC. + +### Threads as rooms + +The provides full server-side APIs for navigating trees of events, and could be considered an extension of this MSC for scenarios which require that capability (e.g. Twitter-style microblogging as per [Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), or building an NNTP or IMAP or Reddit style threaded UI) + +"Threads as rooms" is the idea that each thread could just get its own Matrix room in parallel with the one which spawned the thread. + +Advantages to "Threads as rooms" include: + * May be simpler for client implementations. + * Also requires minimal Client-Server API changes + +Disadvantages include: + * Access control, membership, history visibility, room versions etc needs to be synced between the thread-room and the parent room + * Harder to control lifetime of threads in the context of the parent room if they're completely split off + * Clients which aren't aware of them are going to fill up with a lot of rooms. + * Bridging to non-threaded chat systems is trickier as you may have to splice together rooms + * The sheer number of rooms involved probably makes it dependent on `/sync` v3 landing (the to-be-specced next generation of `/sync` which is constant-time complexity with your room count). + +### Threads via m.in_reply_to + +The rationale for using a new relation type instead of building on `m.in_reply_to` is to re-use the event relationship APIs provided by [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675). The MSC3267 definition of `m.reference` relationships could be updated to mention threads (perhaps by using the key field from [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) as the thread ID), but it is clearer to define a new relation type. It is unclear what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), but that is unimplemented by clients. + +## Security considerations + +None + +## Unstable prefix + +Clients and servers should use list of unstable prefixes listed below while this MSC has not been included in a spec release. + + * `io.element.thread` should be used in place of `m.thread` as relation type + * `io.element.relation_senders` should be used in place of `relation_senders` in the `RoomEventFilter` + * `io.element.relation_types` should be used in place of `relation_types` in the `RoomEventFilter` \ No newline at end of file From 2fa27ac2641119963c7375318fea1219a22a13f7 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 18 Oct 2021 09:43:07 +0100 Subject: [PATCH 02/72] Add explainer on how to handle m.in_reply_to --- proposals/3440-threading-via-relations.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 5cb79a5eb4b..c515465b024 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -59,6 +59,10 @@ No recommendation to modifying quote replies is made, this would still be handle } ``` +It is possible that an `m.in_reply_to` event targets an event that is outside the +related thread. Clients should always do their upmost to display the quote-reply +and upon clicking it the event should be displayed and highlighted in its original context. + ### Fetch all replies to a thread To fetch an entire thread, the `/relations` API can be used as defined in [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) @@ -114,7 +118,7 @@ Bundling only includes relations a single-layer deep, so it might return an even It is possible for clients to provide a backwards compatible experience for users by treating the new relation `m.thread` the same way they would treat a `m.in_reply_to` event. -Failing to do the above will still render the event in the room. It might create a disjointed experience as events might lack the original context for correct understanding. +Failing to do the above should still render the event in the room's timeline. It might create a disjointed experience as events might lack the original context for correct understanding. #### Sending `m.thread` before fully implementing threads From d8a0a94c975f9be338a8aea4cf919557d574ae48 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 18 Oct 2021 13:32:22 +0100 Subject: [PATCH 03/72] Clarify wording on threading MSC --- proposals/3440-threading-via-relations.md | 73 +++++++++++++++++++++-- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index c515465b024..4441914f14c 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -30,9 +30,14 @@ A new relation would be used to express that an event belongs to a thread. ``` Where $thread_root is the event ID of the root message in the thread. -A big advantage of relations over quote replies is that they can be server-side aggregated. It means that a client is not bound to download the entire history of a room to have a comprehensive list of events being part of a thread. +A big advantage of relations over quote replies is that they can be server-side +aggregated. It means that a client is not bound to download the entire history of +a room to have a comprehensive list of events being part of a thread. -It will have a custom aggregation which is a summary of the thread: the latest message, a list of participants and the total count of messages. I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root would include additional information in the `unsigned` field: +When a thread head is aggregated (as in MSC2675), returns a summary of the thread: +the latest message, a list of participants and the total count of messages. +I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), +the thread root would include additional information in the `unsigned` field: ```json { @@ -110,7 +115,46 @@ Synchronising the synthesized notification count across devices will present its #### Single-layer event aggration -Bundling only includes relations a single-layer deep, so it might return an event with `m.thread` relation, the `m.annotation` to that event and the `m.reference` relations to that event, but not the `m.annotation` to the `m.reference`. +Bundling only includes relations a single-layer deep. Given the following list of +events, `ev4` would not be returned as it isn't a direct reference to `ev1`. + +``` +[ + { + "event_id": "ev1", + ... + }, + { + "event_id": "ev2", + ... + "m.relates_to": { + "rel_type": "m.thread", + "event_id": "ev1", + "m.in_reply_to": { + "event_id": "ev1" + } + } + }, + { + "event_id": "ev3", + ... + "m.relates_to": { + "rel_type": "m.annotation", + "event_id": "ev1", + "key": "✅" + } + }, + { + "event_id": "ev4", + ... + "m.relates_to": { + "rel_type": "m.annotation", + "event_id": "ev1", + "key": "❎" + } + } +] +``` ### Client considerations @@ -122,11 +166,28 @@ Failing to do the above should still render the event in the room's timeline. It #### Sending `m.thread` before fully implementing threads -To ensure maximum compability and continuity in the conversation it is recommend for clients who do not fully support threads yet to adapt the `m.relates_to` body to use the `m.thread` relation type when replying to a threaded event. +Clients that do not support threads yet should include a `m.thread` relation to the +event body if a user is replying to an event that has an `m.thread` relation type + +This is done so that clients that support threads can render the event in the most +relevant context. + +If a client does not include that relation type to the outgoing event, it will be +rendered in the room timeline with a quote reply that should open and highlight the +event in the thread context when clicked. -This will help threads enabled clients to render the event in the place that gives the maximum context to the users. +When replying to the following event, a client that does not support thread should +copy in `rel_type` and `event_id` properties in their reply mixin. -As a fallback, it is recommended that clients make clicking on a quote reply related to a threaded event open that thread and highlight the corresponding event +``` +{ + ... + "m.relates_to": { + "rel_type": "m.thread", + "event_id": "ev1" + } +} +``` ## Alternatives From 7d3988758ab686ffc54c82b1fe222bf6602aeb7d Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 18 Oct 2021 13:37:26 +0100 Subject: [PATCH 04/72] Mention MSC3051 in the alternative section of MSC3440 --- proposals/3440-threading-via-relations.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 4441914f14c..846fa419ab1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -191,7 +191,12 @@ copy in `rel_type` and `event_id` properties in their reply mixin. ## Alternatives -[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", building on `m.in_reply_to` are the main alternatives here. The first two are non-overlapping with this MSC. +[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", +building on `m.in_reply_to` are the main alternatives here. The first two are +non-overlapping with this MSC. + +It is also worth noting that relations in this MSC could be expressed using the +scalable relation format described in [MSC3051](https://github.com/matrix-org/matrix-doc/pull/3051). ### Threads as rooms From 6e37911fd5c8ae5aa8aea14a51cd1eb37a962fea Mon Sep 17 00:00:00 2001 From: Germain Date: Mon, 18 Oct 2021 14:26:02 +0100 Subject: [PATCH 05/72] Clarify updates to MSC2675 for MSC3440 Co-authored-by: Patrick Cloke --- proposals/3440-threading-via-relations.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 846fa419ab1..75a638409d5 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -78,7 +78,9 @@ GET /_matrix/client/unstable/rooms/!room_id:domain/relations/$thread_root/m.thre Where `$thread_root` is the event ID of the root message in the thread. -[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) would need to be clarified to ensure that returned messages include any bundled relations necessary for displaying the thread, e.g. reactions to the threaded events. +In order to properly display a thread it is necessary to retrieve the relations to threaded events, e.g. the reactions to the threaded events. This proposes clarifying [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) that the `/relations` API includes bundled relations. This follows what MSC2675 already describes: + +> Any API which receives events should bundle relations (apart from non-gappy incremental syncs), for instance: initial sync, gappy incremental sync, /messages and /context. ### Fetch all threads in a room From c142b17bdc9f18cfb272bf46d49d6223e867b485 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 18 Oct 2021 14:35:17 +0100 Subject: [PATCH 06/72] Line wrap the MSC --- proposals/3440-threading-via-relations.md | 86 +++++++++++++++++------ 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 75a638409d5..adf610eaf05 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -2,9 +2,13 @@ ## Problem -Threading is a great way to create alternative timelines to group messages related to each other. This is particularly useful in high traffic rooms where multiple conversations can happen in parallel or when a single discussion might stretch over a very long period of time. +Threading is a great way to create alternative timelines to group messages related +to each other. This is particularly useful in high traffic rooms where multiple +conversations can happen in parallel or when a single discussion might stretch +over a very long period of time. -The main goal when implementing threads is to create conversations that are easier to follow and smoother to read. +The main goal when implementing threads is to create conversations that are easier +to follow and smoother to read. There have been several experiments in threading for Matrix... @@ -12,9 +16,11 @@ There have been several experiments in threading for Matrix... - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): Threading by serverside traversal of relationships - "Threads as rooms" -...but none have yet been widely adopted due to the upheaval of implementing an entirely new Client-Server API construct in the core message sending/display path. +...but none have yet been widely adopted due to the upheaval of implementing an +entirely new Client-Server API construct in the core message sending/display path. -Meanwhile, threading is very clearly a core requirement for any modern messaging solution, and Matrix uptake is suffering due to the lack of progress. +Meanwhile, threading is very clearly a core requirement for any modern messaging +solution, and Matrix uptake is suffering due to the lack of progress. ## Proposal @@ -52,7 +58,8 @@ the thread root would include additional information in the `unsigned` field: #### Quote replies in a thread -No recommendation to modifying quote replies is made, this would still be handled via the `m.in_reply_to` field of `m.relates_to`. Thus you could quote a reply in a thread: +No recommendation to modifying quote replies is made, this would still be handled +via the `m.in_reply_to` field of `m.relates_to`. Thus you could quote a reply in a thread: ```json "m.relates_to": { @@ -70,7 +77,8 @@ and upon clicking it the event should be displayed and highlighted in its origin ### Fetch all replies to a thread -To fetch an entire thread, the `/relations` API can be used as defined in [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) +To fetch an entire thread, the `/relations` API can be used as defined in +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) ``` GET /_matrix/client/unstable/rooms/!room_id:domain/relations/$thread_root/m.thread @@ -78,18 +86,28 @@ GET /_matrix/client/unstable/rooms/!room_id:domain/relations/$thread_root/m.thre Where `$thread_root` is the event ID of the root message in the thread. -In order to properly display a thread it is necessary to retrieve the relations to threaded events, e.g. the reactions to the threaded events. This proposes clarifying [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) that the `/relations` API includes bundled relations. This follows what MSC2675 already describes: +In order to properly display a thread it is necessary to retrieve the relations +to threaded events, e.g. the reactions to the threaded events. This proposes +clarifying [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) that +the `/relations` API includes bundled relations. This follows what MSC2675 already describes: -> Any API which receives events should bundle relations (apart from non-gappy incremental syncs), for instance: initial sync, gappy incremental sync, /messages and /context. +> Any API which receives events should bundle relations (apart from non-gappy +incremental syncs), for instance: initial sync, gappy incremental sync, +/messages and /context. ### Fetch all threads in a room -To fetch all threads in a room it is proposed to use the [`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) API and expand the room event filtering to include relations. The `RoomEventFilter` will take additional parameters: +To fetch all threads in a room it is proposed to use the +[`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) +API and expand the room event filtering to include relations. The `RoomEventFilter` +will take additional parameters: -* `relation_types`: A list of relation types which must be bundled with the event to include it. If this list is absent then no filtering is done on relation types. +* `relation_types`: A list of relation types which must be bundled with the event +to include it. If this list is absent then no filtering is done on relation types. * `relation_senders`: A list of senders of relations... -This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). +This can also be combined with the `sender` field to search for threads which a +user has participated in (or not participated in). ``` GET /_matrix/client/unstable/rooms/!room_id:domain/messages/filter=... @@ -162,9 +180,12 @@ events, `ev4` would not be returned as it isn't a direct reference to `ev1`. #### Display "m.thread" as "m.in_reply_to" -It is possible for clients to provide a backwards compatible experience for users by treating the new relation `m.thread` the same way they would treat a `m.in_reply_to` event. +It is possible for clients to provide a backwards compatible experience for users +by treating the new relation `m.thread` the same way they would treat a `m.in_reply_to` event. -Failing to do the above should still render the event in the room's timeline. It might create a disjointed experience as events might lack the original context for correct understanding. +Failing to do the above should still render the event in the room's timeline. +It might create a disjointed experience as events might lack the original context +for correct understanding. #### Sending `m.thread` before fully implementing threads @@ -202,24 +223,40 @@ scalable relation format described in [MSC3051](https://github.com/matrix-org/ma ### Threads as rooms -The provides full server-side APIs for navigating trees of events, and could be considered an extension of this MSC for scenarios which require that capability (e.g. Twitter-style microblogging as per [Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), or building an NNTP or IMAP or Reddit style threaded UI) +The provides full server-side APIs for navigating trees of events, and could be +considered an extension of this MSC for scenarios which require that capability +(e.g. Twitter-style microblogging as per [Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), +or building an NNTP or IMAP or Reddit style threaded UI) -"Threads as rooms" is the idea that each thread could just get its own Matrix room in parallel with the one which spawned the thread. +"Threads as rooms" is the idea that each thread could just get its own Matrix room +in parallel with the one which spawned the thread. Advantages to "Threads as rooms" include: * May be simpler for client implementations. * Also requires minimal Client-Server API changes Disadvantages include: - * Access control, membership, history visibility, room versions etc needs to be synced between the thread-room and the parent room - * Harder to control lifetime of threads in the context of the parent room if they're completely split off + * Access control, membership, history visibility, room versions etc needs to be + synced between the thread-room and the parent room + * Harder to control lifetime of threads in the context of the parent room if + they're completely split off * Clients which aren't aware of them are going to fill up with a lot of rooms. - * Bridging to non-threaded chat systems is trickier as you may have to splice together rooms - * The sheer number of rooms involved probably makes it dependent on `/sync` v3 landing (the to-be-specced next generation of `/sync` which is constant-time complexity with your room count). + * Bridging to non-threaded chat systems is trickier as you may have to splice + together rooms + * The sheer number of rooms involved probably makes it dependent on `/sync` v3 + landing (the to-be-specced next generation of `/sync` which is constant-time + complexity with your room count). ### Threads via m.in_reply_to -The rationale for using a new relation type instead of building on `m.in_reply_to` is to re-use the event relationship APIs provided by [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675). The MSC3267 definition of `m.reference` relationships could be updated to mention threads (perhaps by using the key field from [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) as the thread ID), but it is clearer to define a new relation type. It is unclear what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), but that is unimplemented by clients. +The rationale for using a new relation type instead of building on `m.in_reply_to` +is to re-use the event relationship APIs provided by +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675). The MSC3267 definition +of `m.reference` relationships could be updated to mention threads (perhaps by +using the key field from [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) +as the thread ID), but it is clearer to define a new relation type. It is unclear +what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), +but that is unimplemented by clients. ## Security considerations @@ -227,8 +264,11 @@ None ## Unstable prefix -Clients and servers should use list of unstable prefixes listed below while this MSC has not been included in a spec release. +Clients and servers should use list of unstable prefixes listed below while this +MSC has not been included in a spec release. * `io.element.thread` should be used in place of `m.thread` as relation type - * `io.element.relation_senders` should be used in place of `relation_senders` in the `RoomEventFilter` - * `io.element.relation_types` should be used in place of `relation_types` in the `RoomEventFilter` \ No newline at end of file + * `io.element.relation_senders` should be used in place of `relation_senders` + in the `RoomEventFilter` + * `io.element.relation_types` should be used in place of `relation_types` + in the `RoomEventFilter` \ No newline at end of file From c578f75b999beffc9647cbdb32b017d351689785 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 18 Oct 2021 14:36:34 +0100 Subject: [PATCH 07/72] More line wrapping for MSC3440 --- proposals/3440-threading-via-relations.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index adf610eaf05..61ce5581e1a 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -12,8 +12,10 @@ to follow and smoother to read. There have been several experiments in threading for Matrix... - - [MSC2326](https://github.com/matrix-org/matrix-doc/pull/2326): Label based filtering - - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): Threading by serverside traversal of relationships + - [MSC2326](https://github.com/matrix-org/matrix-doc/pull/2326): + Label based filtering + - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): + Threading by serverside traversal of relationships - "Threads as rooms" ...but none have yet been widely adopted due to the upheaval of implementing an @@ -42,8 +44,9 @@ a room to have a comprehensive list of events being part of a thread. When a thread head is aggregated (as in MSC2675), returns a summary of the thread: the latest message, a list of participants and the total count of messages. -I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), -the thread root would include additional information in the `unsigned` field: +I.e. in places which include bundled relations (per +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root +would include additional information in the `unsigned` field: ```json { @@ -127,11 +130,17 @@ Where filter would be JSON and URL-encoded string include the above new fields: #### Read receipts -Read receipts and read markers assume a single chronological timeline. Threading changes that assumption making the current API not very practical. +Read receipts and read markers assume a single chronological timeline. Threading +changes that assumption making the current API not very practical. -Clients can synthetize read receipts but it is possible that some notification get lost upon a fresh start where the clients have to start off the `m.read` information received from the homeserver. +Clients can synthetize read receipts but it is possible that some notification get +lost upon a fresh start where the clients have to start off the `m.read` +information received from the homeserver. -Synchronising the synthesized notification count across devices will present its own challenges and is probably undesirable at this stage. The preferred route would be to create another MSC to make read receipts support multiple timelines in a single room. +Synchronising the synthesized notification count across devices will present its +own challenges and is probably undesirable at this stage. The preferred route +would be to create another MSC to make read receipts support multiple timelines +in a single room. #### Single-layer event aggration From 33acdf40fbe3a7ccbf4bd6b3b2202095e4dd79ba Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 25 Oct 2021 15:23:22 +0100 Subject: [PATCH 08/72] Clarify single-layer event aggregation section --- proposals/3440-threading-via-relations.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 61ce5581e1a..3c501b546ad 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -144,8 +144,13 @@ in a single room. #### Single-layer event aggration -Bundling only includes relations a single-layer deep. Given the following list of -events, `ev4` would not be returned as it isn't a direct reference to `ev1`. +Bundling only includes relations a single-layer deep. This MSC is not looking to +solve nested threading but is rather focusing on bringing mechanisms to allow +threading in chat applications + +Nested threading is out of scope for this proposal and would be the subject of +a different MSC. +A `m.thread` event can only reference events that do not have a `rel_type` ``` [ @@ -172,19 +177,13 @@ events, `ev4` would not be returned as it isn't a direct reference to `ev1`. "event_id": "ev1", "key": "✅" } - }, - { - "event_id": "ev4", - ... - "m.relates_to": { - "rel_type": "m.annotation", - "event_id": "ev1", - "key": "❎" - } } ] ``` +Given the above list of events, only `ev1` would be a valid target for an `m.thread` +relation event. + ### Client considerations #### Display "m.thread" as "m.in_reply_to" From 7102165e5ad2ce01a09c31aaed11294263dee4c5 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 25 Oct 2021 15:41:22 +0100 Subject: [PATCH 09/72] Update thread-as-rooms advantages --- proposals/3440-threading-via-relations.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 3c501b546ad..42b36e7d1d1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -18,9 +18,6 @@ There have been several experiments in threading for Matrix... Threading by serverside traversal of relationships - "Threads as rooms" -...but none have yet been widely adopted due to the upheaval of implementing an -entirely new Client-Server API construct in the core message sending/display path. - Meanwhile, threading is very clearly a core requirement for any modern messaging solution, and Matrix uptake is suffering due to the lack of progress. @@ -236,12 +233,12 @@ considered an extension of this MSC for scenarios which require that capability (e.g. Twitter-style microblogging as per [Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), or building an NNTP or IMAP or Reddit style threaded UI) -"Threads as rooms" is the idea that each thread could just get its own Matrix room -in parallel with the one which spawned the thread. +"Threads as rooms" is the idea that each thread could just get its own Matrix room.. Advantages to "Threads as rooms" include: * May be simpler for client implementations. - * Also requires minimal Client-Server API changes + * Restricting events visiblity as the room creator + * Ability to create read-only threads Disadvantages include: * Access control, membership, history visibility, room versions etc needs to be From f84f949b5893d467e975226a2d0f704ca58a95dd Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 17 Nov 2021 11:00:56 +0000 Subject: [PATCH 10/72] Clarify backwards compatibility and incremental support --- proposals/3440-threading-via-relations.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 42b36e7d1d1..44070370a36 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -185,12 +185,16 @@ relation event. #### Display "m.thread" as "m.in_reply_to" -It is possible for clients to provide a backwards compatible experience for users -by treating the new relation `m.thread` the same way they would treat a `m.in_reply_to` event. +Clients that don't support threads will render threaded messages in the room's +timeline at the point at which they were sent. This does risk a confusing experience +for those on such clients, but options to mitigate this are limited. -Failing to do the above should still render the event in the room's timeline. -It might create a disjointed experience as events might lack the original context -for correct understanding. +Having older clients treat threaded messages as replies would give a better +experience, but adding reply metadata in addition to thread metadata would mean +replies could not then be used in threads and would be significant extra metadata. + +Clients that wish to offer basic thread support can display threads as replies to +the thread root message. See matrix-org/matrix-react-sdk#7109 for an example. #### Sending `m.thread` before fully implementing threads From f02dc8d78117b6bc0f41f20673a81ae127931228 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 17 Nov 2021 11:09:34 +0000 Subject: [PATCH 11/72] Clarify wording and correct typos --- proposals/3440-threading-via-relations.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 44070370a36..07e3883b0da 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -51,7 +51,6 @@ would include additional information in the `unsigned` field: "content": { ... }, ... }, - "senders": ["@john:example.com", ...], "count": 7 } ``` @@ -102,18 +101,20 @@ To fetch all threads in a room it is proposed to use the API and expand the room event filtering to include relations. The `RoomEventFilter` will take additional parameters: -* `relation_types`: A list of relation types which must be bundled with the event -to include it. If this list is absent then no filtering is done on relation types. -* `relation_senders`: A list of senders of relations... +* `relation_types`: A list of relation types which must be exist pointing to the event + being filtered. If this list is absent then no filtering is done on relation types. +* `relation_senders`: A list of senders of relations which must be exist pointing to + the event being filtered. If this list is absent then no filtering is done on relation types. This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). ``` -GET /_matrix/client/unstable/rooms/!room_id:domain/messages/filter=... +GET /_matrix/client/unstable/rooms/!room_id:domain/messages?filter=... ``` -Where filter would be JSON and URL-encoded string include the above new fields: +The filter string would include the new fields, above. In this example, the URL +encoded JSON is presented unencoded and formatted for legibility: ```json { @@ -130,7 +131,7 @@ Where filter would be JSON and URL-encoded string include the above new fields: Read receipts and read markers assume a single chronological timeline. Threading changes that assumption making the current API not very practical. -Clients can synthetize read receipts but it is possible that some notification get +Clients can synthetize read receipts but it is possible that some notifications get lost upon a fresh start where the clients have to start off the `m.read` information received from the homeserver. From 3e46728b29d45de2063b7fe978a31f6f0add2c8c Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 17 Nov 2021 14:54:57 +0000 Subject: [PATCH 12/72] Splitting Cerulean and MSC2836 in alternatives section --- proposals/3440-threading-via-relations.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 07e3883b0da..d6e7b901a95 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -17,6 +17,7 @@ There have been several experiments in threading for Matrix... - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): Threading by serverside traversal of relationships - "Threads as rooms" + - Building threads off `m.in_reply_to` Meanwhile, threading is very clearly a core requirement for any modern messaging solution, and Matrix uptake is suffering due to the lack of progress. @@ -103,7 +104,7 @@ will take additional parameters: * `relation_types`: A list of relation types which must be exist pointing to the event being filtered. If this list is absent then no filtering is done on relation types. -* `relation_senders`: A list of senders of relations which must be exist pointing to +* `relation_senders`: A list of senders of relations which must exist pointing to the event being filtered. If this list is absent then no filtering is done on relation types. This can also be combined with the `sender` field to search for threads which a @@ -253,9 +254,22 @@ Disadvantages include: * Clients which aren't aware of them are going to fill up with a lot of rooms. * Bridging to non-threaded chat systems is trickier as you may have to splice together rooms - * The sheer number of rooms involved probably makes it dependent on `/sync` v3 - landing (the to-be-specced next generation of `/sync` which is constant-time - complexity with your room count). + +### Threads via serverside traversal of relationships MSC2836 + +Advantages include: + * Fits other use cases than instant messaging + * Simple possible API shape to implement threading in a useful way + +Disadvantages include: + * Relationships are queried using `/event_relationships` which is outside the + bounds of the `/sync` API so lacks the nice things /sync gives you (live updates). + That being said, the event will come down `/sync`, you just may not have the + context required to see parents/siblings/children. + * Threads can be of arbitrary width (unlimited direct replies to a single message) + and depth (unlimited chain of replies) which complicates UI design when you just + want "simple" threading. + * Does not consider use cases like editing or reactions ### Threads via m.in_reply_to From 44e967fca674d7cb102c82067cd522dae541158f Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 19 Nov 2021 16:35:41 +0000 Subject: [PATCH 13/72] Add dependencies for threads MSC --- proposals/3440-threading-via-relations.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index d6e7b901a95..1eadb6006f0 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -295,4 +295,10 @@ MSC has not been included in a spec release. * `io.element.relation_senders` should be used in place of `relation_senders` in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `relation_types` - in the `RoomEventFilter` \ No newline at end of file + in the `RoomEventFilter` + +## Dependencies + +This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674) +and [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) (which at the +time of writing have not yet been accepted into the spec). \ No newline at end of file From 65d0d55c0b54ee345759a5a98d0d7610dc810d00 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 19 Nov 2021 16:38:36 +0000 Subject: [PATCH 14/72] Clarify intro to threads as rooms --- proposals/3440-threading-via-relations.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 1eadb6006f0..14ccb4e2d30 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -225,7 +225,7 @@ copy in `rel_type` and `event_id` properties in their reply mixin. ## Alternatives -[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", +[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", and building on `m.in_reply_to` are the main alternatives here. The first two are non-overlapping with this MSC. @@ -234,10 +234,11 @@ scalable relation format described in [MSC3051](https://github.com/matrix-org/ma ### Threads as rooms -The provides full server-side APIs for navigating trees of events, and could be -considered an extension of this MSC for scenarios which require that capability -(e.g. Twitter-style microblogging as per [Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), -or building an NNTP or IMAP or Reddit style threaded UI) +Threads as rooms could provide full server-side APIs for navigating trees of events, +and could be considered an extension of this MSC for scenarios which require that +capability (e.g. Twitter-style microblogging as per +[Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), or building +an NNTP or IMAP or Reddit style threaded UI) "Threads as rooms" is the idea that each thread could just get its own Matrix room.. From 2b76a6eed919e2bb9f3a6836bcaee9a5d7510f3a Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 19 Nov 2021 16:44:14 +0000 Subject: [PATCH 15/72] Add currentUserParticipated flag --- proposals/3440-threading-via-relations.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 14ccb4e2d30..a68f4587aee 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -52,10 +52,16 @@ would include additional information in the `unsigned` field: "content": { ... }, ... }, - "count": 7 + "count": 7, + "currentUserParticipated": true } ``` +* `latest_event`: A reference to the last `m.thread` relation part of the thread +* `count`: An integer counting the number of `m.thread` events +* `currentUserParticipated`: A flag set to `true` if the current logged in user + has participated in the thread + #### Quote replies in a thread No recommendation to modifying quote replies is made, this would still be handled From 99c5b2eee1e2e721a04ac817e312f17657d2adc1 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 19 Nov 2021 17:42:46 +0000 Subject: [PATCH 16/72] snake_case over camelCase --- proposals/3440-threading-via-relations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a68f4587aee..18ddef1d60d 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -53,13 +53,13 @@ would include additional information in the `unsigned` field: ... }, "count": 7, - "currentUserParticipated": true + "current_user_participated": true } ``` * `latest_event`: A reference to the last `m.thread` relation part of the thread * `count`: An integer counting the number of `m.thread` events -* `currentUserParticipated`: A flag set to `true` if the current logged in user +* `current_user_participated`: A flag set to `true` if the current logged in user has participated in the thread #### Quote replies in a thread From 4ee42b1526ea7f13cae54dac620c2cef5dc9632b Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 14 Dec 2021 16:52:39 +0000 Subject: [PATCH 17/72] Adding dependency to MSC3567 --- proposals/3440-threading-via-relations.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 18ddef1d60d..d0321161aca 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -306,6 +306,7 @@ MSC has not been included in a spec release. ## Dependencies -This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674) -and [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) (which at the -time of writing have not yet been accepted into the spec). \ No newline at end of file +This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) and, +[MSC3567](https://github.com/matrix-org/matrix-doc/pull/3567/files) (which at the +time of writing have not yet been accepted into the spec). From fc81bbd836955876c931c95277249981b3e2778c Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 5 Jan 2022 12:54:38 +0000 Subject: [PATCH 18/72] Add threads capability --- proposals/3440-threading-via-relations.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index d0321161aca..e9c9a8ccbdf 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -131,6 +131,22 @@ encoded JSON is presented unencoded and formatted for legibility: } ``` +### Server capabilities + +Threads might have sporadic support across servers, to simplify feature +detections for clients, a homeserver must return a capability entry for threads. + +```json +{ + "capabilities": { + ... + "m.thread": { + "enabled": true + } + } +} +``` + ### Limitations #### Read receipts From eaeef00d61a8ec409e5c67c3c893ed2e3eaadd0f Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 7 Jan 2022 08:56:48 +0000 Subject: [PATCH 19/72] Fix typo --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index e9c9a8ccbdf..64c00ed946c 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -266,7 +266,7 @@ an NNTP or IMAP or Reddit style threaded UI) Advantages to "Threads as rooms" include: * May be simpler for client implementations. - * Restricting events visiblity as the room creator + * Restricting events visibility as the room creator * Ability to create read-only threads Disadvantages include: From 26fb5f236ba9ef3d50e524d2afe67f1a2e274b2f Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 11 Jan 2022 16:46:05 +0000 Subject: [PATCH 20/72] Update syntax highlighting to use jsonc --- proposals/3440-threading-via-relations.md | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 64c00ed946c..0f9dd751963 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -46,11 +46,13 @@ I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root would include additional information in the `unsigned` field: -```json +```jsonc { "latest_event": { - "content": { ... }, - ... + "content": { + // ... + }, + // ... }, "count": 7, "current_user_participated": true @@ -123,10 +125,12 @@ GET /_matrix/client/unstable/rooms/!room_id:domain/messages?filter=... The filter string would include the new fields, above. In this example, the URL encoded JSON is presented unencoded and formatted for legibility: -```json +```jsonc { "types": ["m.room.message"], - "relation_senders": [...], + "relation_senders": [ + // ... + ], "relation_types": ["m.thread"] } ``` @@ -136,10 +140,10 @@ encoded JSON is presented unencoded and formatted for legibility: Threads might have sporadic support across servers, to simplify feature detections for clients, a homeserver must return a capability entry for threads. -```json +```jsonc { "capabilities": { - ... + // ... "m.thread": { "enabled": true } @@ -173,15 +177,15 @@ Nested threading is out of scope for this proposal and would be the subject of a different MSC. A `m.thread` event can only reference events that do not have a `rel_type` -``` +```jsonc [ { "event_id": "ev1", - ... + // ... }, { "event_id": "ev2", - ... + // ... "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", @@ -192,7 +196,7 @@ A `m.thread` event can only reference events that do not have a `rel_type` }, { "event_id": "ev3", - ... + // ... "m.relates_to": { "rel_type": "m.annotation", "event_id": "ev1", @@ -235,9 +239,9 @@ event in the thread context when clicked. When replying to the following event, a client that does not support thread should copy in `rel_type` and `event_id` properties in their reply mixin. -``` +```jsonc { - ... + // ... "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1" From a23c795f6eb31cb7d85ccbee7752b641d624bb22 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 11 Jan 2022 16:58:18 +0000 Subject: [PATCH 21/72] Add limitations when fetching thread content by relation type --- proposals/3440-threading-via-relations.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 0f9dd751963..1bd73b361ca 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -209,6 +209,9 @@ A `m.thread` event can only reference events that do not have a `rel_type` Given the above list of events, only `ev1` would be a valid target for an `m.thread` relation event. + + +#### ### Client considerations #### Display "m.thread" as "m.in_reply_to" From 6b1a36855146982c3b83c33ed9ecd3ea251b7d17 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 13 Jan 2022 15:41:57 +0000 Subject: [PATCH 22/72] Add reply chain fallback via m.in_reply_to --- proposals/3440-threading-via-relations.md | 41 +++++++++++++---------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 1bd73b361ca..995ab64cb9b 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -66,15 +66,15 @@ would include additional information in the `unsigned` field: #### Quote replies in a thread -No recommendation to modifying quote replies is made, this would still be handled -via the `m.in_reply_to` field of `m.relates_to`. Thus you could quote a reply in a thread: +Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. However clients should fill in the new `render_in` field with `m.thread` in order to display that in a thread context. ```json "m.relates_to": { "rel_type": "m.thread", "event_id": "$thread_root", "m.in_reply_to": { - "event_id": "$event_target" + "event_id": "$event_target", + "render_in": ["m.thread"] } } ``` @@ -83,6 +83,22 @@ It is possible that an `m.in_reply_to` event targets an event that is outside th related thread. Clients should always do their upmost to display the quote-reply and upon clicking it the event should be displayed and highlighted in its original context. +### Backwards compatibility + +In order to provide a readable event history for everyone, thread-ready clients +should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitely replying to another event. +The quote reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. + +```jsonc +"m.relates_to": { + "rel_type": "m.thread", + "event_id": "ev1", + "m.in_reply_to": { + "event_id": "last_event_id_in_thread", + } + } +``` + ### Fetch all replies to a thread To fetch an entire thread, the `/relations` API can be used as defined in @@ -135,6 +151,9 @@ encoded JSON is presented unencoded and formatted for legibility: } ``` + + + ### Server capabilities Threads might have sporadic support across servers, to simplify feature @@ -190,7 +209,8 @@ A `m.thread` event can only reference events that do not have a `rel_type` "rel_type": "m.thread", "event_id": "ev1", "m.in_reply_to": { - "event_id": "ev1" + "event_id": "ev1", + "render_in": ["m.thread"], } } }, @@ -214,19 +234,6 @@ relation event. #### ### Client considerations -#### Display "m.thread" as "m.in_reply_to" - -Clients that don't support threads will render threaded messages in the room's -timeline at the point at which they were sent. This does risk a confusing experience -for those on such clients, but options to mitigate this are limited. - -Having older clients treat threaded messages as replies would give a better -experience, but adding reply metadata in addition to thread metadata would mean -replies could not then be used in threads and would be significant extra metadata. - -Clients that wish to offer basic thread support can display threads as replies to -the thread root message. See matrix-org/matrix-react-sdk#7109 for an example. - #### Sending `m.thread` before fully implementing threads Clients that do not support threads yet should include a `m.thread` relation to the From f2275927c625026c7c74b7eb05a06f161262c2a8 Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 18 Jan 2022 10:36:20 +0000 Subject: [PATCH 23/72] Clarity in wording and fix typo Co-authored-by: James Salter Co-authored-by: Matthew Hodgson --- proposals/3440-threading-via-relations.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 995ab64cb9b..a4fd0a98ec1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -2,12 +2,12 @@ ## Problem -Threading is a great way to create alternative timelines to group messages related +Threading allows users to branch out a new conversation from the main timeline of a room. to each other. This is particularly useful in high traffic rooms where multiple conversations can happen in parallel or when a single discussion might stretch over a very long period of time. -The main goal when implementing threads is to create conversations that are easier +The main goal of implementing threads is to facilitate conversations that are easier to follow and smoother to read. There have been several experiments in threading for Matrix... @@ -40,7 +40,7 @@ A big advantage of relations over quote replies is that they can be server-side aggregated. It means that a client is not bound to download the entire history of a room to have a comprehensive list of events being part of a thread. -When a thread head is aggregated (as in MSC2675), returns a summary of the thread: +When a thread head is aggregated (as in MSC2675), it returns a summary of the thread: the latest message, a list of participants and the total count of messages. I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root @@ -80,8 +80,8 @@ Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. ``` It is possible that an `m.in_reply_to` event targets an event that is outside the -related thread. Clients should always do their upmost to display the quote-reply -and upon clicking it the event should be displayed and highlighted in its original context. +related thread. Clients should always do their utmost to display the quote-reply +and when clicked, the event should be displayed and highlighted in its original context. ### Backwards compatibility @@ -121,12 +121,11 @@ incremental syncs), for instance: initial sync, gappy incremental sync, ### Fetch all threads in a room -To fetch all threads in a room it is proposed to use the +To fetch all threads in a room, use the [`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) API and expand the room event filtering to include relations. The `RoomEventFilter` -will take additional parameters: -* `relation_types`: A list of relation types which must be exist pointing to the event +* `relation_types`: A list of relation types which must exist pointing to the event being filtered. If this list is absent then no filtering is done on relation types. * `relation_senders`: A list of senders of relations which must exist pointing to the event being filtered. If this list is absent then no filtering is done on relation types. @@ -138,7 +137,7 @@ user has participated in (or not participated in). GET /_matrix/client/unstable/rooms/!room_id:domain/messages?filter=... ``` -The filter string would include the new fields, above. In this example, the URL +The filter string includes the new fields, above. In this example, the URL encoded JSON is presented unencoded and formatted for legibility: ```jsonc @@ -177,8 +176,8 @@ detections for clients, a homeserver must return a capability entry for threads. Read receipts and read markers assume a single chronological timeline. Threading changes that assumption making the current API not very practical. -Clients can synthetize read receipts but it is possible that some notifications get -lost upon a fresh start where the clients have to start off the `m.read` +Clients can synthesize read receipts but it is possible that some notifications get +lost on a fresh start where the clients have to start off the `m.read` information received from the homeserver. Synchronising the synthesized notification count across devices will present its From b493f210c11485282354c3b96cc73ebddc11e0e2 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 18 Jan 2022 12:00:52 +0000 Subject: [PATCH 24/72] Cosmetic changes based on pull request feedback --- proposals/3440-threading-via-relations.md | 35 ++++++----------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a4fd0a98ec1..37062f32b06 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -9,24 +9,14 @@ over a very long period of time. The main goal of implementing threads is to facilitate conversations that are easier to follow and smoother to read. - -There have been several experiments in threading for Matrix... - - - [MSC2326](https://github.com/matrix-org/matrix-doc/pull/2326): - Label based filtering - - [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836): - Threading by serverside traversal of relationships - - "Threads as rooms" - - Building threads off `m.in_reply_to` - -Meanwhile, threading is very clearly a core requirement for any modern messaging +Threading is very clearly a core requirement for any modern messaging solution, and Matrix uptake is suffering due to the lack of progress. ## Proposal ### Event format -A new relation would be used to express that an event belongs to a thread. +A new relation type m.thread expresses that an event belongs to a thread. ```json "m.relates_to": { @@ -85,8 +75,9 @@ and when clicked, the event should be displayed and highlighted in its original ### Backwards compatibility -In order to provide a readable event history for everyone, thread-ready clients -should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitely replying to another event. +A thread will be displayed as a chain of replies on clients unaware of threads. + +Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitely replying to another event. The quote reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. ```jsonc @@ -110,11 +101,6 @@ GET /_matrix/client/unstable/rooms/!room_id:domain/relations/$thread_root/m.thre Where `$thread_root` is the event ID of the root message in the thread. -In order to properly display a thread it is necessary to retrieve the relations -to threaded events, e.g. the reactions to the threaded events. This proposes -clarifying [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) that -the `/relations` API includes bundled relations. This follows what MSC2675 already describes: - > Any API which receives events should bundle relations (apart from non-gappy incremental syncs), for instance: initial sync, gappy incremental sync, /messages and /context. @@ -180,16 +166,11 @@ Clients can synthesize read receipts but it is possible that some notifications lost on a fresh start where the clients have to start off the `m.read` information received from the homeserver. -Synchronising the synthesized notification count across devices will present its -own challenges and is probably undesirable at this stage. The preferred route -would be to create another MSC to make read receipts support multiple timelines -in a single room. +Synchronising the synthesized notification count across devices is out of scope and deferred to a later MSC. #### Single-layer event aggration -Bundling only includes relations a single-layer deep. This MSC is not looking to -solve nested threading but is rather focusing on bringing mechanisms to allow -threading in chat applications +This MSC does not include support for nested threads. Nested threading is out of scope for this proposal and would be the subject of a different MSC. @@ -278,7 +259,7 @@ an NNTP or IMAP or Reddit style threaded UI) "Threads as rooms" is the idea that each thread could just get its own Matrix room.. Advantages to "Threads as rooms" include: - * May be simpler for client implementations. + * May be simpler for client implementations * Restricting events visibility as the room creator * Ability to create read-only threads From 46e1e9bf852e72d41fbf28b3f9cf786330866468 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 18 Jan 2022 15:07:45 +0000 Subject: [PATCH 25/72] Add note to allow clients to omit fallback for rich replies --- proposals/3440-threading-via-relations.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 37062f32b06..3490fe9740f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -90,6 +90,10 @@ The quote reply fallback should be hidden in a thread context unless it contains } ``` +In the context of threads clients will omit the fallback for rich replies to allow +events of any `msgtype` to be sent in a thread. +Events that can accomodate the fallback for rich replies should include it. + ### Fetch all replies to a thread To fetch an entire thread, the `/relations` API can be used as defined in From e40efa0c05507874b31b25d3a2975598630346d9 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 18 Jan 2022 15:15:53 +0000 Subject: [PATCH 26/72] fix typo --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 3490fe9740f..a7e67769cd4 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -77,7 +77,7 @@ and when clicked, the event should be displayed and highlighted in its original A thread will be displayed as a chain of replies on clients unaware of threads. -Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitely replying to another event. +Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitly replying to another event. The quote reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. ```jsonc From 23928e7f66d882026f7a06d3ced628ca653570c2 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 20 Jan 2022 15:05:58 +0000 Subject: [PATCH 27/72] Clarify wording to not confuse thread answers with quote-replies --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a7e67769cd4..575d3b2f389 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -94,7 +94,7 @@ In the context of threads clients will omit the fallback for rich replies to all events of any `msgtype` to be sent in a thread. Events that can accomodate the fallback for rich replies should include it. -### Fetch all replies to a thread +### Fetch all relations to a thread root To fetch an entire thread, the `/relations` API can be used as defined in [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) From 0880a86be1a085cc7d98f3a53d16ead4bef163e4 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 20 Jan 2022 15:07:19 +0000 Subject: [PATCH 28/72] move relations justification to alternatives section --- proposals/3440-threading-via-relations.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 575d3b2f389..73b44c2734f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -26,10 +26,6 @@ A new relation type m.thread expresses that an event belongs to a thread. ``` Where $thread_root is the event ID of the root message in the thread. -A big advantage of relations over quote replies is that they can be server-side -aggregated. It means that a client is not bound to download the entire history of -a room to have a comprehensive list of events being part of a thread. - When a thread head is aggregated (as in MSC2675), it returns a summary of the thread: the latest message, a list of participants and the total count of messages. I.e. in places which include bundled relations (per @@ -303,6 +299,10 @@ as the thread ID), but it is clearer to define a new relation type. It is unclea what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), but that is unimplemented by clients. +A big advantage of relations over quote replies is that they can be server-side +aggregated. It means that a client is not bound to download the entire history of +a room to have a comprehensive list of events being part of a thread. + ## Security considerations None From 1bbb0213c8ff13992b1df5a963e2dfc82a0a2ced Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 20 Jan 2022 15:26:51 +0000 Subject: [PATCH 29/72] Clarify handling of m.in_reply_to missing rel_type:m.thread --- proposals/3440-threading-via-relations.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 73b44c2734f..122f43a889c 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -52,7 +52,9 @@ would include additional information in the `unsigned` field: #### Quote replies in a thread -Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. However clients should fill in the new `render_in` field with `m.thread` in order to display that in a thread context. +Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. +However clients should fill in the new `render_in` field with `m.thread` in order +to display that in a thread context. ```json "m.relates_to": { @@ -69,6 +71,10 @@ It is possible that an `m.in_reply_to` event targets an event that is outside th related thread. Clients should always do their utmost to display the quote-reply and when clicked, the event should be displayed and highlighted in its original context. +A quote reply without `rel_type: m.thread` targetting a thread relation must be +rendered in the main timeline. This will allow users to advertise threaded messages +in the room. + ### Backwards compatibility A thread will be displayed as a chain of replies on clients unaware of threads. From 3c977f7bd76edbbb63d3c72ca8114426284e03a3 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 20 Jan 2022 15:29:59 +0000 Subject: [PATCH 30/72] Fix typo --- proposals/3440-threading-via-relations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 122f43a889c..bfe9dddab8f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -53,7 +53,7 @@ would include additional information in the `unsigned` field: #### Quote replies in a thread Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. -However clients should fill in the new `render_in` field with `m.thread` in order +However clients should fill in the new `render_in` field with `m.thread` in order to display that in a thread context. ```json @@ -71,7 +71,7 @@ It is possible that an `m.in_reply_to` event targets an event that is outside th related thread. Clients should always do their utmost to display the quote-reply and when clicked, the event should be displayed and highlighted in its original context. -A quote reply without `rel_type: m.thread` targetting a thread relation must be +A quote reply without `rel_type: m.thread` targetting a thread relation must be rendered in the main timeline. This will allow users to advertise threaded messages in the room. @@ -94,7 +94,7 @@ The quote reply fallback should be hidden in a thread context unless it contains In the context of threads clients will omit the fallback for rich replies to allow events of any `msgtype` to be sent in a thread. -Events that can accomodate the fallback for rich replies should include it. +Events that can accommodate the fallback for rich replies should include it. ### Fetch all relations to a thread root From 014045489b91a5e79987fa84cc1aa304859743a0 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 20 Jan 2022 15:42:20 +0000 Subject: [PATCH 31/72] Fix typo --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index bfe9dddab8f..8cc9deefbb5 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -71,7 +71,7 @@ It is possible that an `m.in_reply_to` event targets an event that is outside th related thread. Clients should always do their utmost to display the quote-reply and when clicked, the event should be displayed and highlighted in its original context. -A quote reply without `rel_type: m.thread` targetting a thread relation must be +A quote reply without `rel_type: m.thread` targeting a thread relation must be rendered in the main timeline. This will allow users to advertise threaded messages in the room. From 700464c2d618851c45e11ff9cf6579eb2f5f7364 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 21 Jan 2022 16:00:43 +0000 Subject: [PATCH 32/72] Declare MSC2781 as a dependency --- proposals/3440-threading-via-relations.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 8cc9deefbb5..482cea5dd0d 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -79,8 +79,11 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. -Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitly replying to another event. -The quote reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. +Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. +It should always reference the latest event in the thread unless a user is +explicitly replying to another event. +The quote reply fallback should be hidden in a thread context unless it contains +the new `render_in` field as described in the previous section. ```jsonc "m.relates_to": { @@ -92,9 +95,10 @@ The quote reply fallback should be hidden in a thread context unless it contains } ``` -In the context of threads clients will omit the fallback for rich replies to allow -events of any `msgtype` to be sent in a thread. -Events that can accommodate the fallback for rich replies should include it. +Historically replies have been limited to text messages due to the legacy fallback +prepended to `formatted_body`. This MSC is dependant on +[MSC2781](https://github.com/matrix-org/matrix-doc/pull/2781) which strips that +requirement unlock use of any event type in this context. ### Fetch all relations to a thread root @@ -327,6 +331,7 @@ MSC has not been included in a spec release. ## Dependencies This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), -[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) and, -[MSC3567](https://github.com/matrix-org/matrix-doc/pull/3567/files) (which at the +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675), +[MSC3567](https://github.com/matrix-org/matrix-doc/pull/3567) and, +[MSC2781](https://github.com/matrix-org/matrix-doc/pull/2781) and, (which at the time of writing have not yet been accepted into the spec). From 0035202d1d4fb90d2e741ca323dafb669df03774 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Mon, 24 Jan 2022 08:12:52 +0000 Subject: [PATCH 33/72] Use rich reply over quote reply --- proposals/3440-threading-via-relations.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 482cea5dd0d..e01690f37b1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -50,9 +50,9 @@ would include additional information in the `unsigned` field: * `current_user_participated`: A flag set to `true` if the current logged in user has participated in the thread -#### Quote replies in a thread +#### Rich replies in a thread -Quote replies are still handled via the `m.in_reply_to` field of `m.relates_to`. +Rich replies are still handled via the `m.in_reply_to` field of `m.relates_to`. However clients should fill in the new `render_in` field with `m.thread` in order to display that in a thread context. @@ -68,10 +68,10 @@ to display that in a thread context. ``` It is possible that an `m.in_reply_to` event targets an event that is outside the -related thread. Clients should always do their utmost to display the quote-reply +related thread. Clients should always do their utmost to display the rich reply and when clicked, the event should be displayed and highlighted in its original context. -A quote reply without `rel_type: m.thread` targeting a thread relation must be +A rich reply without `rel_type: m.thread` targeting a thread relation must be rendered in the main timeline. This will allow users to advertise threaded messages in the room. @@ -82,7 +82,7 @@ A thread will be displayed as a chain of replies on clients unaware of threads. Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest event in the thread unless a user is explicitly replying to another event. -The quote reply fallback should be hidden in a thread context unless it contains +The rich reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. ```jsonc @@ -233,7 +233,7 @@ This is done so that clients that support threads can render the event in the mo relevant context. If a client does not include that relation type to the outgoing event, it will be -rendered in the room timeline with a quote reply that should open and highlight the +rendered in the room timeline with a rich reply that should open and highlight the event in the thread context when clicked. When replying to the following event, a client that does not support thread should @@ -309,7 +309,7 @@ as the thread ID), but it is clearer to define a new relation type. It is unclea what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), but that is unimplemented by clients. -A big advantage of relations over quote replies is that they can be server-side +A big advantage of relations over rich replies is that they can be server-side aggregated. It means that a client is not bound to download the entire history of a room to have a comprehensive list of events being part of a thread. From e3cb699b190b1ddc6d62bdce8db62432f8b3f2ec Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 26 Jan 2022 00:23:30 +0000 Subject: [PATCH 34/72] Depend on MSC3676 rather than MSC2781 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than relying on fallbacks being removed outright (and all the notification complications that causes in #2781), instead depend on #3676 which makes fallbacks best effort. --- proposals/3440-threading-via-relations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index e01690f37b1..617b6fe040b 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -97,8 +97,8 @@ the new `render_in` field as described in the previous section. Historically replies have been limited to text messages due to the legacy fallback prepended to `formatted_body`. This MSC is dependant on -[MSC2781](https://github.com/matrix-org/matrix-doc/pull/2781) which strips that -requirement unlock use of any event type in this context. +[MSC3676](https://github.com/matrix-org/matrix-doc/pull/3676) which strips that +requirement to unlock use of any event type in this context. ### Fetch all relations to a thread root @@ -333,5 +333,5 @@ MSC has not been included in a spec release. This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675), [MSC3567](https://github.com/matrix-org/matrix-doc/pull/3567) and, -[MSC2781](https://github.com/matrix-org/matrix-doc/pull/2781) and, (which at the +[MSC3676](https://github.com/matrix-org/matrix-doc/pull/3676) (which at the time of writing have not yet been accepted into the spec). From 847f46800c73f339944cbc97b5f2ed0ef196ed47 Mon Sep 17 00:00:00 2001 From: Germain Date: Thu, 10 Feb 2022 09:40:46 +0000 Subject: [PATCH 35/72] Remove full stop typo Co-authored-by: Erik Johnston --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 617b6fe040b..f6200b7f9cc 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -2,7 +2,7 @@ ## Problem -Threading allows users to branch out a new conversation from the main timeline of a room. +Threading allows users to branch out a new conversation from the main timeline of a room to each other. This is particularly useful in high traffic rooms where multiple conversations can happen in parallel or when a single discussion might stretch over a very long period of time. From c8ffa62e16a09d82c8d3bac266ffb61513772535 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 14 Feb 2022 09:16:37 -0500 Subject: [PATCH 36/72] Clarify new filtering parameters. --- proposals/3440-threading-via-relations.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index f6200b7f9cc..30fd634c02c 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -117,9 +117,10 @@ incremental syncs), for instance: initial sync, gappy incremental sync, ### Fetch all threads in a room -To fetch all threads in a room, use the +To fetch all threads in a room, the [`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) -API and expand the room event filtering to include relations. The `RoomEventFilter` +API is used with newly added filtering options. It is proposed to expand the room +event filtering to include filtering events by their related events: * `relation_types`: A list of relation types which must exist pointing to the event being filtered. If this list is absent then no filtering is done on relation types. @@ -146,8 +147,17 @@ encoded JSON is presented unencoded and formatted for legibility: } ``` +Note that the newly added filtering parameters return events based on information +in related events. Consider the following events in a room: +* `A`: a `m.room.message` event sent by `alice` +* `B`: a `m.room.message` event sent by `bob` which relates to `A` with type `m.thread` +Using a filter of `"relation_types": ["m.thread"]` would return event `A` as it +has another event which relates to it via `m.thread`. + +Similary, using a filter of `"relation_senders": ["bob"]` would return event `A` +as it has another event which relates to it sent by `bob`. ### Server capabilities From a7cbf8db297814f01fedd3402f4b68995e92e00d Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 15 Feb 2022 09:31:47 -0500 Subject: [PATCH 37/72] Fix typo. --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 30fd634c02c..62280ebf530 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -156,7 +156,7 @@ in related events. Consider the following events in a room: Using a filter of `"relation_types": ["m.thread"]` would return event `A` as it has another event which relates to it via `m.thread`. -Similary, using a filter of `"relation_senders": ["bob"]` would return event `A` +Similarly, using a filter of `"relation_senders": ["bob"]` would return event `A` as it has another event which relates to it sent by `bob`. ### Server capabilities From 5896d6923d786572cb724009eade481f6947ea15 Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 16 Feb 2022 11:28:22 +0000 Subject: [PATCH 38/72] Update wording for client side considerations Co-authored-by: Hubert Chathi --- proposals/3440-threading-via-relations.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 62280ebf530..6879ab4bbd9 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -242,9 +242,11 @@ event body if a user is replying to an event that has an `m.thread` relation typ This is done so that clients that support threads can render the event in the most relevant context. -If a client does not include that relation type to the outgoing event, it will be -rendered in the room timeline with a rich reply that should open and highlight the -event in the thread context when clicked. +If a client does not include that relation type to the outgoing event, it should +be treated as not being part of the thread. For example, if a client has a +separate area for displaying threads, clients can render the event in the main +room timeline as a rich reply that will open and highlight the event in the +thread context when clicked. When replying to the following event, a client that does not support thread should copy in `rel_type` and `event_id` properties in their reply mixin. From ee5df808460de061cfbddc010b49c2735b6e34aa Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 16 Feb 2022 11:27:35 +0000 Subject: [PATCH 39/72] Add m.in_reply_to mixin to thread fallback --- proposals/3440-threading-via-relations.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 6879ab4bbd9..d3213016dd8 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -256,7 +256,11 @@ copy in `rel_type` and `event_id` properties in their reply mixin. // ... "m.relates_to": { "rel_type": "m.thread", - "event_id": "ev1" + "event_id": "ev1", + "m.in_reply_to": { + "event_id": "$event_target", + "render_in": ["m.thread"] + } } } ``` From 00daf64956c20b42a4b5a725a477cbb30e451948 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 16 Feb 2022 16:45:51 +0000 Subject: [PATCH 40/72] Add guidance for clients and servers for thread invalid relations --- proposals/3440-threading-via-relations.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index d3213016dd8..a2ae3826b19 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -229,9 +229,17 @@ A `m.thread` event can only reference events that do not have a `rel_type` Given the above list of events, only `ev1` would be a valid target for an `m.thread` relation event. +Invalid thread relations should be rejected with an HTTP `400` status code and a +`M_UNKNOWN` error code. +Events received through federations should be always be accepted without checking +the validity of the relations as it would break the extensibility of this proposal +in a future MSC. +This means that events with invalid thread relations can make their way into the +network, either due by malicious activity or buggy implementation. If a client +receives such events, they should hide them as soon as it can determine for certain +that the associated event is not a valid target. -#### ### Client considerations #### Sending `m.thread` before fully implementing threads From a5d8aab6fcb007c86da5a314d1a431191082d963 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 17 Feb 2022 08:48:43 +0000 Subject: [PATCH 41/72] update thread root wording --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a2ae3826b19..7594696b67a 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -26,7 +26,7 @@ A new relation type m.thread expresses that an event belongs to a thread. ``` Where $thread_root is the event ID of the root message in the thread. -When a thread head is aggregated (as in MSC2675), it returns a summary of the thread: +When a thread root is aggregated (as in MSC2675), it returns a summary of the thread: the latest message, a list of participants and the total count of messages. I.e. in places which include bundled relations (per [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675)), the thread root From d7ed3c4e588d374457a1fd204129cd67c604aa77 Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 22 Feb 2022 09:08:45 +0000 Subject: [PATCH 42/72] Add better definition to reply target event Co-authored-by: Travis Ralston --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 7594696b67a..04c6d6f62b9 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -80,7 +80,7 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. -It should always reference the latest event in the thread unless a user is +It should always reference the latest message-like event in the thread unless a user is explicitly replying to another event. The rich reply fallback should be hidden in a thread context unless it contains the new `render_in` field as described in the previous section. From 5c04906e1bf84d4d01f2fb5ff9b3251993d08435 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 22 Feb 2022 09:07:14 +0000 Subject: [PATCH 43/72] Add note regarding forward compatibility --- proposals/3440-threading-via-relations.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 04c6d6f62b9..c466facd479 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -79,6 +79,10 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. +To ensure forward-compatiblity on systems that do not support threads, clients +are advised to attach the `m.thread` relation to replies that are target an event +containing a `m.thread` relation. + Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. It should always reference the latest message-like event in the thread unless a user is explicitly replying to another event. From d667a0baa5e6c903106b04130d58dcd7e4e3e379 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 22 Feb 2022 15:28:21 +0000 Subject: [PATCH 44/72] link to MSC2674 --- proposals/3440-threading-via-relations.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index c466facd479..c3d81a34560 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -16,7 +16,8 @@ solution, and Matrix uptake is suffering due to the lack of progress. ### Event format -A new relation type m.thread expresses that an event belongs to a thread. +A new relation type (see [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674)) +`m.thread` expresses that an event belongs to a thread. ```json "m.relates_to": { From b157dfd6e47e1b46e5bc834bdd720c4e9c237dc3 Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 22 Feb 2022 16:49:45 +0000 Subject: [PATCH 45/72] Update proposals/3440-threading-via-relations.md Co-authored-by: Hubert Chathi --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index c3d81a34560..e83523f3b0e 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -81,7 +81,7 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. To ensure forward-compatiblity on systems that do not support threads, clients -are advised to attach the `m.thread` relation to replies that are target an event +are advised to attach the `m.thread` relation to replies that target an event containing a `m.thread` relation. Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. From 3162bea4078c36ac3e3efb5271a0f08fc9c427c2 Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 22 Feb 2022 17:09:01 +0000 Subject: [PATCH 46/72] Clarification on responsibilities for the reply fallback Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index e83523f3b0e..300ce115db1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -84,7 +84,7 @@ To ensure forward-compatiblity on systems that do not support threads, clients are advised to attach the `m.thread` relation to replies that target an event containing a `m.thread` relation. -Thread-ready clients should attach a `m.in_reply_to` mixin to the event source. +Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. It should always reference the latest message-like event in the thread unless a user is explicitly replying to another event. The rich reply fallback should be hidden in a thread context unless it contains From fa232f465ed34d1fd6b4ac3942f371a4fcc5c41c Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 22 Feb 2022 17:12:47 +0000 Subject: [PATCH 47/72] Update `/messages` API endpoint version on example Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 300ce115db1..cdb8b526582 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -136,7 +136,7 @@ This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). ``` -GET /_matrix/client/unstable/rooms/!room_id:domain/messages?filter=... +GET /_matrix/client/v3/rooms/!room_id:domain/messages?filter=... ``` The filter string includes the new fields, above. In this example, the URL From 68d9c42a95af94935061290bd38c9118d6313fde Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 23 Feb 2022 10:27:28 +0000 Subject: [PATCH 48/72] Apply wording suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index cdb8b526582..b40ad779d54 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -80,7 +80,7 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. -To ensure forward-compatiblity on systems that do not support threads, clients +To ensure forward-compatibility on systems that do not support threads, clients are advised to attach the `m.thread` relation to replies that target an event containing a `m.thread` relation. @@ -234,23 +234,24 @@ A `m.thread` event can only reference events that do not have a `rel_type` Given the above list of events, only `ev1` would be a valid target for an `m.thread` relation event. -Invalid thread relations should be rejected with an HTTP `400` status code and a +Servers should reject attempts to send events with invalid thread relations via the +Client-Server API with an HTTP `400` status code and a `M_UNKNOWN` error code. -Events received through federations should be always be accepted without checking +Events received over federation should always be accepted without checking the validity of the relations as it would break the extensibility of this proposal in a future MSC. This means that events with invalid thread relations can make their way into the network, either due by malicious activity or buggy implementation. If a client -receives such events, they should hide them as soon as it can determine for certain +receives such events, they should hide them as soon as they can determine for certain that the associated event is not a valid target. ### Client considerations #### Sending `m.thread` before fully implementing threads -Clients that do not support threads yet should include a `m.thread` relation to the -event body if a user is replying to an event that has an `m.thread` relation type +Clients that do not support threads yet should include a `m.thread` relation in the +event body if a user is replying to an event that has an `m.thread` relation type. This is done so that clients that support threads can render the event in the most relevant context. From 5bbb015f031b70ffbd93a1b64049353a3a15fd1f Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 22 Feb 2022 16:53:57 +0000 Subject: [PATCH 49/72] Add notes on server-side invalid relation filtering --- proposals/3440-threading-via-relations.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index b40ad779d54..7e9aef8466a 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -246,6 +246,11 @@ network, either due by malicious activity or buggy implementation. If a client receives such events, they should hide them as soon as they can determine for certain that the associated event is not a valid target. +Servers should not filter out invalid `m.thread` relations from the results when +serving endpoints that deal with message relations. Clients that call those +endpoints should be aware that they may return events with invalid relations, +and deal with them appropriately. + ### Client considerations #### Sending `m.thread` before fully implementing threads From 707af2ba3e9824995068ac6d16c7450bf985bffd Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 22 Feb 2022 17:19:06 +0000 Subject: [PATCH 50/72] Fix typo --- proposals/3440-threading-via-relations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 7e9aef8466a..06fb0eb7e31 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -193,7 +193,7 @@ information received from the homeserver. Synchronising the synthesized notification count across devices is out of scope and deferred to a later MSC. -#### Single-layer event aggration +#### Single-layer event aggregation This MSC does not include support for nested threads. From b28a3652f89543087509bce2730c0659592f6e78 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 23 Feb 2022 10:59:30 +0000 Subject: [PATCH 51/72] reword paragraph about forwarding m.thread relation --- proposals/3440-threading-via-relations.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 06fb0eb7e31..6ebb23ca39d 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -255,11 +255,9 @@ and deal with them appropriately. #### Sending `m.thread` before fully implementing threads -Clients that do not support threads yet should include a `m.thread` relation in the -event body if a user is replying to an event that has an `m.thread` relation type. - -This is done so that clients that support threads can render the event in the most -relevant context. +Clients that do not support threads yet should copy the `m.thread` relation of the +associated event when sending a reply. This is done so that clients that support +threads can render the event in the most relevant context. If a client does not include that relation type to the outgoing event, it should be treated as not being part of the thread. For example, if a client has a From 8f82dfaa6943d80e1562f7aa9a9ad71a90b94d3f Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 23 Feb 2022 11:03:24 +0000 Subject: [PATCH 52/72] Add unstable prefix for capability endpoint --- proposals/3440-threading-via-relations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 6ebb23ca39d..f450b098333 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -356,6 +356,7 @@ Clients and servers should use list of unstable prefixes listed below while this MSC has not been included in a spec release. * `io.element.thread` should be used in place of `m.thread` as relation type + * `io.element.thread` should be used in place of `m.thread` as a capability entry * `io.element.relation_senders` should be used in place of `relation_senders` in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `relation_types` From 8f8be64df27b5760df98ecef5faf7d4951b98b24 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 23 Feb 2022 11:08:36 +0000 Subject: [PATCH 53/72] Re-order alternatives to match intro paragraph --- proposals/3440-threading-via-relations.md | 34 +++++++++++------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index f450b098333..a9d81d97f1f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -284,9 +284,7 @@ copy in `rel_type` and `event_id` properties in their reply mixin. ## Alternatives -[MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836), "Threading as rooms", and -building on `m.in_reply_to` are the main alternatives here. The first two are -non-overlapping with this MSC. +"Threading as rooms", building on `m.in_reply_to`, and [MSC2836](https://github.com/matrix-org/matrix-doc/pull/2836) are the main alternatives here. It is also worth noting that relations in this MSC could be expressed using the scalable relation format described in [MSC3051](https://github.com/matrix-org/matrix-doc/pull/3051). @@ -315,6 +313,21 @@ Disadvantages include: * Bridging to non-threaded chat systems is trickier as you may have to splice together rooms +### Threads via m.in_reply_to + +The rationale for using a new relation type instead of building on `m.in_reply_to` +is to re-use the event relationship APIs provided by +[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675). The MSC3267 definition +of `m.reference` relationships could be updated to mention threads (perhaps by +using the key field from [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) +as the thread ID), but it is clearer to define a new relation type. It is unclear +what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), +but that is unimplemented by clients. + +A big advantage of relations over rich replies is that they can be server-side +aggregated. It means that a client is not bound to download the entire history of +a room to have a comprehensive list of events being part of a thread. + ### Threads via serverside traversal of relationships MSC2836 Advantages include: @@ -331,21 +344,6 @@ Disadvantages include: want "simple" threading. * Does not consider use cases like editing or reactions -### Threads via m.in_reply_to - -The rationale for using a new relation type instead of building on `m.in_reply_to` -is to re-use the event relationship APIs provided by -[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675). The MSC3267 definition -of `m.reference` relationships could be updated to mention threads (perhaps by -using the key field from [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) -as the thread ID), but it is clearer to define a new relation type. It is unclear -what impact this would have on [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267), -but that is unimplemented by clients. - -A big advantage of relations over rich replies is that they can be server-side -aggregated. It means that a client is not bound to download the entire history of -a room to have a comprehensive list of events being part of a thread. - ## Security considerations None From b6d807698549d2a8532321dc7b1a73fb23dd9d2b Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 23 Feb 2022 11:26:43 +0000 Subject: [PATCH 54/72] rework relation_senders and relation_types definition --- proposals/3440-threading-via-relations.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a9d81d97f1f..2288ec1e725 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -127,10 +127,13 @@ To fetch all threads in a room, the API is used with newly added filtering options. It is proposed to expand the room event filtering to include filtering events by their related events: -* `relation_types`: A list of relation types which must exist pointing to the event - being filtered. If this list is absent then no filtering is done on relation types. -* `relation_senders`: A list of senders of relations which must exist pointing to - the event being filtered. If this list is absent then no filtering is done on relation types. + +* `relation_types`: A list of relation types to include. An event `A` is included +in the filter only if there exists another event `B` which relates to `A` with a +`rel_type` which is defined in the list +* `relation_senders`: A list of senders to include. An event `A` is included in +the filter only if there exists another event `B` which relates to `A` with a +`sender` which is defined in the list This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). From cd671ef31403aab79d5c9be90c60b9e2b60fccfd Mon Sep 17 00:00:00 2001 From: Germain Date: Thu, 24 Feb 2022 11:12:09 +0000 Subject: [PATCH 55/72] Apply wording suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Kim Brose --- proposals/3440-threading-via-relations.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 2288ec1e725..1d562b83f5d 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -125,15 +125,15 @@ incremental syncs), for instance: initial sync, gappy incremental sync, To fetch all threads in a room, the [`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) API is used with newly added filtering options. It is proposed to expand the room -event filtering to include filtering events by their related events: +event filtering to include filtering events by their relating events: * `relation_types`: A list of relation types to include. An event `A` is included in the filter only if there exists another event `B` which relates to `A` with a `rel_type` which is defined in the list * `relation_senders`: A list of senders to include. An event `A` is included in -the filter only if there exists another event `B` which relates to `A` with a -`sender` which is defined in the list +the filter only if there exists another event `B` which relates to `A`, and +which has a `sender` which is in the list. This can also be combined with the `sender` field to search for threads which a user has participated in (or not participated in). @@ -246,10 +246,10 @@ in a future MSC. This means that events with invalid thread relations can make their way into the network, either due by malicious activity or buggy implementation. If a client -receives such events, they should hide them as soon as they can determine for certain +receives such events, it should hide them as soon as it can determine for certain that the associated event is not a valid target. -Servers should not filter out invalid `m.thread` relations from the results when +Servers are expected to not filter out invalid `m.thread` relations from the results when serving endpoints that deal with message relations. Clients that call those endpoints should be aware that they may return events with invalid relations, and deal with them appropriately. @@ -262,7 +262,7 @@ Clients that do not support threads yet should copy the `m.thread` relation of t associated event when sending a reply. This is done so that clients that support threads can render the event in the most relevant context. -If a client does not include that relation type to the outgoing event, it should +If a client does not include that relation type in the outgoing event, it should be treated as not being part of the thread. For example, if a client has a separate area for displaying threads, clients can render the event in the main room timeline as a rich reply that will open and highlight the event in the From a61c01eade95abb803096b6d3d44da7c72dec7cb Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 24 Feb 2022 11:20:50 +0000 Subject: [PATCH 56/72] Clarify fallback mechanism --- proposals/3440-threading-via-relations.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 1d562b83f5d..e0354ec6a6f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -258,9 +258,10 @@ and deal with them appropriately. #### Sending `m.thread` before fully implementing threads -Clients that do not support threads yet should copy the `m.thread` relation of the -associated event when sending a reply. This is done so that clients that support -threads can render the event in the most relevant context. +Clients that do not support threads yet should behave as followed when replying. +It should set the `m.in_reply_to` part as usual, and then add on +`"rel_type": "m.thread"` and `"event_id": "$thread_root"`, copying `$thread_root` +from the replied-to event. If a client does not include that relation type in the outgoing event, it should be treated as not being part of the thread. For example, if a client has a From 362e661fa69412c51a794530bb974e4efb975af6 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 24 Feb 2022 11:41:12 +0000 Subject: [PATCH 57/72] Rename filter property names --- proposals/3440-threading-via-relations.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index e0354ec6a6f..1adb3c26dea 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -128,10 +128,10 @@ API is used with newly added filtering options. It is proposed to expand the roo event filtering to include filtering events by their relating events: -* `relation_types`: A list of relation types to include. An event `A` is included +* `related_by_rel_types`: A list of relation types to include. An event `A` is included in the filter only if there exists another event `B` which relates to `A` with a `rel_type` which is defined in the list -* `relation_senders`: A list of senders to include. An event `A` is included in +* `related_by_senders`: A list of senders to include. An event `A` is included in the filter only if there exists another event `B` which relates to `A`, and which has a `sender` which is in the list. @@ -148,10 +148,10 @@ encoded JSON is presented unencoded and formatted for legibility: ```jsonc { "types": ["m.room.message"], - "relation_senders": [ + "related_by_senders": [ // ... ], - "relation_types": ["m.thread"] + "related_by_rel_types": ["m.thread"] } ``` @@ -161,10 +161,10 @@ in related events. Consider the following events in a room: * `A`: a `m.room.message` event sent by `alice` * `B`: a `m.room.message` event sent by `bob` which relates to `A` with type `m.thread` -Using a filter of `"relation_types": ["m.thread"]` would return event `A` as it +Using a filter of `"related_by_rel_types": ["m.thread"]` would return event `A` as it has another event which relates to it via `m.thread`. -Similarly, using a filter of `"relation_senders": ["bob"]` would return event `A` +Similarly, using a filter of `"related_by_senders": ["bob"]` would return event `A` as it has another event which relates to it sent by `bob`. ### Server capabilities @@ -359,9 +359,9 @@ MSC has not been included in a spec release. * `io.element.thread` should be used in place of `m.thread` as relation type * `io.element.thread` should be used in place of `m.thread` as a capability entry - * `io.element.relation_senders` should be used in place of `relation_senders` + * `io.element.relation_senders` should be used in place of `related_by_senders` in the `RoomEventFilter` - * `io.element.relation_types` should be used in place of `relation_types` + * `io.element.relation_types` should be used in place of `related_by_rel_types` in the `RoomEventFilter` ## Dependencies From b831fb3818fe33364381773a74e1c462301abd44 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 24 Feb 2022 11:47:31 +0000 Subject: [PATCH 58/72] Change m.render_in to m.display_reply_fallback --- proposals/3440-threading-via-relations.md | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 1adb3c26dea..5f4a3c8e007 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -54,16 +54,16 @@ would include additional information in the `unsigned` field: #### Rich replies in a thread Rich replies are still handled via the `m.in_reply_to` field of `m.relates_to`. -However clients should fill in the new `render_in` field with `m.thread` in order -to display that in a thread context. +However clients should fill in the new `m.display_reply_fallback` property +in order to display that in a thread context. ```json "m.relates_to": { "rel_type": "m.thread", "event_id": "$thread_root", + "m.display_reply_fallback": true, "m.in_reply_to": { - "event_id": "$event_target", - "render_in": ["m.thread"] + "event_id": "$event_target" } } ``` @@ -84,11 +84,11 @@ To ensure forward-compatibility on systems that do not support threads, clients are advised to attach the `m.thread` relation to replies that target an event containing a `m.thread` relation. -Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. -It should always reference the latest message-like event in the thread unless a user is -explicitly replying to another event. +Thread-ready clients should always include an `m.in_reply_to` property when sending +a threaded event. It should always reference the latest message-like event in the +thread unless a user is explicitly replying to another event. The rich reply fallback should be hidden in a thread context unless it contains -the new `render_in` field as described in the previous section. +the new `m.display_reply_fallback` field as described in the previous section. ```jsonc "m.relates_to": { @@ -216,9 +216,9 @@ A `m.thread` event can only reference events that do not have a `rel_type` "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", + "m.display_reply_fallback": true, "m.in_reply_to": { - "event_id": "ev1", - "render_in": ["m.thread"], + "event_id": "ev1" } } }, @@ -278,9 +278,9 @@ copy in `rel_type` and `event_id` properties in their reply mixin. "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", + "m.display_reply_fallback": true, "m.in_reply_to": { - "event_id": "$event_target", - "render_in": ["m.thread"] + "event_id": "$event_target" } } } @@ -363,6 +363,7 @@ MSC has not been included in a spec release. in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `related_by_rel_types` in the `RoomEventFilter` + * `io.element.display_reply_fallback` should be used in place of `m.display_reply_fallback` ## Dependencies From e2dde8ea0e5f2561cccd64700fbcc181bc2e8b96 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 25 Feb 2022 09:31:56 +0000 Subject: [PATCH 59/72] Clarify what endpoints support the new filter --- proposals/3440-threading-via-relations.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 5f4a3c8e007..60b1dcbd036 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -122,11 +122,9 @@ incremental syncs), for instance: initial sync, gappy incremental sync, ### Fetch all threads in a room -To fetch all threads in a room, the -[`/messages`](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-messages) -API is used with newly added filtering options. It is proposed to expand the room -event filtering to include filtering events by their relating events: - +[Event filters](https://spec.matrix.org/v1.2/client-server-api/#filtering) (as +used by endpoints including `/messages`, `/sync` and `/context`) are extended +with new options to allow filtering events by their relating events: * `related_by_rel_types`: A list of relation types to include. An event `A` is included in the filter only if there exists another event `B` which relates to `A` with a From e640f6b95d828076003626d131c51a846be58e05 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 25 Feb 2022 09:36:48 +0000 Subject: [PATCH 60/72] Switch from /capabilities to /versions --- proposals/3440-threading-via-relations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 60b1dcbd036..886fbee067b 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -168,15 +168,15 @@ as it has another event which relates to it sent by `bob`. ### Server capabilities Threads might have sporadic support across servers, to simplify feature -detections for clients, a homeserver must return a capability entry for threads. +detections for clients, a homeserver must advertise unstable support for threads. +As part of the `/versions` API + ```jsonc { - "capabilities": { + "unstable_features": { + "org.matrix.msc3440": true, // ... - "m.thread": { - "enabled": true - } } } ``` From bda3a1e6c9a9625e6aafd201b00dc30e4e569495 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 25 Feb 2022 10:05:23 +0000 Subject: [PATCH 61/72] remove references to Cerulean --- proposals/3440-threading-via-relations.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 886fbee067b..a4d83120252 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -295,11 +295,9 @@ scalable relation format described in [MSC3051](https://github.com/matrix-org/ma Threads as rooms could provide full server-side APIs for navigating trees of events, and could be considered an extension of this MSC for scenarios which require that -capability (e.g. Twitter-style microblogging as per -[Cerulean](https://matrix.org/blog/2020/12/18/introducing-cerulean), or building -an NNTP or IMAP or Reddit style threaded UI) +capability -"Threads as rooms" is the idea that each thread could just get its own Matrix room.. +"Threads as rooms" is the idea that each thread could just get its own Matrix room. Advantages to "Threads as rooms" include: * May be simpler for client implementations From 89c4b5e4b65eef20e8d8a9e971bceba17a5e60fa Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 25 Feb 2022 10:14:28 +0000 Subject: [PATCH 62/72] Update latest_event description --- proposals/3440-threading-via-relations.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a4d83120252..3f9de72ad7d 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -46,7 +46,8 @@ would include additional information in the `unsigned` field: } ``` -* `latest_event`: A reference to the last `m.thread` relation part of the thread +* `latest_event`: The most recent event which relates to this event, with + `rel_type` of `m.thread`. * `count`: An integer counting the number of `m.thread` events * `current_user_participated`: A flag set to `true` if the current logged in user has participated in the thread From 61bb518513cff12751b41a63b230c767cf12864a Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 1 Mar 2022 15:25:17 +0000 Subject: [PATCH 63/72] Clarity in wording and fix typo Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 3f9de72ad7d..a3c823454f2 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -169,9 +169,8 @@ as it has another event which relates to it sent by `bob`. ### Server capabilities Threads might have sporadic support across servers, to simplify feature -detections for clients, a homeserver must advertise unstable support for threads. -As part of the `/versions` API - +detections for clients, a homeserver must advertise unstable support for threads +as part of the `/versions` API: ```jsonc { @@ -257,18 +256,19 @@ and deal with them appropriately. #### Sending `m.thread` before fully implementing threads -Clients that do not support threads yet should behave as followed when replying. -It should set the `m.in_reply_to` part as usual, and then add on +Clients that do not offer a threading UI should behave as follows when replying, for +best interaction with those that do. +They should set the `m.in_reply_to` part as usual, and then add on `"rel_type": "m.thread"` and `"event_id": "$thread_root"`, copying `$thread_root` from the replied-to event. -If a client does not include that relation type in the outgoing event, it should +If the `m.thread` relation type is not present in an incoming event, it should be treated as not being part of the thread. For example, if a client has a separate area for displaying threads, clients can render the event in the main room timeline as a rich reply that will open and highlight the event in the thread context when clicked. -When replying to the following event, a client that does not support thread should +When replying to the following event, a client that does not support threads should copy in `rel_type` and `event_id` properties in their reply mixin. ```jsonc From 9159a5a7381a1ba5a7416e78a2a8d80c5a4cffd5 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 1 Mar 2022 15:09:49 +0000 Subject: [PATCH 64/72] rename m.display_reply_fallback to hide_reply --- proposals/3440-threading-via-relations.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index a3c823454f2..81926625bc7 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -55,14 +55,14 @@ would include additional information in the `unsigned` field: #### Rich replies in a thread Rich replies are still handled via the `m.in_reply_to` field of `m.relates_to`. -However clients should fill in the new `m.display_reply_fallback` property +However clients should fill in the new `hide_reply` property in order to display that in a thread context. ```json "m.relates_to": { "rel_type": "m.thread", "event_id": "$thread_root", - "m.display_reply_fallback": true, + "hide_reply": false, "m.in_reply_to": { "event_id": "$event_target" } @@ -88,8 +88,8 @@ containing a `m.thread` relation. Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. It should always reference the latest message-like event in the thread unless a user is explicitly replying to another event. -The rich reply fallback should be hidden in a thread context unless it contains -the new `m.display_reply_fallback` field as described in the previous section. +The rich reply fallback should be displayed in a thread context unless it contains +the new `hide_reply` field as described in the previous section. ```jsonc "m.relates_to": { @@ -214,7 +214,7 @@ A `m.thread` event can only reference events that do not have a `rel_type` "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "m.display_reply_fallback": true, + "hide_reply": true, "m.in_reply_to": { "event_id": "ev1" } @@ -277,7 +277,7 @@ copy in `rel_type` and `event_id` properties in their reply mixin. "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "m.display_reply_fallback": true, + "hide_reply": false, "m.in_reply_to": { "event_id": "$event_target" } @@ -360,7 +360,7 @@ MSC has not been included in a spec release. in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `related_by_rel_types` in the `RoomEventFilter` - * `io.element.display_reply_fallback` should be used in place of `m.display_reply_fallback` + * `io.element.hide_reply` should be used in place of `hide_reply` ## Dependencies From a97307af3a516e8df511e6721a2758465991ca5a Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 1 Mar 2022 16:01:13 +0000 Subject: [PATCH 65/72] remove redundant paragraph about forward compat --- proposals/3440-threading-via-relations.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 81926625bc7..23eb6dfec7f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -81,10 +81,6 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. -To ensure forward-compatibility on systems that do not support threads, clients -are advised to attach the `m.thread` relation to replies that target an event -containing a `m.thread` relation. - Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. It should always reference the latest message-like event in the thread unless a user is explicitly replying to another event. From f541dab3353ba5707199d3c0ad8e629cddd602f5 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 1 Mar 2022 16:08:52 +0000 Subject: [PATCH 66/72] Improve bundled relationship example --- proposals/3440-threading-via-relations.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 23eb6dfec7f..0f5d3646f07 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -35,14 +35,19 @@ would include additional information in the `unsigned` field: ```jsonc { - "latest_event": { - "content": { - // ... - }, - // ... - }, - "count": 7, - "current_user_participated": true + "event_id": "$root_event", + "unsigned": { + "m.relations": { + "m.thread": { + "latest_event": { + "event_id": "$thread_event", + // ... + }, + "count": 7, + "current_user_participated": true + } + } + } } ``` From 82b4c62c30dc495095205bab00d30000632ceeac Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 1 Mar 2022 16:22:27 +0000 Subject: [PATCH 67/72] Explain context on why a thread-unaware client might want to send m.thread --- proposals/3440-threading-via-relations.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 0f5d3646f07..fcc25220b4a 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -257,6 +257,11 @@ and deal with them appropriately. #### Sending `m.thread` before fully implementing threads +There will be clients that will not or can't support threads. Whether this is a +deliberate choice or because the system bridges to a platform that does not support +threads, there are a number of steps developer of those systems can take to ensure +continuity of conversation in the ecosystem. + Clients that do not offer a threading UI should behave as follows when replying, for best interaction with those that do. They should set the `m.in_reply_to` part as usual, and then add on From 75f4cb2a3e17bda519a9999597c499ede7181cd5 Mon Sep 17 00:00:00 2001 From: Germain Date: Fri, 4 Mar 2022 14:25:56 +0000 Subject: [PATCH 68/72] Clarify `hide_reply` Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index fcc25220b4a..c80e23288c1 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -88,9 +88,11 @@ A thread will be displayed as a chain of replies on clients unaware of threads. Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. It should always reference the latest message-like event in the -thread unless a user is explicitly replying to another event. -The rich reply fallback should be displayed in a thread context unless it contains -the new `hide_reply` field as described in the previous section. +thread unless a user is explicitly replying to another event (in which case `hide_reply` +should be set to `false`, as above). + +The rich reply fallback should be ignored by thread-ready clients (ie, the +event should be displayed in a thread context) unless `hide_reply` is `false`. ```jsonc "m.relates_to": { From 54ce18565513d22f0966bb67fa118fa48aeec414 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 8 Mar 2022 10:19:38 +0000 Subject: [PATCH 69/72] Rename hide_reply to show_reply --- proposals/3440-threading-via-relations.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index c80e23288c1..60084cd0de4 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -60,14 +60,14 @@ would include additional information in the `unsigned` field: #### Rich replies in a thread Rich replies are still handled via the `m.in_reply_to` field of `m.relates_to`. -However clients should fill in the new `hide_reply` property +However clients should fill in the new `show_reply` property in order to display that in a thread context. ```json "m.relates_to": { "rel_type": "m.thread", "event_id": "$thread_root", - "hide_reply": false, + "show_reply": true, "m.in_reply_to": { "event_id": "$event_target" } @@ -92,7 +92,7 @@ thread unless a user is explicitly replying to another event (in which case `hid should be set to `false`, as above). The rich reply fallback should be ignored by thread-ready clients (ie, the -event should be displayed in a thread context) unless `hide_reply` is `false`. +event should be displayed in a thread context) unless `show_reply` is `reply`. ```jsonc "m.relates_to": { @@ -217,7 +217,7 @@ A `m.thread` event can only reference events that do not have a `rel_type` "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "hide_reply": true, + "show_reply": false, "m.in_reply_to": { "event_id": "ev1" } @@ -285,7 +285,7 @@ copy in `rel_type` and `event_id` properties in their reply mixin. "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "hide_reply": false, + "show_reply": true, "m.in_reply_to": { "event_id": "$event_target" } @@ -368,7 +368,7 @@ MSC has not been included in a spec release. in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `related_by_rel_types` in the `RoomEventFilter` - * `io.element.hide_reply` should be used in place of `hide_reply` + * `io.element.show_reply` should be used in place of `show_reply` ## Dependencies From 6d6baa262191dafaee7d3896ba6e0359db38fcf0 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 8 Mar 2022 17:43:01 +0000 Subject: [PATCH 70/72] rename show_reply to is_falling_back --- proposals/3440-threading-via-relations.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 60084cd0de4..3807a53023f 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -60,14 +60,14 @@ would include additional information in the `unsigned` field: #### Rich replies in a thread Rich replies are still handled via the `m.in_reply_to` field of `m.relates_to`. -However clients should fill in the new `show_reply` property -in order to display that in a thread context. +However clients should specify that this is not a thread fallback by setting +the `is_falling_back` property to `false`. ```json "m.relates_to": { "rel_type": "m.thread", "event_id": "$thread_root", - "show_reply": true, + "is_falling_back": false, "m.in_reply_to": { "event_id": "$event_target" } @@ -88,16 +88,17 @@ A thread will be displayed as a chain of replies on clients unaware of threads. Thread-ready clients should always include an `m.in_reply_to` property when sending a threaded event. It should always reference the latest message-like event in the -thread unless a user is explicitly replying to another event (in which case `hide_reply` -should be set to `false`, as above). - -The rich reply fallback should be ignored by thread-ready clients (ie, the -event should be displayed in a thread context) unless `show_reply` is `reply`. +thread. When sending the event, clients should also specify that `m.in_reply_to` +is a fallback mechanism by setting the `is_falling_back` property to `true`. +If omitted this property will default to `false` and client will treat the +`m.in_reply_to` part of the event as a genuine reply and not as a fallback +mechasnim anymore. ```jsonc "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", + "is_falling_back": true, "m.in_reply_to": { "event_id": "last_event_id_in_thread", } @@ -217,7 +218,7 @@ A `m.thread` event can only reference events that do not have a `rel_type` "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "show_reply": false, + "is_falling_back": true, "m.in_reply_to": { "event_id": "ev1" } @@ -285,7 +286,7 @@ copy in `rel_type` and `event_id` properties in their reply mixin. "m.relates_to": { "rel_type": "m.thread", "event_id": "ev1", - "show_reply": true, + "is_falling_back": false, "m.in_reply_to": { "event_id": "$event_target" } @@ -368,7 +369,7 @@ MSC has not been included in a spec release. in the `RoomEventFilter` * `io.element.relation_types` should be used in place of `related_by_rel_types` in the `RoomEventFilter` - * `io.element.show_reply` should be used in place of `show_reply` + * `io.element.show_reply` should be used in place of `is_falling_back` ## Dependencies From 893cf1fbd1c4c437d87f0ac7c28c14fe32eb2b80 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 8 Mar 2022 13:43:29 -0500 Subject: [PATCH 71/72] Add note about stable support. --- proposals/3440-threading-via-relations.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 3807a53023f..0edb30b446b 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -371,6 +371,10 @@ MSC has not been included in a spec release. in the `RoomEventFilter` * `io.element.show_reply` should be used in place of `is_falling_back` +While this MSC is considered stable, but not in v1.3 of the specification, clients +should look for `org.matrix.msc3440.stable` as an unstable feature flag as part of +the `/versions` API response to determine server support for the stable identifiers. + ## Dependencies This MSC builds on [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), From 641e326f738a98a8fb997915a59918dcebabcff0 Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 9 Mar 2022 09:49:46 +0000 Subject: [PATCH 72/72] Update proposals/3440-threading-via-relations.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3440-threading-via-relations.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/3440-threading-via-relations.md b/proposals/3440-threading-via-relations.md index 0edb30b446b..4a6975d29fd 100644 --- a/proposals/3440-threading-via-relations.md +++ b/proposals/3440-threading-via-relations.md @@ -87,12 +87,13 @@ in the room. A thread will be displayed as a chain of replies on clients unaware of threads. Thread-ready clients should always include an `m.in_reply_to` property when sending -a threaded event. It should always reference the latest message-like event in the -thread. When sending the event, clients should also specify that `m.in_reply_to` -is a fallback mechanism by setting the `is_falling_back` property to `true`. -If omitted this property will default to `false` and client will treat the -`m.in_reply_to` part of the event as a genuine reply and not as a fallback -mechasnim anymore. +a threaded event. Unless the user is explicitly replying to another event (see "Rich replies in a thread", above), +the `m.in_reply_to` property should reference the latest message-like event in the +thread, and clients should also specify that `m.in_reply_to` +is a fallback mechanism (rather than a genuine reply) by setting the `is_falling_back` property to `true`. + +(If omitted, `is_falling_back` defaults to `false`, and receiving clients will treat the +`m.in_reply_to` part of the event as a genuine reply.) ```jsonc "m.relates_to": {