Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TW-221: Fix remove url markdown on messages #311

Merged
merged 2 commits into from
Jul 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/pages/chat/events/message_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ class MessageContent extends StatelessWidget {
if (AppConfig.renderHtml &&
!event.redacted &&
event.isRichMessage) {
var html = event.formattedText;
var html = event.formattedText.unMarkdownLinks(event.text);

if (event.messageType == MessageTypes.Emote) {
html = '* $html';
}
Expand Down
33 changes: 33 additions & 0 deletions lib/utils/string_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,37 @@ extension StringCasingExtension on String {
final String? firstValidLink = matches.firstWhere((link) => AnyLinkPreview.isValidLink(link!));
return firstValidLink;
}

// Removes markdowned links from a string based on the unformatted text
// Workaround for content['formatted_body'] which formats urls in a way that makes them unusable
hoangdat marked this conversation as resolved.
Show resolved Hide resolved
String unMarkdownLinks(String unformattedText) {
final RegExp regex = RegExp(r'https:\/\/[^\s]+');

final Iterable<Match> formattedLinksMatches = regex.allMatches(this);
final Iterable<Match> unformattedLinksMatches = regex.allMatches(unformattedText);

if (formattedLinksMatches.isEmpty ||
unformattedLinksMatches.isEmpty ||
formattedLinksMatches.length != unformattedLinksMatches.length) {
return this;
}

var unMarkdownedText = this;

final Iterator<Match> formattedIterator = formattedLinksMatches.iterator;
final Iterator<Match> unformattedIterator = unformattedLinksMatches.iterator;

// Replace respectively all formatted links with unformatted links
while (formattedIterator.moveNext() && unformattedIterator.moveNext()) {
final Match formattedLinkMatch = formattedIterator.current;
final Match unformattedLinkMatch = unformattedIterator.current;

final String formattedLink = formattedLinkMatch.group(0)!;
final String unformattedLink = unformattedLinkMatch.group(0)!;

unMarkdownedText = unMarkdownedText.replaceFirst(formattedLink, unformattedLink);
}

return unMarkdownedText;
}
}
92 changes: 92 additions & 0 deletions test/string_extension_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,96 @@ void main() {

expect(result, isEmpty);
});

test('unMarkdownLinks should replace links when there is only one link', () {
const unMarkdownMessageWithOnlyLink = "https://superman.com/this-is-a-*superman*-link";
const markdownMessageWithOnlyLink = "https://superman.com/this-is-a-<em>superman</em>-link";

final result = markdownMessageWithOnlyLink.unMarkdownLinks(unMarkdownMessageWithOnlyLink);

expect(result, equals(unMarkdownMessageWithOnlyLink));
});

test('unMarkdownLinks should replace links when there are multiple links', () {
const unMarkdownMessageWith2Links = "https://superman.com/this-is-a-*superman*-link https://batman.com/this-is-a-*batman*-link";
const markdownMessageWith2Links = "https://superman.com/this-is-a-<em>superman</em>-link https://batman.com/this-is-a-<em>batman</em>-link";

final result = markdownMessageWith2Links.unMarkdownLinks(unMarkdownMessageWith2Links);

expect(result, equals(unMarkdownMessageWith2Links));
});

test('unMarkdownLinks should replace links when there are links and text', () {
hoangdat marked this conversation as resolved.
Show resolved Hide resolved
const unMarkdownMessageWithLinksAndTexts = "is this serious https://superman.com/this-is-a-*superman*-link hello guys https://batman.com/this-is-a-*batman*-link";
const markdownMessageWithLinksAndTexts = "is this serious https://superman.com/this-is-a-<em>superman</em>-link hello guys https://batman.com/this-is-a-<em>batman</em>-link";

final result = markdownMessageWithLinksAndTexts.unMarkdownLinks(unMarkdownMessageWithLinksAndTexts);
expect(result, equals(unMarkdownMessageWithLinksAndTexts));
});

