Autolinker Component in Loklak Search
In Loklak Search the post items contain links, which are either internal or external. These links include the hashtags, mentions, and URLs. From the backend server we just received the message in the plain text format, and thus there is need to parse the plain text and render it as clickable links. These clickable links can be either internal or external. Thus we need an auto-linker component, which takes the text and render it as links. The API of the Component The component takes as the input the plain text, then four arrays of strings. Each containing the text to be linked. These are hashtags, mentions, links and the unshorten attribute which is used to unshorten the shortened URLs in the post. These attributes are used by the component to render the text in the appropriate format. export class FeedLinkerComponent implements OnInit { @Input() text: string; @Input() hashtags: string[] = new Array<string>(); @Input() mentions: string[] = new Array<string>(); @Input() links: string[] = new Array<string>(); @Input() unshorten: Object = {}; } The Logic of the Component The basic logic of the component works as the following, we divide the text into chunks known as shards, we have three basic data structures for the component to work The ShardType which is the type of the chunk it specifies whether it is plain, hashtags, mentions, and links. The Shard which is the simple object containing the text to show, its type and the link it refers to The StringIndexdChunks, they are utilized to index the chunks in the order in which they appear in the text. const enum ShardType { plain, // 0 link, // 1 hashtag, // 2 mention // 3 } class Shard { constructor ( public type: ShardType = ShardType.plain, public text: String = '', public linkTo: any = null, public queryParams: any = null ) { } } interface StringIndexedChunks { index: number; str: string; type: ShardType; } First we have a private method of the component which searches for all the elements (strings) in the text. Here we have an array which maintains the index of those chunks in the text. private generateShards() { const indexedChunks: StringIndexedChunks[] = []; this.hashtags.forEach(hashtag => { const indices = getIndicesOf(this.text, `#${hashtag}`, false); indices.forEach(idx => { indexedChunks.push({index: idx, str: `#${hashtag}`, type: ShardType.hashtag}); }); }); this.mentions.forEach(mention => { const indices = getIndicesOf(this.text, `@${mention}`, false); indices.forEach(idx => { indexedChunks.push({index: idx, str: `@${mention}`, type: ShardType.mention}); }); }); } Then we sort the chunks according to their indexes in the text. This gives us sorted array which consists of all the chunks sorted according to the indexes as they appear in the text. indexedChunks.sort((a, b) => { return (a.index > b.index) ? 1 : (a.index < b.index) ? -1 : 0; }); The next part of the logic is to generate the shard array, an array which contains each chunk, once. To do this we iterate over the Sorted Indexed array created in the previous step and use it split the text into chunks. We iterate over the…
