Description
Purpose and constraints
The purpose of this issue is to document how the preferred rendering for content and styles should be in root messages (only in the thread list) and thread summaries (both in the main timeline and thread list) for the Threads MVP.
We're trying to set a baseline for every client, on which we'll improve later on. While some of these in their current form are far from ideal (e.g., spoilers being spoiled), we can't address all the current issues within the scope of Threads MVP.
For this first iteration we have taken the current implementation for Web as the reference implementation.
The next step, after the Threads MVP, will be figuring out how to improve the spec, and make it more usable, which includes revisiting how we render the different content types and formatting styles in the context of threads (root messages, thread summaries).
Platform issues
- Remove mentions decorations for root messages in the thread list element-web#20870
- Emotes and Rainbow emotes as the root message for a thread break the layout for thread tiles element-web#20869
- Fix rendering of content types and formatting styles in root messages and thread summaries element-android#5139
- Fix rendering of content types and formatting styles in root messages and thread summaries element-ios#5488
Legend
- ✅ Rendered as expected for the Threads MVP.
- ❌ Fails to render as expected for the Threads MVP.
- 🗒 Deviation from the expected rendering but we don't plan to change this for the Threads MVP.
- 🔮 The test case couldn't be performed.
Case | Web | Android | iOS |
---|---|---|---|
Mentions: render as plain text (e.g. @Name is rendered as Name ) |
✅ | ✅ | ✅ |
URLs: render as plain text (e.g. https://element.io gets rendered as non-clickable plain text https://element.io ) |
✅ | ✅ | ✅ |
Text links: render as plain text (e.g. [Element](https://element.io) gets rendered as non-clickable plain text Element ) |
✅ | ✅ | ✅ |
Link previews: do not render | ✅ | ✅ | ✅ |
Markdown: strip tags, linearize (render it as a single line, without new lines), and render it as plain text (e.g. ## Heading is rendered as Heading ) |
✅ | ✅ | ❌ root message (renders Markdown) |
Horizontal ruler: render as plain text (e.g. a message containing only this sequence of characters --- is rendered as --- ) |
❌ root message (blank) ❌ thread summary (blank) |
❌ root message (blank) ❌ thread summary (blank) |
❌ root message (blank) ❌ thread summary (blank) ❌ main timeline (not rendered) |
HTML: strip tags, linearize (render it as a single line, without new lines), and render it as plain text (e.g. <h2>Heading</h2> is rendered as Heading ) |
✅ | 🗒 preamature text truncation | ❌ root message (renders HTML) |
Inline formatting (bold, italics, strikethrough): rendered as undecorated plain text (e.g. **bold** is rendered as bold ) |
✅ | ✅ | ❌ root message (renders formatting) |
Code blocks: linearize (don't render new lines) and render it as undecorated plain text without backticks (e.g. multiline text that is wrapped with backticks ) |
✅ | ❌ root message (empty first line, and ellipsis in second line) 🗒 preamature text truncation |
❌ root message (renders formatted blocks) ❌ thread summary (plain text but renders new lines) |
Inline code snippets: render as plain text without backticks (e.g. timeline { display: none; } is rendered as non-monospaced plain text, without backticks) |
✅ | ✅ | ❌ root message (renders formatting) |
Quoted text: render as plain text (e.g. > quoted text is rendered as quoted text ) |
✅ | 🗒 preamature text truncation | ❌ root message (indented) ❌ thread summary (renders new line after quote) |
"(edited)" flag: do not render | ✅ | ✅ | ❌ root message (it shows the (edited) label)❌ thread summary (it shows the (edited) label) |
Images: render the filename as plain text | ✅ | 🗒 root message Image. 🗒 thread summary Image. |
✅ |
GIFs: render the filename as plain text | ✅ | 🗒 root message Image. 🗒 thread summary Image. |
✅ |
Sticker: render the image alt text as plain text | ✅ | 🗒 root message Sticker 🗒 thread summary Sticker |
✅ |
Video: render the video filename as plain text | ✅ | 🗒 root message Video. 🗒 thread summary Video. |
✅ |
File: render the filename as plaint text | ✅ | 🗒 root message File 🗒 thread summary File |
✅ |
Message highlight for mentions: do not decorate/highlight the message | ✅ | ✅ | ✅ |
Reply chain: do not render | ✅ | ❌ root message(In reply to @name:example.com rendered as plain text) ❌ thread summary ( In reply to @name:example.com rendered as plain text) |
✅ |
Big emoji: render it as a regular size emoji | ✅ | ✅ | ✅ |
Voice message: render it as plain text label that reads Voice message |
❌ thread summary (Voice message.ogg ) |
❌ root message (Voice )❌ thread summary ( Voice ) |
❌ thread summary (Voice message.ogg ) |
Polls: render the poll title as plain text | 🔮 thread summary (not supported in threads yet) | 🗒 root message Poll 🔮 thread summary (not supported in threads yet) |
🔮 thread summary (not supported in threads yet) |
Locations: location rendered as plain text (e.g. User Location geo:23.3371955,-2.7875839;u=30 at 2022-01-14T08:13:31.314Z , actual text depends on the platform that created the event, on iOS starts with Location was shared at geo: ) |
✅ | 🗒 root message Shared their location 🗒 thread summary Shared their location |
✅ |
Emote: render as plain text without the * Name part |
❌ root message (shows * name part) ❌ thread summary (shows * name part) |
✅ | ❌ root message (shows * name part) ❌ thread summary (shows * name part) |
Rainbow emote: rendered as plain text without color and the * Name part |
❌ (same issues as in regular emotes) | ❌ thread summary in thread list (shows /rainbowme command if emote content is edited) |
❌ (same issues as in regular emotes) |
Spoilers: rendered as plain text | ✅ | ❌ root message (rendered as block chars) ❌ thread summary (rendered as block chars) |
✅ |