improved text selection handling, added text selection handling for HTML messages, clear selection on close overlay

This commit is contained in:
ggurdin 2024-09-04 10:20:22 -04:00
parent bb0a499654
commit 03e04ee752
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
5 changed files with 47 additions and 19 deletions

View file

@ -1250,7 +1250,7 @@ class ChatController extends State<ChatPageWithRoom>
void pickEmojiReactionAction(Iterable<Event> allReactionEvents) async {
// #Pangea
MatrixState.pAnyState.closeAllOverlays();
closeSelectionOverlay();
// Pangea#
_allReactionEvents = allReactionEvents;
emojiPickerType = EmojiPickerType.reaction;
@ -1271,9 +1271,19 @@ class ChatController extends State<ChatPageWithRoom>
// Pangea#
}
// #Pangea
/// Close the combined selection view overlay and clear the message
/// text and selection stored for the text in that overlay
void closeSelectionOverlay() {
MatrixState.pAnyState.closeAllOverlays();
textSelection.clearMessageText();
textSelection.onSelection(null);
}
// Pangea#
void clearSelectedEvents() => setState(() {
// #Pangea
MatrixState.pAnyState.closeAllOverlays();
closeSelectionOverlay();
// Pangea#
selectedEvents.clear();
showEmojiPicker = false;

View file

@ -71,6 +71,9 @@ class HtmlMessage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// #Pangea
controller.textSelection.setMessageText(html);
// Pangea#
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
final linkColor = textColor.withAlpha(150);

View file

@ -1,28 +1,41 @@
import 'dart:async';
/// Contains information about the text currently being shown in a
/// toolbar overlay message and any selection within that text.
/// The ChatController contains one instance of this class, and it's values
/// should be updated each time an overlay is openned or closed, or when
/// an overlay's text selection changes.
class MessageTextSelection {
/// The currently selected text in the overlay message.
String? selectedText;
String messageText = "";
/// The full text displayed in the overlay message.
String? messageText;
/// A stream that emits the currently selected text whenever it changes.
final StreamController<String?> selectionStream =
StreamController<String?>.broadcast();
void setMessageText(String text) {
messageText = text;
}
/// Sets messageText to match the text currently being displayed in the overlay.
/// Text in messages is displayed in a variety of ways, i.e., direct message content,
/// translation, HTML rendered message, etc. This method should be called wherever the
/// text displayed in the overlay is determined.
void setMessageText(String text) => messageText = text;
void onSelection(String? text) => text == null || text.isEmpty
? clearTextSelection()
: setTextSelection(text);
/// Clears the messageText value. Called when the message selection overlay is closed.
void clearMessageText() => messageText = null;
void setTextSelection(String selection) {
selectedText = selection;
/// Updates the selectedText value and emits it to the selectionStream.
void onSelection(String? text) {
text == null || text.isEmpty ? selectedText = null : selectedText = text;
selectionStream.add(selectedText);
}
void clearTextSelection() {
selectedText = null;
selectionStream.add(selectedText);
/// Returns the index of the selected text within the message text.
/// If the selected text is not found, returns null.
int? get offset {
if (selectedText == null || messageText == null) return null;
final index = messageText!.indexOf(selectedText!);
return index > -1 ? index : null;
}
int get offset => messageText.indexOf(selectedText!);
}

View file

@ -141,6 +141,7 @@ class MessageToolbarState extends State<MessageToolbar> {
void showDefinition() {
debugPrint("show definition");
if (widget.textSelection.selectedText == null ||
widget.textSelection.messageText == null ||
widget.textSelection.selectedText!.isEmpty) {
toolbarContent = const SelectToDefine();
return;
@ -149,7 +150,7 @@ class MessageToolbarState extends State<MessageToolbar> {
toolbarContent = WordDataCard(
word: widget.textSelection.selectedText!,
wordLang: widget.pangeaMessageEvent.messageDisplayLangCode,
fullText: widget.textSelection.messageText,
fullText: widget.textSelection.messageText!,
fullTextLang: widget.pangeaMessageEvent.messageDisplayLangCode,
hasInfo: true,
room: widget.controller.room,

View file

@ -52,7 +52,8 @@ class MessageTranslationCardState extends State<MessageTranslationCard> {
Future<void> translateSelection() async {
if (widget.selection.selectedText == null ||
l1Code == null ||
l2Code == null) {
l2Code == null ||
widget.selection.messageText == null) {
selectionTranslation = null;
return;
}
@ -64,7 +65,7 @@ class MessageTranslationCardState extends State<MessageTranslationCard> {
final resp = await FullTextTranslationRepo.translate(
accessToken: accessToken,
request: FullTextTranslationRequestModel(
text: widget.selection.messageText,
text: widget.selection.messageText!,
tgtLang: l1Code!,
userL1: l1Code!,
userL2: l2Code!,