@ -17,6 +17,7 @@ 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/events/models/pangea_token_text_model.dart ' ;
import ' package:fluffychat/pangea/toolbar/controllers/text_to_speech_controller.dart ' ;
import ' package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart ' ;
import ' package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart ' ;
import ' package:fluffychat/pangea/toolbar/widgets/message_toolbar.dart ' ;
@ -61,6 +62,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
MessageMode toolbarMode = MessageMode . noneSelected ;
PangeaTokenText ? _selectedSpan ;
List < PangeaTokenText > ? _highlightedTokens ;
List < PangeaToken > ? tokens ;
bool initialized = false ;
@ -129,6 +131,26 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
setState ( ( ) { } ) ;
}
/ / / If sentence TTS is playing a word , highlight that word in message overlay
void highlightCurrentText ( int currentPosition , List < TTSToken > ttsTokens ) {
final List < TTSToken > textToSelect = [ ] ;
/ / Check if current time is between start and end times of tokens
for ( final TTSToken token in ttsTokens ) {
if ( token . endMS > currentPosition ) {
if ( token . startMS < currentPosition ) {
textToSelect . add ( token ) ;
} else {
break ;
}
}
}
if ( const ListEquality ( ) . equals ( textToSelect , _highlightedTokens ) ) return ;
_highlightedTokens =
textToSelect . isEmpty ? null : textToSelect . map ( ( t ) = > t . text ) . toList ( ) ;
setState ( ( ) { } ) ;
}
void _setupSubscriptions ( ) {
_animationController = AnimationController (
vsync: this ,
@ -278,6 +300,9 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
debugPrint ( " updateToolbarMode: $ mode - clearing selectedSpan " ) ;
_selectedSpan = null ;
}
if ( mode ! = MessageMode . textToSpeech ) {
_highlightedTokens = null ;
}
toolbarMode = mode ;
} ) ;
}
@ -327,17 +352,24 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
setState ( ( ) { } ) ;
}
/ / / Whether the given token is currently selected
/ / / Whether the given token is currently selected or highlighted
bool isTokenSelected ( PangeaToken token ) {
final isSelected = _selectedSpan ? . offset = = token . text . offset & &
_selectedSpan ? . length = = token . text . length ;
return isSelected ;
}
bool isTokenHighlighted ( PangeaToken token ) {
if ( _highlightedTokens = = null ) return false ;
return _highlightedTokens ! . any (
( t ) = > t . offset = = token . text . offset & & t . length = = token . text . length ,
) ;
}
PangeaToken ? get selectedToken = > tokens ? . firstWhereOrNull ( isTokenSelected ) ;
/ / / Whether the overlay is currently displaying a selection
bool get isSelection = > _selectedSpan ! = null ;
bool get isSelection = > _selectedSpan ! = null | | _highlightedTokens ! = null ;
PangeaTokenText ? get selectedSpan = > _selectedSpan ;