diff --git a/lib/pangea/events/utils/message_text_util.dart b/lib/pangea/events/utils/message_text_util.dart index f23fc30f28..7c829dba3c 100644 --- a/lib/pangea/events/utils/message_text_util.dart +++ b/lib/pangea/events/utils/message_text_util.dart @@ -28,7 +28,7 @@ class MessageTextUtil { final tokens = pangeaMessageEvent.messageDisplayRepresentation!.tokens!; int pointer = 0; while (pointer < tokens.length) { - final token = tokens[pointer]; + PangeaToken token = tokens[pointer]; final start = token.start; final end = token.end; @@ -56,13 +56,23 @@ class MessageTextUtil { ); } - // group tokens with punctuation next to it so punctuation doesn't cause newline - final List followingPunctTokens = []; + // group tokens with punctuation before and after so punctuation doesn't cause newline int nextTokenPointer = pointer + 1; while (nextTokenPointer < tokens.length) { final nextToken = tokens[nextTokenPointer]; - if (nextToken.pos == 'PUNCT') { - followingPunctTokens.add(nextToken); + if (token.pos == 'PUNCT' && token.end == nextToken.start) { + token = nextToken; + nextTokenPointer++; + endIndex = messageCharacters.take(nextToken.end).length; + continue; + } + break; + } + + while (nextTokenPointer < tokens.length) { + final nextToken = tokens[nextTokenPointer]; + + if (nextToken.pos == 'PUNCT' && token.end == nextToken.start) { nextTokenPointer++; endIndex = messageCharacters.take(nextToken.end).length; continue; @@ -74,8 +84,8 @@ class MessageTextUtil { TokenPosition( start: startIndex, end: endIndex, - tokenStart: startIndex, - tokenEnd: messageCharacters.take(end).length, + tokenStart: messageCharacters.take(token.start).length, + tokenEnd: messageCharacters.take(token.end).length, token: token, hideContent: hideContent, selected: (isSelected?.call(token) ?? false) && diff --git a/lib/pangea/toolbar/widgets/message_token_text.dart b/lib/pangea/toolbar/widgets/message_token_text.dart index 61d547dc85..82994bdbd8 100644 --- a/lib/pangea/toolbar/widgets/message_token_text.dart +++ b/lib/pangea/toolbar/widgets/message_token_text.dart @@ -238,16 +238,24 @@ class MessageTextWidget extends StatelessWidget { ); } - // if the tokenPosition is a combination of the token and following punctuation + // if the tokenPosition is a combination of the token and preceding / following punctuation // split them so that only the token itself is highlighted when clicked - String firstSubstring = substring; - String secondSubstring = ''; + String start = ''; + String middle = substring; + String end = ''; + + if (tokenPosition.tokenStart != tokenPosition.start) { + final splitIndex = + (tokenPosition.tokenStart - tokenPosition.start); + start = substring.substring(0, splitIndex); + middle = substring.substring(splitIndex); + } if (tokenPosition.end != tokenPosition.tokenEnd) { final splitIndex = (tokenPosition.end - tokenPosition.start) - (tokenPosition.end - tokenPosition.tokenEnd); - firstSubstring = substring.substring(0, splitIndex); - secondSubstring = substring.substring(splitIndex); + middle = middle.substring(0, splitIndex); + end = substring.substring(splitIndex); } return WidgetSpan( @@ -260,8 +268,22 @@ class MessageTextWidget extends StatelessWidget { child: RichText( text: TextSpan( children: [ + if (start.isNotEmpty) + LinkifySpan( + text: start, + style: style, + linkStyle: TextStyle( + decoration: TextDecoration.underline, + color: Theme.of(context).brightness == + Brightness.light + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.onPrimary, + ), + onOpen: (url) => + UrlLauncher(context, url.url).launchUrl(), + ), LinkifySpan( - text: firstSubstring, + text: middle, style: style.merge( TextStyle( backgroundColor: backgroundColor, @@ -277,9 +299,9 @@ class MessageTextWidget extends StatelessWidget { onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), ), - if (secondSubstring.isNotEmpty) + if (end.isNotEmpty) LinkifySpan( - text: secondSubstring, + text: end, style: style, linkStyle: TextStyle( decoration: TextDecoration.underline,