mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-03-26 13:04:10 +01:00
Apply suggestions from code review
Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
parent
3abe913f5d
commit
091d1f032c
|
|
@ -7,7 +7,7 @@ type: module
|
||||||
{{% added-in v="1.4" %}}
|
{{% added-in v="1.4" %}}
|
||||||
|
|
||||||
Event replacements, or "message edit events", are events that use an [event
|
Event replacements, or "message edit events", are events that use an [event
|
||||||
relationship](http://localhost:1313/client-server-api/#forming-relationships-between-events)
|
relationship](#forming-relationships-between-events)
|
||||||
with a `rel_type` of `m.replace`, which indicates that the original event is
|
with a `rel_type` of `m.replace`, which indicates that the original event is
|
||||||
intended to be replaced.
|
intended to be replaced.
|
||||||
|
|
||||||
|
|
@ -46,17 +46,17 @@ an event's content property, such as `formatted_body` (see [`m.room.message`
|
||||||
There are a number of requirements on message edit events, which must be satisfied for the replacement to be considered valid:
|
There are a number of requirements on message edit events, which must be satisfied for the replacement to be considered valid:
|
||||||
|
|
||||||
* As with all event relationships, the original event and replacement event
|
* As with all event relationships, the original event and replacement event
|
||||||
must have the same `room_id` (i.e. it is not possible to send an event in
|
must have the same `room_id` (i.e. you cannot send an event in
|
||||||
one room and then an edited version in a different room).
|
one room and then an edited version in a different room).
|
||||||
|
|
||||||
* The original event and replacement event must have the same `sender`
|
* The original event and replacement event must have the same `sender`
|
||||||
(i.e. you cannot edit someone else's messages).
|
(i.e. you cannot edit someone else's messages).
|
||||||
|
|
||||||
* The replacement and original events must have the same `type` (i.e. editing
|
* The replacement and original events must have the same `type` (i.e. you
|
||||||
an event cannot change its type).
|
cannot change the original event's type).
|
||||||
|
|
||||||
* Neither the replacement nor original events may have a `state_key` property
|
* The replacement and original events must not have a `state_key` property
|
||||||
(i.e. it is not possible to edit a state event).
|
(i.e. you cannot edit state events at all).
|
||||||
|
|
||||||
* The original event must not, itself, have a `rel_type` of `m.replace`
|
* The original event must not, itself, have a `rel_type` of `m.replace`
|
||||||
(i.e. you cannot edit an edit — though you can send multiple edits for a
|
(i.e. you cannot edit an edit — though you can send multiple edits for a
|
||||||
|
|
@ -70,7 +70,7 @@ replacement event (the content of the original should not be replaced, and the
|
||||||
edit should not be included in the server-side aggregation).
|
edit should not be included in the server-side aggregation).
|
||||||
|
|
||||||
Note that the [`msgtype`](#mroommessage-msgtypes) property of replacement
|
Note that the [`msgtype`](#mroommessage-msgtypes) property of replacement
|
||||||
`m.room.message` events need *not* be the same as in the original event. For
|
`m.room.message` events does *not* need to be the same as in the original event. For
|
||||||
example, it is legitimate to replace an `m.text` event with an `m.emote`.
|
example, it is legitimate to replace an `m.text` event with an `m.emote`.
|
||||||
|
|
||||||
#### Editing encrypted events
|
#### Editing encrypted events
|
||||||
|
|
@ -82,8 +82,6 @@ must be sent in the unencrypted (cleartext) part of the event.
|
||||||
|
|
||||||
For example, a replacement for an encrypted event might look like this:
|
For example, a replacement for an encrypted event might look like this:
|
||||||
|
|
||||||
For example, an encrypted replacement event might look like this:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "m.room.encrypted",
|
"type": "m.room.encrypted",
|
||||||
|
|
@ -98,7 +96,7 @@ For example, an encrypted replacement event might look like this:
|
||||||
"session_id": "<outbound_group_session_id>",
|
"session_id": "<outbound_group_session_id>",
|
||||||
"ciphertext": "<encrypted_payload_base_64>"
|
"ciphertext": "<encrypted_payload_base_64>"
|
||||||
}
|
}
|
||||||
// ...
|
// irrelevant fields not shown
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -121,10 +119,14 @@ For example, an encrypted replacement event might look like this:
|
||||||
|
|
||||||
Note that:
|
Note that:
|
||||||
|
|
||||||
* There is no `m.relates_to` property in the encrypted payload. (Any such property would be ignored.)
|
* There is no `m.relates_to` property in the encrypted payload. If there was, it would be ignored.
|
||||||
* There is no `m.new_content` property in the cleartext content of the `m.room.encrypted` event. (Again, any such property would be ignored.)
|
* There is no `m.new_content` property in the cleartext content of the `m.room.encrypted` event. As above, if there was then it would be ignored.
|
||||||
|
|
||||||
The payload of an encrypted replacement event must be encrypted as normal, including ratcheting any [Megolm](#mmegolmv1aes-sha2) session as normal. The original Megolm ratchet entry should **not** be re-used.
|
{{% boxes/note %}}
|
||||||
|
The payload of an encrypted replacement event must be encrypted as normal, including
|
||||||
|
ratcheting any [Megolm](#mmegolmv1aes-sha2) session as normal. The original Megolm
|
||||||
|
ratchet entry should **not** be re-used.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
|
|
||||||
#### Applying `m.new_content`
|
#### Applying `m.new_content`
|
||||||
|
|
@ -199,13 +201,13 @@ most recent event is determined by comparing `origin_server_ts`; if two or more
|
||||||
replacement events have identical `origin_server_ts`, the event with the
|
replacement events have identical `origin_server_ts`, the event with the
|
||||||
lexicographically largest `event_id` is treated as more recent.
|
lexicographically largest `event_id` is treated as more recent.
|
||||||
|
|
||||||
This aggregation is bundled into the `unsigned/m.relations` property of any
|
This aggregation is bundled under the `unsigned` property as `m.relations` for any
|
||||||
event that is the target of an `m.replace` relationship. For example:
|
event that is the target of an `m.replace` relationship. For example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"event_id": "$original_event_id",
|
"event_id": "$original_event_id",
|
||||||
// ...
|
// irrelevant fields not shown
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
"m.relations": {
|
"m.relations": {
|
||||||
"m.replace": {
|
"m.replace": {
|
||||||
|
|
@ -219,13 +221,13 @@ event that is the target of an `m.replace` relationship. For example:
|
||||||
```
|
```
|
||||||
|
|
||||||
If the original event is
|
If the original event is
|
||||||
[redacted](http://localhost:1313/client-server-api/#redactions), any
|
[redacted](#redactions), any
|
||||||
`m.replace` relationship should **not** be bundled with it (whether or not any
|
`m.replace` relationship should **not** be bundled with it (whether or not any
|
||||||
subsequent replacements are themselves redacted). Note that this behaviour is
|
subsequent replacements are themselves redacted). Note that this behaviour is
|
||||||
specific to the `m.replace` relationship. See also [redactions of edited
|
specific to the `m.replace` relationship. See also [redactions of edited
|
||||||
events](#redactions-of-edited-events) below.
|
events](#redactions-of-edited-events) below.
|
||||||
|
|
||||||
#### Server-side replacement of content
|
##### Server-side replacement of content
|
||||||
|
|
||||||
Whenever an `m.replace` is to be bundled with an event as above, the server
|
Whenever an `m.replace` is to be bundled with an event as above, the server
|
||||||
should also modify the content of the original event according to the
|
should also modify the content of the original event according to the
|
||||||
|
|
@ -237,9 +239,9 @@ be bundled, as described above).
|
||||||
|
|
||||||
#### Client behaviour
|
#### Client behaviour
|
||||||
|
|
||||||
Clients can often ignore `m.replace` events, since any events the server
|
Clients can often ignore `m.replace` events, because any events returned
|
||||||
returns via the C-S API will be updated by the server to account for subsequent
|
by the server to the client will be updated by the server to account for
|
||||||
edits.
|
subsequent edits.
|
||||||
|
|
||||||
However, clients should apply the replacement themselves when the server is
|
However, clients should apply the replacement themselves when the server is
|
||||||
unable to do so. This happens in the following situations:
|
unable to do so. This happens in the following situations:
|
||||||
|
|
@ -251,7 +253,7 @@ unable to do so. This happens in the following situations:
|
||||||
|
|
||||||
Client authors are reminded to take note of the requirements for [Validity of
|
Client authors are reminded to take note of the requirements for [Validity of
|
||||||
message edit events](#validity-of-message-edit-events), and to ignore any
|
message edit events](#validity-of-message-edit-events), and to ignore any
|
||||||
invalid edit events that may be received.
|
invalid edit events that are received.
|
||||||
|
|
||||||
##### Permalinks
|
##### Permalinks
|
||||||
|
|
||||||
|
|
@ -274,7 +276,8 @@ subsequent edits, from the visible timeline. In this situation, homeservers
|
||||||
will return an empty `content` for the original event as with any other
|
will return an empty `content` for the original event as with any other
|
||||||
redacted event, and as
|
redacted event, and as
|
||||||
[above](#server-side-aggregation-of-mreplace-relationships) the replacement
|
[above](#server-side-aggregation-of-mreplace-relationships) the replacement
|
||||||
events will not be bundled with the original event.
|
events will not be bundled with the original event. Note that the subsequent edits are
|
||||||
|
not actually redacted themselves: they simply serve no purpose within the visible timeline.
|
||||||
|
|
||||||
#### Edits of replies
|
#### Edits of replies
|
||||||
|
|
||||||
|
|
@ -283,13 +286,13 @@ Some particular constraints apply to events which replace a
|
||||||
|
|
||||||
* In contrast to the original reply, there should be no `m.in_reply_to`
|
* In contrast to the original reply, there should be no `m.in_reply_to`
|
||||||
property in the the `m.relates_to` object, since it would be redundant (see
|
property in the the `m.relates_to` object, since it would be redundant (see
|
||||||
[Applying `m.new_content`](/#applying-mnew_content) above, which notes that
|
[Applying `m.new_content`](#applying-mnew_content) above, which notes that
|
||||||
the original event's `m.relates_to` is preserved), as well as being contrary
|
the original event's `m.relates_to` is preserved), as well as being contrary
|
||||||
to the spirit of the event relationships mechanism which expects only one
|
to the spirit of the event relationships mechanism which expects only one
|
||||||
"parent" per event.
|
"parent" per event.
|
||||||
|
|
||||||
* `m.new_content` should **not** contain any [reply
|
* `m.new_content` should **not** contain any [reply
|
||||||
fallback](https://spec.matrix.org/v1.3/client-server-api/#fallbacks-for-rich-replies),
|
fallback](#fallbacks-for-rich-replies),
|
||||||
since it is assumed that any client which can handle edits can also display
|
since it is assumed that any client which can handle edits can also display
|
||||||
replies natively. However, the `content` of the replacement event should provide
|
replies natively. However, the `content` of the replacement event should provide
|
||||||
fallback content for clients which support neither rich replies nor edits.
|
fallback content for clients which support neither rich replies nor edits.
|
||||||
|
|
@ -299,6 +302,7 @@ An example of an edit to a reply is as follows:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "m.room.message",
|
"type": "m.room.message",
|
||||||
|
// irrelevant fields not shown
|
||||||
"content": {
|
"content": {
|
||||||
"body": "> <@alice:example.org> question\n\n* reply",
|
"body": "> <@alice:example.org> question\n\n* reply",
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue