mlemgroup / mlem

Mlem for Lemmy
https://lemmy.ml/c/mlemapp
GNU General Public License v3.0
162 stars 34 forks source link

[2.0] Tappable links #1072

Open Sjmarf opened 1 month ago

Sjmarf commented 1 month ago

In v1.0, we extracted these using Regex. For 2.0, I've implemented the link extraction logic in LemmyMarkdownUI. This has several advantages:

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 }.