-
Notifications
You must be signed in to change notification settings - Fork 399
MSC2545: Image Packs (Emoticons & Stickers) #2545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Sorunome
wants to merge
55
commits into
matrix-org:old_master
Choose a base branch
from
Sorunome:soru/emotes
base: old_master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+593
−0
Open
Changes from 10 commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
bc55ff6
add emotes proposal
Sorunome 0f4bd5e
add more stuffs
Sorunome 2d191f6
fix naming thingy
Sorunome fa3a8be
fix typo
Sorunome 96f2864
outline room emote packs and emote rooms
Sorunome 81ccecb
remove comma
Sorunome dc43e79
address things
Sorunome 4435d75
update emotes msc
Sorunome 79aae8a
update
Sorunome 4fea69b
Fix typos and grammar mistakes
Sorunome 0e382e0
m.emote --> m.emoticon, update dedupe and pack priority
Sorunome 72b2174
update stuff
Sorunome 2e2987b
add a paragraph over emojis and stuff
Sorunome e8c2e34
Re-word proposal to sound more firm, address lots of suggestions
Sorunome b41c091
specify that emotes can be animated
Sorunome 4f6d147
update msc to also include stickers and thelike
Sorunome 5351cb3
update a few things
Sorunome 12c8fa8
add a few more words on slugs
Sorunome e8d910f
Update proposals/2545-emotes.md
Sorunome a879bcd
license --> attribution
Sorunome 580a836
Update proposals/2545-emotes.md
Sorunome 43f20ad
Merge branch 'soru/emotes' of github.com:Sorunome/matrix-doc into sor…
Sorunome 739b4c0
Update with "looking further" section and slightly update comparison
Sorunome 51bcec2
add a sentance to suggest image packs from spaces
Sorunome 71a3c55
soru bamboozled herself!
Sorunome a7a4a36
Fix small wording and ensure that emotes from canonical spaces are to…
Sorunome be7d0df
Update spelling mistakes and wording, only suggest deduplication meth…
Sorunome b5ca351
fix some typos
anoadragon453 3517a16
Make reference to spec/client naming disparity timeless
anoadragon453 5d62d52
Require `alt` and `title` attributes for emotes
anoadragon453 e5b9c2c
Link `m.sticker` spec; small wording changes
anoadragon453 44c5ed3
Prevent clients from rendering emotes behind non-MXC uri schemes
anoadragon453 ea50cc7
Clarify client requirements around emote resolution
anoadragon453 3c2e29c
Add a new proposal intro
anoadragon453 c429552
Recommend default of 32px for emote height
anoadragon453 d4e9cd2
Specify image formats are equivalent to m.image
anoadragon453 2366ffd
Add grammar and remove de-duplication req
SkyePrism dd84e7f
Add potential issues section
SkyePrism 76da385
Potential issue individual heading
SkyePrism 1cd8168
Add event size limit in potential issues
SkyePrism 628a0a0
Explicitly allow all non-colon characters in the shortcode
SkyePrism 7d399e6
Add definition for shortcode
SkyePrism 645662b
Note that this MSC has no dependents.
anoadragon453 72888d8
Extend security considerations related to image pack lack of encryption
SkyePrism c243748
Update security considerations with full explanation of E2EE concerns
anoadragon453 5663906
polish the MSC
anoadragon453 aa41f7a
Use inline comments in `m.image_pack` example
anoadragon453 8077e81
Apply suggestions from code review
anoadragon453 bccfa91
Justify 32px default height.
anoadragon453 2f14ae1
Disallow spaces in shortcodes.
anoadragon453 d6e4e39
Add `m.image_pack.rooms` state event to reference packs
anoadragon453 8364b10
Add "linking to image pack" to Future Ideas section
anoadragon453 50512fe
Add "abusive images in packs" security concern
anoadragon453 e601f9e
Reorder shown priority of image packs
anoadragon453 d98ffdf
Apply suggestions from code review
anoadragon453 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
# MSC2545: Emotes | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Emotes.....emotes! | ||
|
||
# Proposal | ||
Emotes have at least a shortcode and an mxc uri. They are sent as `<img>` tags currently already in | ||
the spec, as such existing clients *should* be able to render them (support for this is sadly poor, | ||
even within riot flavours). To allow clients to distinguish emotes from other inline images, a new | ||
property `data-mx-emote` is introduced. A client may chose to ignore the size attributes of emotes | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
when rendering, and instead pick the size based on other circumstances. This could e.g. be used to | ||
display emotes in messages with only emotes and emoji larger than usual, which is commonly found in | ||
messengers. Such an `<img>` tag of a shortcode `:emote:` and an mxc uri `mxc://example.org/emote` | ||
could look as follows: | ||
|
||
```html | ||
<img data-mx-emote src="mxc://example.org/emote" alt=":emote:" title=":emote:" height="32" /> | ||
``` | ||
|
||
Both the `alt` and the `title` attributes are specified as they serve different purposes: `alt` is | ||
displayed if e.g. the emote does not load. `title` is displayed e.g. on mouse hover over the emote. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
The height is just a height that looks good on most devices with the normal, default font size. | ||
No width is displayed as to not weirdly squish non-square emotes. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Emote sources | ||
In order to be able to send emotes the client needs to have a list of shortcodes and their corresponding | ||
mxc uris. All the emote sources described here are merely suggestions on where to get emotes from. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
A client is free to implement / design their own way of fetching emotes, e.g. via dropping image files | ||
into a folder and uploading them on-the-fly. For cross-compatibility between clients it'd still be a | ||
good idea to implement the emote sources described here. For this there are two different emote sources: | ||
|
||
### User emotes | ||
User emotes are per-user emotes that are defined in the users respective account data. The type for that | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
is `im.ponies.user_emotes` (later: `m.emotes`). The content is as following: | ||
|
||
```json | ||
{ | ||
"short": { | ||
":emote:": "mxc://example.org/blah", | ||
":other-emote:": "mxc://example.org/other-blah" | ||
} | ||
} | ||
``` | ||
|
||
The emotes are defined inside of a dict called `short`, which stands for shortcode. Other, additional | ||
keys may exist to define more metadata for the emotes. No such guide exists yet. | ||
|
||
### Room emotes | ||
Room emotes are per-room emotes that every user of a specific room can use inside of that room. They | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
are set with a state event of type `im.ponies.room_emotes` (later: `m.emotes`). The state key denotes a possible | ||
pack, whereas the default one would be a blank state key. E.g. a discord bridge could set as state key | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
`de.sorunome.mx-puppet-bridge.discord` and have all the bridged emotes in said state event, keeping | ||
bridged emotes from matrix emotes separate. | ||
|
||
The content extends that of the user emotes: It uses the `short` key, which is a map of the shortcode | ||
of the emote to its mxc uri. Additionally, an optional `pack` key can be set, which defines meta-information | ||
on the pack. The following keys for `pack` are valid: | ||
|
||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- `displayname`: An easy displayname for the pack. Defaults to the room name, if it doesn't exist | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- `avatar_url`: The mxc uri of an avatar/icon to display for the pack. Defaults to the room name, | ||
if it doesn't exist. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- `name`: A short identifier of the pack. Defaults to the normalized state key, and if the state | ||
key is blank it defaults to "room". | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Normalized means here, converting spaces to `-`, taking only alphanumerical characters, `-` and `_`, | ||
and casting it all to lowercase. In regex, this would be `[a-z0-9-_]+`. | ||
|
||
As such, a `im.ponies.room_emotes` (later: `m.emotes`) state event could look like the following: | ||
|
||
```json | ||
{ | ||
"short": { | ||
":emote:": "mxc://example.org/blah", | ||
":other-emote:": "mxc://example.org/other-blah" | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
"pack": { | ||
"displayname": "Emotes from Discord!", | ||
"avatar_url": "mxc://example.org/discord_guild", | ||
"name": "some_discord_guild" | ||
} | ||
} | ||
``` | ||
|
||
### Emote rooms | ||
While room emotes are specific to a room and are only accessible within that room, emote rooms should | ||
be accessible from everywhere. They do not differentiate themselves from room emotes at all, instead you | ||
set an event in your account data of type `im.ponies.emote_rooms` (later: `m.emotes.rooms`) which outlines | ||
which room emote states should be globally accessible for that user. For that, a `room` key contains | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
a map of room ids that map to state keys that map to an optional pack definition override. | ||
If you are currently viewing a room that is in your `im.ponies.emote_rooms` (later: `m.emotes.rooms`) | ||
it is expected that the client de-duplicates the packs, to only give suggestions for it onces. | ||
The the contents of `im.ponies.emote_rooms` (later: `m.emotes.rooms`) could look like the following: | ||
|
||
```json | ||
{ | ||
"rooms": { | ||
"!someroom:example.org": { | ||
"": {}, | ||
"de.sorunome.mx-puppet-bridge.discord": { | ||
"displayname": "Overriden name", | ||
"short": "new_short_name" | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}, | ||
"!someotherroom:example.org": { | ||
"": {} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Here three emote packs are globally accessible to the user: Two defined in `!someroom:example.org` | ||
(one with blank state key and one with state key `de.sorunome.mx-puppet-bridge.discord`) and one in | ||
`!someotherroom:example.org`. | ||
|
||
## Sending | ||
In places where fancy tab-complete with the emote itself is not possible it is suggested that sending | ||
the shortcode will convert to the img tag, e.g. sending `Hey there :wave:` will convert to `Hey there <img-for-wave>`. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If there are collisions due to the same emote shortcode being present as both room emote and user emote | ||
a user could specify the emote source by writing e.g. `:room~wave:` or `:user~wave:`. Here the short | ||
pack name is used for room emotes, and "user" for user emotes. If a room pack does not have a short | ||
pack name and has a blank state key, then "room" is used. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Ideas | ||
- ??? | ||
|
||
# Current implementations | ||
## Emote rendering (rendering of the `<img>` tag) | ||
- riot-web | ||
- revolution | ||
- nheko | ||
- fluffychat | ||
## Emote sending, using the mentioned events here | ||
- revolution | ||
- fluffychat | ||
|
||
# Security Considerations | ||
When sending an `<img>` tag in an end-to-end encrypted room, the client will make a request to fetch | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
said image, in this case an emote. As there is no way to encrypt content behind `<img>` tags yet, | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this could potentially leak part of the conversation. This is **not** a new security consideration, | ||
it already exists. This, however, isn't much different from posting someone a link in an e2ee chat and | ||
the recipient opens the link. Additionally, images, and thus emotes, are often cached by the client, | ||
not even necessarily leading to an http query. | ||
|
||
# Alternatives | ||
One can easily think of near infinite ways to implement emotes. The aspect of sending an `<img>` tag | ||
and marking it as an emote with `data-mx-emote` seems to be pretty universal though, so the question | ||
is mainly on different emote sources. For that, a separate MSC, [MSC1951](https://github.com/matrix-org/matrix-doc/pull/1951) | ||
already exists, so it is reasonable to compare this one with that one: | ||
|
||
## Comparison with MSC1951 | ||
MSC1951 defines a dedicated room as the only emote source. This MSC, however, also allows you to bind emotes | ||
to your own account, offering greater flexibility. In MSC1951 there can also only be a single emote | ||
pack in a room. This could be problematic in e.g. bridged rooms: You set some emotes from the matrix | ||
side and a discord bridge would plop all the discord emotes in another pack in the same room. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
MSC1951 defines a way to recommend using a pack of a different room - this MSC does not have an equivalent | ||
to that. Instead, this MSC allows multiple emote packs for a room, and allows you to enable an emote | ||
pack to be globally available for yourself across all rooms you are in. | ||
|
||
The core difference is how MSC1951 and this MSC define the emotes themselves: In MSC1951 you have to | ||
set one state event *per emote*. While this might seem like a nice idea on the surface, it doesn't | ||
scale well. There are people who easily use and want hundreds or even thousands of emotes accessible. | ||
A simple dict of shortcode to mxc URI seems more appropriate for this. | ||
|
||
Additionally, this MSC has already been used in the wild for roughly two years by some clients, while MSC1951 | ||
only exists in MSC form. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
In general, MSC1951 feels like a heavier approach to emote sourcs, while this MSC is more lightweight | ||
and thus should allow for significantly larger packs. | ||
Sorunome marked this conversation as resolved.
Show resolved
Hide resolved
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.