[2.0] Tappable links
In v1.0, we extracted these using Regex. For 2.0, I've implemented the link extraction logic in LemmyMarkdownUI. This has several advantages:
- It won't look for links inside of code blocks.
- We can choose not to render links inside of spoilers.
- We can extract the title of each link as a series of nodes, allowing the tappable link titles to be rendered in the same markdown format as the links in the original text.
- It's about 8-10x faster than our regex solution (tested on the markdown in the Profile tab), because it simply traverses an existing markdown tree.
LemmyMarkdownUI implementation
Get the links contained within some markdown like so:
let blocks: [BlockNode] = .init(markdown: string)
let links = blocks.links
links is an array of LinkData, which is defined as follows:
struct LinkData {
let title: [InlineNode]
let url: URL
var insideSpoiler: Bool
}
Using this in Mlem
LemmyMarkdownUI's Markdown view has an initialiser that accepts [BlockNode]. This means that we can create the markdown tree in Mlem, extract the links from it, then pass the tree to Markdown to render it. This should be pretty performant.
Notice that LinkData.title is an array of inline nodes. When rendering the title of each tappable link, we can pass this array to LemmyMarkdownUI's MarkdownText view to render the title with markdown features. Or, you can use title.stringLiteral to get the raw string with markdown delimiters removed.
We should probably not include links that are inside spoilers in the tappable links list. To exclude these, we can use something like links.filter { !$0.insideSpoiler }.