fix: when merging punctuation into tokens to prevent line breaks, account for punctuation preceding tokens (#1812)

This commit is contained in:
ggurdin 2025-02-17 11:52:00 -05:00 committed by GitHub
parent 9d13d2fa73
commit 87581e8cfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 15 deletions

View file

@ -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<PangeaToken> 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) &&

View file

@ -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,