improved text selection handling, added text selection handling for HTML messages, clear selection on close overlay
This commit is contained in:
parent
bb0a499654
commit
03e04ee752
5 changed files with 47 additions and 19 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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!);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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!,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue