diff --git a/imports/NeoChat/Component/Timeline/LinkPreviewDelegate.qml b/imports/NeoChat/Component/Timeline/LinkPreviewDelegate.qml index 4e170a227..f8ae1b393 100644 --- a/imports/NeoChat/Component/Timeline/LinkPreviewDelegate.qml +++ b/imports/NeoChat/Component/Timeline/LinkPreviewDelegate.qml @@ -11,9 +11,22 @@ import org.kde.neochat 1.0 RowLayout { id: row + readonly property var customEmojiLinksRegex: /data-mx-emoticon="" src="(\bhttps?:\/\/[^\s\<\>\"\']*[^\s\<\>\"\'])/g + readonly property var customEmojiLinks: { + let links = []; + // we need all this because QML JS doesn't support String.matchAll introduced in ECMAScript 2020 + let match = customEmojiLinksRegex.exec(model.display); + while (match !== null) { + links.push(match[1]) + match = customEmojiLinksRegex.exec(model.display); + } + return links; + } property var links: model.display.match(/(\bhttps?:\/\/[^\s\<\>\"\']*[^\s\<\>\"\'])/g) - // don't show previews for room links or user mentions - .filter(link => !link.includes("https://matrix.to")) + // don't show previews for room links or user mentions or custom emojis + .filter(link => !( + link.includes("https://matrix.to") || (customEmojiLinks && customEmojiLinks.includes(link)) + )) // remove ending fullstops and commas .map(link => (link.length && [".", ","].includes(link[link.length-1])) ? link.substring(0, link.length-1) : link) LinkPreviewer { diff --git a/imports/NeoChat/Component/Timeline/RichLabel.qml b/imports/NeoChat/Component/Timeline/RichLabel.qml index bfa098665..8457d7013 100644 --- a/imports/NeoChat/Component/Timeline/RichLabel.qml +++ b/imports/NeoChat/Component/Timeline/RichLabel.qml @@ -17,20 +17,33 @@ TextEdit { property bool isEmote: false /* Turn all links which aren't already in tags into hyperlinks */ + readonly property var customEmojiLinksRegex: /data-mx-emoticon="" src="(\bhttps?:\/\/[^\s\<\>\"\']*[^\s\<\>\"\'])/g + readonly property var customEmojiLinks: { + let links = []; + // we need all this because QML JS doesn't support String.matchAll introduced in ECMAScript 2020 + let match = customEmojiLinksRegex.exec(model.display); + while (match !== null) { + links.push(match[1]) + match = customEmojiLinksRegex.exec(model.display); + } + return links; + } readonly property var linkRegex: /(href=["'])?(\b(https?):\/\/[^\s\<\>\"\'\\]+)/g property string textMessage: model.display.includes("http") ? model.display.replace(linkRegex, function() { + if (customEmojiLinks && customEmojiLinks.includes(arguments[0])) { + return arguments[0]; + } if (arguments[1]) { return arguments[0]; - } else { - var l = arguments[2]; - if ([".", ","].includes(l[l.length-1])) { - var link = l.substring(0, l.length-1); - var leftover = l[l.length-1]; - return "" + link + "" + leftover; - } - return "" + l + ""; - } + } + const l = arguments[2]; + if ([".", ","].includes(l[l.length-1])) { + const link = l.substring(0, l.length-1); + const leftover = l[l.length-1]; + return `${link}${leftover}`; + } + return `${l}`; }) : model.display property bool spoilerRevealed: !hasSpoiler.test(textMessage)