diff --git a/api/client-server/v1/rooms.yaml b/api/client-server/v1/rooms.yaml index 90b51290..ff5587a9 100644 --- a/api/client-server/v1/rooms.yaml +++ b/api/client-server/v1/rooms.yaml @@ -311,7 +311,11 @@ paths: "user_id": "@alice:example.com" } ], - "visibility": "private" + "visibility": "private", + "account_data": [{ + "type": "m.tag", + "content": {"tags": {"work": {"order": "1"}}} + }] } schema: title: RoomInfo @@ -371,6 +375,15 @@ paths: description: |- Whether this room is visible to the ``/publicRooms`` API or not." + account_data: + type: array + description: |- + The private data that this user has attached to this room. + items: + title: Event + type: object + allOf: + - "$ref": "core-event-schema/event.json" required: ["room_id"] 403: description: > diff --git a/api/client-server/v1/sync.yaml b/api/client-server/v1/sync.yaml index d07e9399..973ccc6e 100644 --- a/api/client-server/v1/sync.yaml +++ b/api/client-server/v1/sync.yaml @@ -245,7 +245,11 @@ paths: "user_id": "@alice:localhost" } ], - "visibility": "private" + "visibility": "private", + "account_data": [{ + "type": "m.tag", + "content": {"tags": {"work": {"order": "1"}}} + }] } ] } @@ -332,6 +336,16 @@ paths: description: |- Whether this room is visible to the ``/publicRooms`` API or not." + account_data: + type: array + description: |- + The private data that this user has attached to + this room. + items: + title: Event + type: object + allOf: + - "$ref": "core-event-schema/event.json" required: ["room_id", "membership"] required: ["end", "rooms", "presence"] 404: diff --git a/api/client-server/v2_alpha/sync.yaml b/api/client-server/v2_alpha/sync.yaml index 0c9d6186..6f2f1412 100644 --- a/api/client-server/v2_alpha/sync.yaml +++ b/api/client-server/v2_alpha/sync.yaml @@ -132,6 +132,14 @@ paths: e.g. typing. allOf: - $ref: "definitions/event_batch.json" + account_data: + title: Account Data + type: object + description: |- + The private data that this user has attached to + this room. + allOf: + - $ref: "definitions/event_batch.json" invite: title: Invited Rooms type: object @@ -252,6 +260,14 @@ paths: "content": {"user_ids": ["@alice:example.com"]} } ] + }, + "account_data": { + "events": [ + { + "type": "m.tag", + "content": {"tags": {"work": {"order": "1"}}} + } + ] } } }, diff --git a/api/client-server/v2_alpha/tags.yaml b/api/client-server/v2_alpha/tags.yaml new file mode 100644 index 00000000..91945dca --- /dev/null +++ b/api/client-server/v2_alpha/tags.yaml @@ -0,0 +1,147 @@ +swagger: '2.0' +info: + title: "Matrix Client-Server tag API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/v2_alpha +consumes: + - application/json +produces: + - application/json +securityDefinitions: + accessToken: + type: apiKey + description: The user_id or application service access_token + name: access_token + in: query +paths: + "/user/{userId}/rooms/{roomId}/tags": + get: + summary: List the tags for a room. + description: |- + List the tags set by a user on a room. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: userId + required: true + description: |- + The id of the user to get tags for. The access token must be + authorized to make requests for this user id. + x-example: "@alice:example.com" + - in: path + type: string + name: roomId + required: true + description: |- + The id of the room to get tags for. + x-example: "!726s6s6q:example.com" + responses: + 200: + description: + The list of tags for the user for the room. + schema: + type: object + properties: + tags: + title: Tags + type: object + examples: + application/json: |- + { + "tags": { + "work": {"order": "1"}, + "pinned": {} + } + } + "/user/{userId}/rooms/{roomId}/tags/{tag}": + put: + summary: Add a tag to a room. + description: |- + Add a tag to the room. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: userId + required: true + description: |- + The id of the user to add a tag for. The access token must be + authorized to make requests for this user id. + x-example: "@alice:example.com" + - in: path + type: string + name: roomId + required: true + description: |- + The id of the room to add a tag to. + x-example: "!726s6s6q:example.com" + - in: path + type: string + name: tag + required: true + description: |- + The tag to add. + x-example: "work" + - in: body + name: body + required: true + description: |- + Extra data for the tag, e.g. ordering. + schema: + type: object + example: |- + {"order": "1"} + responses: + 200: + description: + The tag was successfully added. + schema: + type: object + examples: + application/json: |- + {} + delete: + summary: Remove a tag from the room. + description: |- + Remove a tag from the room. + security: + - access_token: [] + parameters: + - in: path + type: string + name: userId + required: true + description: |- + The id of the user to remove a tag for. The access token must be + authorized to make requests for this user id. + x-example: "@alice:example.com" + - in: path + type: string + name: roomId + required: true + description: |- + The id of the room to remove a tag from. + x-example: "!726s6s6q:example.com" + - in: path + type: string + name: tag + required: true + description: |- + The tag to remove. + x-example: "work" + responses: + 200: + description: + The tag was successfully removed + schema: + type: object + examples: + application/json: |- + {} diff --git a/event-schemas/examples/v1/m.tag b/event-schemas/examples/v1/m.tag new file mode 100644 index 00000000..00e81060 --- /dev/null +++ b/event-schemas/examples/v1/m.tag @@ -0,0 +1,8 @@ +{ + "type": "m.tag", + "content": { + "tags": { + "work": {"order": 1} + } + } +} diff --git a/event-schemas/schema/v1/m.tag b/event-schemas/schema/v1/m.tag new file mode 100644 index 00000000..4c5b4fa5 --- /dev/null +++ b/event-schemas/schema/v1/m.tag @@ -0,0 +1,25 @@ +{ + "type": "object", + "title": "Tag Event", + "description": "Informs the client of tags on a room.", + "properties": { + "type": { + "type": "string", + "enum": ["m.tag"] + }, + "content": { + "type": "object", + "properties": { + "tags": { + "type": "object", + "description": "The tags on the room and their contents.", + "additionalProperties": { + "title": "Tag", + "type": "object" + } + } + } + } + }, + "required": ["type", "content"] +} diff --git a/specification/modules/tags.rst b/specification/modules/tags.rst new file mode 100644 index 00000000..bb467bc0 --- /dev/null +++ b/specification/modules/tags.rst @@ -0,0 +1,48 @@ +Room Tagging +============ + +.. _module:tagging: + +Users can add tags to rooms. Tags are short strings used to label rooms, e.g. +"work", "family". A room may have multiple tags. Tags are only visible to the +user that set them but are shared across all their devices. + +Events +------ + +The tags on a room are received as single ``m.tag`` event in the +``account_data`` section of a room in a v2 /sync. + +The ``m.tag`` can also be received in a v1 /events response or in the +``account_data`` section of a room in v1 /initialSync. ``m.tag`` +events appearing in v1 /events will have a ``room_id`` with the room +the tags are for. + +Each tag has an associated JSON object with information about the tag, e.g how +to order the rooms with a given tag. + +Ordering information is given under the ``order`` key as a string. The string +are compared lexicographically by unicode codepoint to determine which should +displayed first. So a room with a tag with an ``order`` key of ``"apples"`` +would appear before a room with a tag with an ``order`` key of ``"oranges"``. +If a room has a tag without an ``order`` key then it should appear after the +rooms with that tag that have an ``order`` key. + +The name of a tag MUST not exceed 255 bytes. + +The name of a tag should be human readable. When displaying tags for a room a +client should display this human readable name. When adding a tag for a room +a client may offer a list to choose from that includes all the tags that the +user has previously set on any of their rooms. + +Two special names are listed in the specification: + +* ``m.favourite`` +* ``m.lowpriority`` + +{{m_tag_event}} + +Client Behaviour +---------------- + +{{v2_tags_http_api}} diff --git a/specification/targets.yaml b/specification/targets.yaml index 8e6a2ce0..caae953f 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -26,6 +26,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/third_party_invites.rst - modules/search.rst - modules/guest_access.rst + - modules/tags.rst title_styles: ["=", "-", "~", "+", "^", "`"]