From 524b8978f5f2c867d6bfe222cbaa83eb8e58ab2d Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 10 Jun 2025 11:50:07 -0400 Subject: [PATCH] remove unused files --- lib/pages/chat/events/html_message.dart | 22 +- .../utils/get_chat_list_item_subtitle.dart | 25 +- .../events/utils/message_text_util.dart | 177 -------- .../toolbar/widgets/message_token_text.dart | 419 ------------------ 4 files changed, 10 insertions(+), 633 deletions(-) delete mode 100644 lib/pangea/events/utils/message_text_util.dart delete mode 100644 lib/pangea/toolbar/widgets/message_token_text.dart diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index d05374dc3..ede3ddb6b 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -166,28 +166,23 @@ class HtmlMessage extends StatelessWidget { (token) => token.text.offset == offset && token.text.length == length, ); - /// Wrap token spans in token tags so styling / functions can be applied - dom.Node _tokenizeHtml( - dom.Node element, - String fullHtml, - List remainingTokens, - ) { + String _addTokenTags() { final regex = RegExp(r'(<[^>]+>)'); - final matches = regex.allMatches(fullHtml); + final matches = regex.allMatches(html); final List result = []; int lastEnd = 0; for (final match in matches) { if (match.start > lastEnd) { - result.add(fullHtml.substring(lastEnd, match.start)); // Text before tag + result.add(html.substring(lastEnd, match.start)); // Text before tag } result.add(match.group(0)!); // The tag itself lastEnd = match.end; } - if (lastEnd < fullHtml.length) { - result.add(fullHtml.substring(lastEnd)); // Remaining text after last tag + if (lastEnd < html.length) { + result.add(html.substring(lastEnd)); // Remaining text after last tag } for (final PangeaToken token in tokens ?? []) { @@ -217,7 +212,7 @@ class HtmlMessage extends StatelessWidget { ]); } - return dom.Element.html('${result.join()}'); + return result.join(); } // Pangea# @@ -834,10 +829,7 @@ class HtmlMessage extends StatelessWidget { // maxLines: limitHeight ? 64 : null,Add commentMore actions // overflow: TextOverflow.fade, // ); - dom.Node parsed = parser.parse(html).body ?? dom.Element.html(''); - if (tokens != null) { - parsed = _tokenizeHtml(parsed, html, List.from(tokens!)); - } + final parsed = parser.parse(_addTokenTags()).body ?? dom.Element.html(''); return SelectionArea( child: GestureDetector( onTap: () { diff --git a/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart b/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart index eb8aae600..995260793 100644 --- a/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart +++ b/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart @@ -6,8 +6,6 @@ import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; -import 'package:fluffychat/pangea/practice_activities/practice_selection_repo.dart'; -import 'package:fluffychat/pangea/toolbar/widgets/message_token_text.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../../utils/matrix_sdk_extensions/matrix_locals.dart'; @@ -88,26 +86,9 @@ class ChatListItemSubtitle extends StatelessWidget { if (snapshot.hasData) { final messageEventAndTokens = snapshot.data as MessageEventAndTokens; final pangeaMessageEvent = messageEventAndTokens.event; - final tokens = messageEventAndTokens.tokens; - - final analyticsEntry = tokens != null - ? PracticeSelectionRepo.get( - messageEventAndTokens.event.messageDisplayLangCode, - tokens, - ) - : null; - - return MessageTextWidget( - pangeaMessageEvent: pangeaMessageEvent, - existingStyle: style, - messageAnalyticsEntry: analyticsEntry, - isSelected: null, - onClick: null, - softWrap: false, - maxLines: pangeaMessageEvent.room.notificationCount >= 1 ? 2 : 1, - overflow: TextOverflow.ellipsis, - isMessage: false, - textScaler: MediaQuery.textScalerOf(context), + return Text( + pangeaMessageEvent.messageDisplayText, + style: style, ); } diff --git a/lib/pangea/events/utils/message_text_util.dart b/lib/pangea/events/utils/message_text_util.dart deleted file mode 100644 index 25c18c035..000000000 --- a/lib/pangea/events/utils/message_text_util.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:fluffychat/pangea/common/utils/error_handler.dart'; -import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; -import 'package:fluffychat/pangea/practice_activities/practice_selection.dart'; - -class TokenPosition { - /// Start index of the full substring in the message - final int start; - - /// End index of the full substring in the message - final int end; - - /// Start index of the token in the message - final int tokenStart; - - /// End index of the token in the message - final int tokenEnd; - - final bool hideContent; - final PangeaToken? token; - final bool isHighlighted; - final bool selected; - - const TokenPosition({ - required this.start, - required this.end, - required this.tokenStart, - required this.tokenEnd, - required this.hideContent, - required this.selected, - required this.isHighlighted, - this.token, - }); -} - -class MessageTextUtil { - static final Map> _tokenPositionsCache = {}; - - static List? getTokenPositions( - PangeaMessageEvent pangeaMessageEvent, { - PracticeSelection? messageAnalyticsEntry, - bool Function(PangeaToken)? isSelected, - bool Function(PangeaToken)? isHighlighted, - }) { - try { - if (pangeaMessageEvent.messageDisplayRepresentation?.tokens == null) { - return null; - } - - final cacheKey = pangeaMessageEvent.event - .getDisplayEvent(pangeaMessageEvent.timeline) - .eventId; - - if (_tokenPositionsCache.containsKey(cacheKey)) { - return _tokenPositionsCache[cacheKey]! - .map( - (t) => TokenPosition( - start: t.start, - end: t.end, - tokenStart: t.tokenStart, - tokenEnd: t.tokenEnd, - hideContent: t.hideContent, - selected: t.token != null - ? isSelected?.call(t.token!) ?? false - : false, - isHighlighted: t.token != null - ? isHighlighted?.call(t.token!) ?? false - : false, - token: t.token, - ), - ) - .toList(); - } - - // Convert the entire message into a list of characters - final Characters messageCharacters = - pangeaMessageEvent.messageDisplayText.characters; - - // When building token positions, use grapheme cluster indices - final List tokenPositions = []; - int globalIndex = 0; - - final tokens = pangeaMessageEvent.messageDisplayRepresentation!.tokens!; - int pointer = 0; - while (pointer < tokens.length) { - PangeaToken token = tokens[pointer]; - final start = token.start; - final end = token.end; - - // Calculate the number of grapheme clusters up to the start and end positions - final int startIndex = messageCharacters.take(start).length; - int endIndex = messageCharacters.take(end).length; - - final hasHiddenContent = - messageAnalyticsEntry?.hasHiddenWordActivity ?? false; - - // if this is white space, add position without token - if (globalIndex < startIndex) { - tokenPositions.add( - TokenPosition( - start: globalIndex, - end: startIndex, - tokenStart: globalIndex, - tokenEnd: startIndex, - hideContent: false, - selected: (isSelected?.call(token) ?? false) && !hasHiddenContent, - isHighlighted: isHighlighted?.call(token) ?? false, - ), - ); - } - - // 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 (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; - } - break; - } - - final hideContent = - messageAnalyticsEntry?.isTokenInHiddenWordActivity(token) ?? false; - - tokenPositions.add( - TokenPosition( - start: startIndex, - end: endIndex, - tokenStart: messageCharacters.take(token.start).length, - tokenEnd: messageCharacters.take(token.end).length, - token: token, - hideContent: hideContent, - selected: (isSelected?.call(token) ?? false) && - !hideContent && - !hasHiddenContent, - isHighlighted: isHighlighted?.call(token) ?? false, - ), - ); - - globalIndex = endIndex; - pointer = nextTokenPointer; - continue; - } - - _tokenPositionsCache[cacheKey] = tokenPositions; - - return tokenPositions; - } catch (err, s) { - ErrorHandler.logError( - e: err, - s: s, - data: { - 'pangeaMessageEvent': pangeaMessageEvent, - 'messageAnalyticsEntry': messageAnalyticsEntry, - 'isSelected': isSelected, - }, - ); - return null; - } - } -} diff --git a/lib/pangea/toolbar/widgets/message_token_text.dart b/lib/pangea/toolbar/widgets/message_token_text.dart deleted file mode 100644 index 0440f98e0..000000000 --- a/lib/pangea/toolbar/widgets/message_token_text.dart +++ /dev/null @@ -1,419 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:collection/collection.dart'; -import 'package:flutter_linkify/flutter_linkify.dart'; - -import 'package:fluffychat/pangea/common/utils/any_state_holder.dart'; -import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; -import 'package:fluffychat/pangea/events/utils/message_text_util.dart'; -import 'package:fluffychat/pangea/message_token_text/message_token_button.dart'; -import 'package:fluffychat/pangea/practice_activities/practice_selection.dart'; -import 'package:fluffychat/pangea/practice_activities/practice_selection_repo.dart'; -import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart'; -import 'package:fluffychat/pangea/toolbar/enums/reading_assistance_mode_enum.dart'; -import 'package:fluffychat/pangea/toolbar/utils/token_rendering_util.dart'; -import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart'; -import 'package:fluffychat/utils/url_launcher.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - -/// Question - does this need to be stateful or does this work? -/// Need to test. -/// - -class MessageTokenText extends StatelessWidget { - final PangeaMessageEvent _pangeaMessageEvent; - final TextStyle _style; - - final bool Function(PangeaToken)? _isSelected; - final void Function(PangeaToken)? _onClick; - final bool Function(PangeaToken)? _isHighlighted; - final MessageOverlayController? _overlayController; - final bool _isTransitionAnimation; - final ReadingAssistanceMode? readingAssistanceMode; - - const MessageTokenText({ - super.key, - required PangeaMessageEvent pangeaMessageEvent, - required List? tokens, - required TextStyle style, - required void Function(PangeaToken)? onClick, - bool Function(PangeaToken)? isSelected, - bool Function(PangeaToken)? isHighlighted, - MessageMode? messageMode, - MessageOverlayController? overlayController, - bool isTransitionAnimation = false, - this.readingAssistanceMode, - }) : _onClick = onClick, - _isSelected = isSelected, - _style = style, - _pangeaMessageEvent = pangeaMessageEvent, - _isHighlighted = isHighlighted, - _overlayController = overlayController, - _isTransitionAnimation = isTransitionAnimation; - - List? get _tokens => - _pangeaMessageEvent.messageDisplayRepresentation?.tokens; - - PracticeSelection? get messageAnalyticsEntry => _tokens != null - ? PracticeSelectionRepo.get( - _pangeaMessageEvent.messageDisplayLangCode, - _tokens!, - ) - : null; - - void callOnClick(TokenPosition tokenPosition) { - _onClick != null && tokenPosition.token != null - ? _onClick!(tokenPosition.token!) - : null; - } - - @override - Widget build(BuildContext context) { - if (_tokens == null) { - return Text( - _pangeaMessageEvent.messageDisplayText, - style: _style, - textScaler: TextScaler.noScaling, - ); - } - - return MessageTextWidget( - pangeaMessageEvent: _pangeaMessageEvent, - existingStyle: _style, - messageAnalyticsEntry: messageAnalyticsEntry, - isSelected: _isSelected, - onClick: callOnClick, - isHighlighted: _isHighlighted, - overlayController: _overlayController, - isTransitionAnimation: _isTransitionAnimation, - readingAssistanceMode: readingAssistanceMode, - ); - } -} - -class MessageTextWidget extends StatelessWidget { - final PangeaMessageEvent pangeaMessageEvent; - final TextStyle existingStyle; - final PracticeSelection? messageAnalyticsEntry; - final bool Function(PangeaToken)? isSelected; - final void Function(TokenPosition tokenPosition)? onClick; - final bool Function(PangeaToken)? isHighlighted; - - final bool? softWrap; - final int? maxLines; - final TextOverflow? overflow; - - final MessageOverlayController? overlayController; - final bool isTransitionAnimation; - final bool isMessage; - final ReadingAssistanceMode? readingAssistanceMode; - - final TextScaler? textScaler; - - const MessageTextWidget({ - super.key, - required this.pangeaMessageEvent, - required this.existingStyle, - this.messageAnalyticsEntry, - this.isSelected, - this.onClick, - this.softWrap, - this.maxLines, - this.overflow, - this.isHighlighted, - this.overlayController, - this.isTransitionAnimation = false, - this.isMessage = true, - this.readingAssistanceMode, - this.textScaler, - }); - - @override - Widget build(BuildContext context) { - final renderer = TokenRenderingUtil( - pangeaMessageEvent: pangeaMessageEvent, - readingAssistanceMode: readingAssistanceMode, - existingStyle: existingStyle, - overlayController: overlayController, - isTransitionAnimation: isTransitionAnimation, - ); - - final Characters messageCharacters = - pangeaMessageEvent.messageDisplayText.characters; - - final tokenPositions = MessageTextUtil.getTokenPositions( - pangeaMessageEvent, - messageAnalyticsEntry: messageAnalyticsEntry, - isSelected: isSelected, - isHighlighted: isHighlighted, - ); - - if (tokenPositions == null) { - return Text( - pangeaMessageEvent.messageDisplayText, - style: renderer.style(context), - softWrap: softWrap, - maxLines: maxLines, - overflow: overflow, - textScaler: textScaler, - ); - } - - final theme = Theme.of(context); - final ownMessage = - pangeaMessageEvent.senderId == Matrix.of(context).client.userID; - final linkColor = theme.brightness == Brightness.light - ? theme.colorScheme.primary - : ownMessage - ? theme.colorScheme.onPrimary - : theme.colorScheme.onSurface; - - return RichText( - softWrap: softWrap ?? true, - maxLines: maxLines, - overflow: overflow ?? TextOverflow.clip, - textScaler: textScaler ?? TextScaler.noScaling, - text: TextSpan( - children: - tokenPositions.mapIndexed((int i, TokenPosition tokenPosition) { - final substring = messageCharacters - .skip(tokenPosition.start) - .take(tokenPosition.end - tokenPosition.start) - .toString(); - - if (tokenPosition.token?.pos == 'SPACE') { - return const TextSpan(text: '\n'); - } - - if (tokenPosition.token != null) { - // 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 start = ''; - String middle = ''; - String end = ''; - - final startSplitIndex = - tokenPosition.tokenStart - tokenPosition.start; - final endSplitIndex = tokenPosition.tokenEnd - tokenPosition.start; - - start = substring.characters.take(startSplitIndex).toString(); - end = substring.characters.skip(endSplitIndex).toString(); - middle = substring.characters - .skip(startSplitIndex) - .take(endSplitIndex - startSplitIndex) - .toString(); - - final token = tokenPosition.token!; - - final tokenWidth = renderer.tokenTextWidthForContainer( - context, - token.text.content, - ); - - return WidgetSpan( - child: CompositedTransformTarget( - link: renderer.assignTokenKey - ? MatrixState.pAnyState - .layerLinkAndKey(token.text.uniqueKey) - .link - : LayerLinkAndKey(token.hashCode.toString()).link, - child: Column( - key: renderer.assignTokenKey - ? MatrixState.pAnyState - .layerLinkAndKey(token.text.uniqueKey) - .key - : null, - children: [ - if (renderer.showCenterStyling) - MessageTokenButton( - token: token, - overlayController: overlayController, - textStyle: renderer.style(context), - width: tokenWidth, - animateIn: isTransitionAnimation, - practiceTargetForToken: overlayController - ?.toolbarMode.associatedActivityType != - null - ? overlayController?.practiceSelection - ?.activities( - overlayController! - .toolbarMode.associatedActivityType!, - ) - .firstWhereOrNull( - (a) => a.tokens.contains(token), - ) - : null, - ), - MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: onClick != null - ? () => onClick?.call(tokenPosition) - : null, - child: RichText( - text: TextSpan( - children: [ - if (start.isNotEmpty) - LinkifySpan( - text: start, - style: renderer.style( - context, - color: renderer.backgroundColor( - context, - tokenPosition.selected, - ), - ), - linkStyle: TextStyle( - decoration: TextDecoration.underline, - color: linkColor, - ), - onOpen: (url) => - UrlLauncher(context, url.url).launchUrl(), - ), - // tokenPosition.hideContent - // ? WidgetSpan( - // alignment: PlaceholderAlignment.middle, - // child: GestureDetector( - // onTap: onClick != null - // ? () => onClick?.call(tokenPosition) - // : null, - // child: HiddenText( - // text: middle, - // style: style(context), - // ), - // ), - // ) - // : - LinkifySpan( - text: middle, - style: renderer.style( - context, - color: renderer.backgroundColor( - context, - tokenPosition.selected, - ), - ), - linkStyle: TextStyle( - decoration: TextDecoration.underline, - color: linkColor, - ), - onOpen: (url) => - UrlLauncher(context, url.url).launchUrl(), - ), - if (end.isNotEmpty) - LinkifySpan( - text: end, - style: renderer.style( - context, - color: renderer.backgroundColor( - context, - tokenPosition.selected, - ), - ), - linkStyle: TextStyle( - decoration: TextDecoration.underline, - color: linkColor, - ), - onOpen: (url) => - UrlLauncher(context, url.url).launchUrl(), - ), - ], - ), - ), - ), - ), - // AnimatedContainer( - // duration: const Duration( - // milliseconds: AppConfig.overlayAnimationDuration, - // ), - // height: overlayController != null && isTransitionAnimation - // ? 4 - // : 0, - // width: tokenWidth, - // child: Container( - // color: backgroundColor(context, tokenPosition), - // ), - // ), - ], - ), - ), - ); - } else { - // if ((i > 0 || i < tokenPositions.length - 1) && - // tokenPositions[i + 1].hideContent && - // tokenPositions[i - 1].hideContent) { - // return WidgetSpan( - // child: GestureDetector( - // onTap: onClick != null - // ? () => onClick?.call(tokenPosition) - // : null, - // child: HiddenText( - // text: substring, - // style: style(context), - // ), - // ), - // ); - // } - return LinkifySpan( - text: substring, - style: renderer.style(context), - options: const LinkifyOptions(humanize: false), - linkStyle: TextStyle( - decoration: TextDecoration.underline, - color: Theme.of(context).colorScheme.primary, - ), - onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), - ); - } - }).toList(), - ), - ); - } -} - -// class HiddenText extends StatelessWidget { -// final String text; -// final TextStyle style; - -// const HiddenText({ -// super.key, -// required this.text, -// required this.style, -// }); - -// @override -// Widget build(BuildContext context) { -// final TextPainter textPainter = TextPainter( -// text: TextSpan(text: text, style: style), -// textDirection: TextDirection.ltr, -// )..layout(); - -// final textWidth = textPainter.size.width; -// final textHeight = textPainter.size.height; - -// textPainter.dispose(); - -// return SizedBox( -// height: textHeight, -// child: Stack( -// children: [ -// Container( -// width: textWidth, -// height: textHeight, -// color: Colors.transparent, -// ), -// Positioned( -// bottom: 0, -// child: Container( -// width: textWidth, -// height: 1, -// color: style.color, -// ), -// ), -// ], -// ), -// ); -// } -// }