From a42ede894f5661b09e58dc5f3c08b9aec87cee87 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:48:55 -0500 Subject: [PATCH] feat: better UX for event too large error (#1975) --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat/chat.dart | 17 ++++++-- .../chat/widgets/event_too_large_dialog.dart | 41 +++++++++++++++++++ .../extensions/room_events_extension.dart | 40 +++++++++++++----- 4 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 lib/pangea/chat/widgets/event_too_large_dialog.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 5a0db36d8..1280a3a86 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4827,5 +4827,6 @@ "enableAutocorrectDescription": "Use your keyboard's built-in autocorrect when typing messages", "ttsDisbledTitle": "Text-to-speech disabled", "ttsDisabledBody": "You can enable text-to-speech in your learning settings", - "noSpaceDescriptionYet": "No space description created yet." + "noSpaceDescriptionYet": "No space description created yet.", + "tooLargeToSend": "This message is too large to send" } \ No newline at end of file diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 98cdfa43b..03d2758f4 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -30,6 +30,7 @@ import 'package:fluffychat/pages/chat_details/chat_details.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/level_up.dart'; import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; +import 'package:fluffychat/pangea/chat/widgets/event_too_large_dialog.dart'; import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; import 'package:fluffychat/pangea/choreographer/models/choreo_record.dart'; import 'package:fluffychat/pangea/choreographer/widgets/igc/pangea_text_controller.dart'; @@ -792,17 +793,25 @@ class ChatController extends State return; } }, - onError: (err, stack) => ErrorHandler.logError( + ).catchError((err, s) { + if (err is EventTooLarge) { + showAdaptiveDialog( + context: context, + builder: (context) => const EventTooLargeDialog(), + ); + return; + } + ErrorHandler.logError( e: err, - s: stack, + s: s, data: { 'roomId': roomId, 'text': sendController.text, 'inReplyTo': replyEvent?.eventId, 'editEventId': editEvent?.eventId, }, - ), - ); + ); + }); // Pangea# sendController.value = TextEditingValue( text: pendingText, diff --git a/lib/pangea/chat/widgets/event_too_large_dialog.dart b/lib/pangea/chat/widgets/event_too_large_dialog.dart new file mode 100644 index 000000000..91084af8a --- /dev/null +++ b/lib/pangea/chat/widgets/event_too_large_dialog.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; + +class EventTooLargeDialog extends StatelessWidget { + const EventTooLargeDialog({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog.adaptive( + title: Icon( + Icons.error_outline_outlined, + color: Theme.of(context).colorScheme.error, + size: 48, + ), + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + L10n.of(context).tooLargeToSend, + maxLines: 4, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + actions: [ + AdaptiveDialogAction( + onPressed: () => Navigator.of(context).pop(), + child: Text(L10n.of(context).close), + ), + ], + ); + } +} diff --git a/lib/pangea/extensions/room_events_extension.dart b/lib/pangea/extensions/room_events_extension.dart index eb57e51be..b357593a9 100644 --- a/lib/pangea/extensions/room_events_extension.dart +++ b/lib/pangea/extensions/room_events_extension.dart @@ -89,16 +89,11 @@ extension EventsRoomExtension on Room { } } - String sendFakeMessage({ - required String text, + Map _getEventContent( + Map content, Event? inReplyTo, String? editEventId, - }) { - final content = { - 'msgtype': MessageTypes.Text, - 'body': text, - }; - + ) { final html = markdown( content['body'], getEmotePacks: () => getImagePacksFlat(ImagePackUsage.emoticon), @@ -111,9 +106,6 @@ extension EventsRoomExtension on Room { content['formatted_body'] = html; } - // Create new transaction id - final messageID = client.generateUniqueTransactionId(); - if (inReplyTo != null) { var replyText = '<${inReplyTo.senderId}> ${inReplyTo.body}'; replyText = replyText.split('\n').map((line) => '> $line').join('\n'); @@ -163,6 +155,23 @@ extension EventsRoomExtension on Room { } } + return content; + } + + String sendFakeMessage({ + required String text, + Event? inReplyTo, + String? editEventId, + }) { + // Create new transaction id + final messageID = client.generateUniqueTransactionId(); + + final baseContent = { + 'msgtype': MessageTypes.Text, + 'body': text, + }; + + final content = _getEventContent(baseContent, inReplyTo, editEventId); final Event event = Event( content: content, type: EventTypes.Message, @@ -238,6 +247,15 @@ extension EventsRoomExtension on Room { event['formatted_body'] = html; } } + + final fullBody = _getEventContent(event, inReplyTo, editEventId); + final jsonString = jsonEncode(fullBody); + final jsonSizeInBytes = utf8.encode(jsonString).length; + const maxBodySize = 60000; + if (jsonSizeInBytes > maxBodySize) { + return Future.error(EventTooLarge(maxBodySize, jsonSizeInBytes)); + } + return sendEvent( event, txid: txid,