| 35 | } |
| 36 | |
| 37 | export function convertFormattedText(text: string, entities: Record<string, any[]>, display_text_range: [number, number]): Record<string, any> { |
| 38 | // collate all entities into one list |
| 39 | const list = []; |
| 40 | if (entities.user_mentions) { |
| 41 | for (const o of entities.user_mentions) { |
| 42 | o.type = 'user_mention'; |
| 43 | list.push(o); |
| 44 | } |
| 45 | } |
| 46 | if (entities.urls) { |
| 47 | for (const o of entities.urls) { |
| 48 | o.type = 'url'; |
| 49 | list.push(o); |
| 50 | } |
| 51 | } |
| 52 | if (entities.hashtags) { |
| 53 | for (const o of entities.hashtags) { |
| 54 | o.type = 'hashtag'; |
| 55 | list.push(o); |
| 56 | } |
| 57 | } |
| 58 | // a fake 'end' entity |
| 59 | list.push({type: 'end', indices: [display_text_range[1], display_text_range[1]]}); |
| 60 | |
| 61 | // add a space so that the library won't mangle the 'end' entity |
| 62 | // that way, an emoji at the end of a tweet doesn't get cut off |
| 63 | twitter.modifyIndicesFromUnicodeToUTF16(text + ' ', list); |
| 64 | |
| 65 | const output = []; |
| 66 | const mentions = []; |
| 67 | const tags = []; |
| 68 | let lastPos = 0; |
| 69 | let entityNum = 0; |
| 70 | |
| 71 | while (entityNum < list.length) { |
| 72 | const entity = list[entityNum]; |
| 73 | entityNum += 1; |
| 74 | |
| 75 | if (entity.indices[0] > lastPos) |
| 76 | output.push(text.substring(lastPos, entity.indices[0])); |
| 77 | |
| 78 | if (entity.type === 'user_mention') { |
| 79 | const url = `${CONFIG.root}/@${entity.screen_name}`; |
| 80 | mentions.push({ |
| 81 | id: entity.id_str, |
| 82 | username: entity.screen_name, |
| 83 | url, |
| 84 | acct: entity.screen_name |
| 85 | }); |
| 86 | const urlEscape = twitter.htmlEscape(url); |
| 87 | const username = twitter.htmlEscape(entity.screen_name); |
| 88 | output.push(`<span class="h-card"><a href="${urlEscape}" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>${username}</span></a></span>`); |
| 89 | } else if (entity.type === 'url') { |
| 90 | // Remap tweet URLs |
| 91 | const match = /^https:\/\/twitter.com\/([^/]+)\/status\/(\d+)/.exec(entity.expanded_url); |
| 92 | if (match) { |
| 93 | entity.expanded_url = `${CONFIG.root}/@${match[1]}/${match[2]}`; |
| 94 | } |