Power level tags (MSC3949): named, coloured power levels #67

Open
opened 2026-10-06 21:04:46 +00:00 by robocub · 0 comments
Member

Support MSC3949 power level tags: a room can give any power level number a name, colour and icon, for example 50 = "Moderator" in green, or 38 = "Bot" 🤖.

Scope: this labels power levels and nothing more. It is not an attempt to copy Discord roles. Real roles (several per user, allow/deny per permission) need MSC4056, which requires a new room version and has no implementation. Labelled power levels are useful without that.

Format

State event with an empty state_key. The unstable type is in.cinny.room.power_level_tags and the stable type will be m.room.power_level_tags; read both and prefer the stable one. The content maps a power level number (as a string) to a tag:

{
  "100": { "name": "Admin", "color": "#e5484d",
           "icon": { "key": "mxc://…", "info": { "w": 152, "h": 152, "mimetype": "image/webp" } } },
  "50":  { "name": "Moderator", "color": "#30a46c" },
  "38":  { "name": "Bot", "icon": { "key": "🤖" } }
}
  • name is required. color is a hex string. icon.key is either an emoji or an mxc:// URL.
  • Levels with no tag: use the nearest lower tagged level. If no lower level is tagged, fall back to today's built-in Member/Moderator/Admin/Owner.
  • No event in the room: behave exactly as today.

Cinny already implements this, so the format is shared with at least one other client. The MSC is open and marked needs-implementation, so Vommet would count as another implementation.

Where it hooks in

  • client/matrix/matrix_role.dart: MatrixRole already takes nameOverride and iconOverride. Add a colour, an image or emoji icon, and lookup from the tags event.
  • ui/atoms/role_view.dart: render the colour and the emoji or mxc icon.
  • Member list: group members by tag, ordered by power level from highest to lowest.
  • Timeline: colour sender names by tag. This should be optional, because it conflicts with the per-user name colours.
  • Room/space settings → Permissions: let users add, edit and remove tags (name, colour picker, emoji or uploaded image). Write the unstable type until the MSC merges.

Open questions

  • Spaces: should a child room without its own tags use the parent space's tags? Check what Cinny does first, so the two clients match.
  • Room v12 creators (infinite power level, MSC4289): show them as "Owner" or with the highest tag, and keep creator rendering correct (upstream commetchat/commet#815).
  • Readability: adjust tag colours for contrast in light and dark themes, as the MSC allows.

Upstream

Same request upstream: commetchat/commet#625 (open feature request, no PR or branch as of 2026-10-06). Related: #59 (moderation tools, permissions editor).

Support [MSC3949 power level tags](https://github.com/matrix-org/matrix-spec-proposals/pull/3949): a room can give any power level number a **name, colour and icon**, for example 50 = "Moderator" in green, or 38 = "Bot" 🤖. **Scope:** this labels power levels and nothing more. It is not an attempt to copy Discord roles. Real roles (several per user, allow/deny per permission) need [MSC4056](https://github.com/matrix-org/matrix-spec-proposals/pull/4056), which requires a new room version and has no implementation. Labelled power levels are useful without that. ## Format State event with an empty `state_key`. The unstable type is `in.cinny.room.power_level_tags` and the stable type will be `m.room.power_level_tags`; read both and prefer the stable one. The content maps a power level number (as a string) to a tag: ```json { "100": { "name": "Admin", "color": "#e5484d", "icon": { "key": "mxc://…", "info": { "w": 152, "h": 152, "mimetype": "image/webp" } } }, "50": { "name": "Moderator", "color": "#30a46c" }, "38": { "name": "Bot", "icon": { "key": "🤖" } } } ``` - `name` is required. `color` is a hex string. `icon.key` is either an emoji or an `mxc://` URL. - **Levels with no tag:** use the nearest *lower* tagged level. If no lower level is tagged, fall back to today's built-in Member/Moderator/Admin/Owner. - **No event in the room:** behave exactly as today. Cinny already implements this, so the format is shared with at least one other client. The MSC is open and marked `needs-implementation`, so Vommet would count as another implementation. ## Where it hooks in - `client/matrix/matrix_role.dart`: `MatrixRole` already takes `nameOverride` and `iconOverride`. Add a colour, an image or emoji icon, and lookup from the tags event. - `ui/atoms/role_view.dart`: render the colour and the emoji or mxc icon. - Member list: group members by tag, ordered by power level from highest to lowest. - Timeline: colour sender names by tag. This should be optional, because it conflicts with the per-user name colours. - Room/space settings → Permissions: let users add, edit and remove tags (name, colour picker, emoji or uploaded image). Write the unstable type until the MSC merges. ## Open questions - **Spaces:** should a child room without its own tags use the parent space's tags? Check what Cinny does first, so the two clients match. - **Room v12 creators** (infinite power level, MSC4289): show them as "Owner" or with the highest tag, and keep creator rendering correct (upstream commetchat/commet#815). - **Readability:** adjust tag colours for contrast in light and dark themes, as the MSC allows. ## Upstream Same request upstream: commetchat/commet#625 (open feature request, no PR or branch as of 2026-10-06). Related: #59 (moderation tools, permissions editor).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nether/vommet#67
No description provided.