test('unMarkdownLinks should replace links when there is link starting with text', () {
const unMarkdownMessageWithLinkStartingWithText = "is this serious https://superman.com/this-is-a-*superman*-link";
const markdownMessageWithLinkStartingWithText = "is this serious https://superman.com/this-is-a-<em>superman</em>-link";

final result = markdownMessageWithLinkStartingWithText.unMarkdownLinks(unMarkdownMessageWithLinkStartingWithText);
expect(result, equals(unMarkdownMessageWithLinkStartingWithText));
});

test('unMarkdownLinks should not replace links when the link is not valid', () {
const unMarkdownMessageWithUnvalidLink = "is this serious-https://superman.com/this-is-a-<em>superman</em>-link";
const markdownMessageWithUnvalidLink = "is this serious-https://superman.com/this-is-a-<em>superman</em>-link";

final result = markdownMessageWithUnvalidLink.unMarkdownLinks(unMarkdownMessageWithUnvalidLink);
expect(result, equals(unMarkdownMessageWithUnvalidLink));
});

test('unMarkdownLinks should return formatted text when there is no link', () {
const unMarkdownMessageWithNoLink = "hello guys";
const markdownMessageWithNoLink = "hello guys";

final result = markdownMessageWithNoLink.unMarkdownLinks(unMarkdownMessageWithNoLink);

expect(result, equals(unMarkdownMessageWithNoLink));
});

test('unMarkdownLinks should replace links when there is link ending with text', () {
const unMarkdownMessageWithLinkEndingWithText = "https://superman.com/this-is-a-*superman*-link hello guys";
const markdownMessageWithLinkEndingWithText = "https://superman.com/this-is-a-<em>superman</em>-link hello guys";

final result = markdownMessageWithLinkEndingWithText.unMarkdownLinks(unMarkdownMessageWithLinkEndingWithText);
expect(result, equals(unMarkdownMessageWithLinkEndingWithText));
});

test('unMarkdownLinks should replace links when there is link ending with incomplete markdown', () {
const unMarkdownMessageWithIncompleteMarkdownLink = "https://superman.com/this-is-a-*supe hello guys";
const markdownMessageWithIncompleteMarkdownLink = "https://superman.com/this-is-a-<em>supe hello guys";

final result = markdownMessageWithIncompleteMarkdownLink.unMarkdownLinks(unMarkdownMessageWithIncompleteMarkdownLink);
expect(result, equals(unMarkdownMessageWithIncompleteMarkdownLink));
});

test('unMarkdownLinks should replace links when there are text and unusable links', () {
const unMarkdownMessageWithUnusableLinks = "https://superman.com/this-is-a-*superman*-link hello guys https://bat";
const markdownMessageWithUnusableLinks = "https://superman.com/this-is-a-<em>superman</em>-link hello guys https://bat";

final result = markdownMessageWithUnusableLinks.unMarkdownLinks(unMarkdownMessageWithUnusableLinks);
expect(result, equals(unMarkdownMessageWithUnusableLinks));
});

test('unMarkdownLinks should replace links when there are markdown and unmarkdown links', () {
const unMarkdownMessageWithMarkdownAndUnMarkdownLinks = "https://superman.com/this-is-a-*superman*-link hello guys https://batman.com/this-";
const markdownMessageWithMarkdownAndUnMarkdownLinks = "https://superman.com/this-is-a-<em>superman</em>-link hello guys https://batman.com/this-";

final result = markdownMessageWithMarkdownAndUnMarkdownLinks.unMarkdownLinks(unMarkdownMessageWithMarkdownAndUnMarkdownLinks);
expect(result, equals(unMarkdownMessageWithMarkdownAndUnMarkdownLinks));
});

test('unMarkdownLinks should return formatted link when the unformatted text has no link', () {
const messageWithNoLinkUnMarkdowned = "hello guys";
const messageWithNoLinkMarkdowned = "hello guys https://superman.com/this-is-a-*superman*-link";

final result = messageWithNoLinkMarkdowned.unMarkdownLinks(messageWithNoLinkUnMarkdowned);

expect(result, equals(messageWithNoLinkMarkdowned));
});
}
Loading