From 04397076248040937783101d12c86010cbb08f93 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 13 May 2025 17:01:25 +0200 Subject: [PATCH] Spec PR - MSC3765: Rich text in room topics (#2095) Signed-off-by: Johannes Marbach --- .../client_server/newsfragments/2095.feature | 1 + .../server_server/newsfragments/2095.feature | 1 + content/client-server-api/modules/search.md | 7 ++-- data/api/client-server/create_room.yaml | 14 ++++---- .../definitions/public_rooms_chunk.yaml | 4 ++- data/event-schemas/examples/m.room.topic.yaml | 10 +++++- .../components/m_text_content_block.yaml | 28 +++++++++++++++ data/event-schemas/schema/m.room.topic.yaml | 35 +++++++++++++++---- 8 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2095.feature create mode 100644 changelogs/server_server/newsfragments/2095.feature create mode 100644 data/event-schemas/schema/components/m_text_content_block.yaml diff --git a/changelogs/client_server/newsfragments/2095.feature b/changelogs/client_server/newsfragments/2095.feature new file mode 100644 index 00000000..0a993bbb --- /dev/null +++ b/changelogs/client_server/newsfragments/2095.feature @@ -0,0 +1 @@ +Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). diff --git a/changelogs/server_server/newsfragments/2095.feature b/changelogs/server_server/newsfragments/2095.feature new file mode 100644 index 00000000..0a993bbb --- /dev/null +++ b/changelogs/server_server/newsfragments/2095.feature @@ -0,0 +1 @@ +Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). diff --git a/content/client-server-api/modules/search.md b/content/client-server-api/modules/search.md index 8115d5be..2705aa66 100644 --- a/content/client-server-api/modules/search.md +++ b/content/client-server-api/modules/search.md @@ -26,9 +26,10 @@ on certain keys of certain event types. The supported keys to search over are: -- `content.body` in `m.room.message` -- `content.name` in `m.room.name` -- `content.topic` in `m.room.topic` +- `content.body` in [`m.room.message`](/client-server-api/#mroommessage) +- `content.name` in [`m.room.name`](/client-server-api/#mroomname) +- In [`m.room.topic`](/client-server-api/#mroomtopic), `content.topic` + as well as the `body` of the `text/plain` representation in `content['m.topic']`. The search will *not* include rooms that are end to end encrypted. diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index 3992fdfe..03a85443 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -109,15 +109,17 @@ paths: name: type: string description: |- - If this is included, an `m.room.name` event will be sent - into the room to indicate the name of the room. See Room - Events for more information on `m.room.name`. + If this is included, an [`m.room.name`](/client-server-api/#mroomname) event + will be sent into the room to indicate the name for the room. + This overwrites any [`m.room.name`](/client-server-api/#mroomname) + event in `initial_state`. topic: type: string description: |- - If this is included, an `m.room.topic` event will be sent - into the room to indicate the topic for the room. See Room - Events for more information on `m.room.topic`. + If this is included, an [`m.room.topic`](/client-server-api/#mroomtopic) + event with a `text/plain` mimetype will be sent into the room + to indicate the topic for the room. This overwrites any + [`m.room.topic`](/client-server-api/#mroomtopic) event in `initial_state`. invite: type: array description: |- diff --git a/data/api/client-server/definitions/public_rooms_chunk.yaml b/data/api/client-server/definitions/public_rooms_chunk.yaml index 9c6ae6fc..64786432 100644 --- a/data/api/client-server/definitions/public_rooms_chunk.yaml +++ b/data/api/client-server/definitions/public_rooms_chunk.yaml @@ -33,7 +33,9 @@ properties: example: "!abcdefg:example.org" topic: type: string - description: The topic of the room, if any. + description: |- + The plain text topic of the room. Omitted if no `text/plain` mimetype + exists in [`m.room.topic`](/client-server-api/#mroomtopic). example: "All things general" world_readable: type: boolean diff --git a/data/event-schemas/examples/m.room.topic.yaml b/data/event-schemas/examples/m.room.topic.yaml index 69e5d4f1..993145a6 100644 --- a/data/event-schemas/examples/m.room.topic.yaml +++ b/data/event-schemas/examples/m.room.topic.yaml @@ -3,6 +3,14 @@ "type": "m.room.topic", "state_key": "", "content": { - "topic": "A room topic" + "m.topic": { + "m.text": [ { + "mimetype": "text/html", + "body": "An interesting room topic" + }, { + "body": "An interesting room topic" + }] + }, + "topic": "An interesting room topic" } } diff --git a/data/event-schemas/schema/components/m_text_content_block.yaml b/data/event-schemas/schema/components/m_text_content_block.yaml new file mode 100644 index 00000000..29c8d148 --- /dev/null +++ b/data/event-schemas/schema/components/m_text_content_block.yaml @@ -0,0 +1,28 @@ +type: array +description: |- + An ordered array of textual representations in different mimetypes. + + Senders SHOULD specify at least one representation and SHOULD always + include a plaintext representation. + + Receivers SHOULD use the first representation in the array that + they understand. +title: TextContentBlock +items: + type: object + title: TextualRepresentation + properties: + mimetype: + type: string + description: The mimetype. Defaults to `text/plain` if omitted. + example: "text/html" + body: + type: string + description: |- + The string content. + + Clients SHOULD validate and sanitize the content as they do + for rich content associated with [`msgtype`](/client-server-api/#mroommessage-msgtypes) + of [`m.room.message`](/client-server-api/#mroommessage). + required: + - body diff --git a/data/event-schemas/schema/m.room.topic.yaml b/data/event-schemas/schema/m.room.topic.yaml index 56f0caf9..580566d2 100644 --- a/data/event-schemas/schema/m.room.topic.yaml +++ b/data/event-schemas/schema/m.room.topic.yaml @@ -1,20 +1,41 @@ --- allOf: - $ref: core-event-schema/state_event.yaml -description: |- - A topic is a short message detailing what is currently being discussed in the room. - It can also be used as a way to display extra information about the room, which may not - be suitable for the room name. - The room topic can also be set when creating a room using `/createRoom` with the `topic` key.' - +description: |- + A topic is a short message detailing what is currently being discussed + in the room. It can also be used as a way to display extra information + about the room, which may not be suitable for the room name. The room + topic can also be set when creating a room using + [`/createRoom`](client-server-api/#post_matrixclientv3createroom), either + with the `topic` key or by specifying a full event in `initial_state`. + If the `topic` property is absent, null, or empty then the topic is unset. In other words, an empty `topic` property effectively resets the room to having no topic. + + In order to prevent formatting abuse in room topics, clients SHOULD + limit the length of topics during both entry and display, for instance, + by capping the number of displayed lines. Additionally, clients SHOULD + ignore things like headings and enumerations (or format them as regular + text). properties: content: properties: topic: - description: The topic text. + description: |- + The topic in plain text. + + This SHOULD duplicate the content of the `text/plain` + representation in `m.topic` if any exists. type: string + m.topic: + type: object + title: TopicContentBlock + x-addedInMatrixVersion: "1.15" + description: |- + Textual representation of the room topic in different mimetypes. + properties: + m.text: + $ref: components/m_text_content_block.yaml required: - topic type: object