Merge pull request #542 from GetStream/feat/message-input-error-handling

feat: message input error listener
This commit is contained in:
Salvatore Giordano
2021-07-14 13:48:06 +02:00
committed by GitHub
@@ -27,6 +27,16 @@ import 'package:video_compress/video_compress.dart';
export 'package:video_compress/video_compress.dart' show VideoQuality; export 'package:video_compress/video_compress.dart' show VideoQuality;
/// A callback that can be passed to [MessageInput.onError].
///
/// This callback should not throw.
///
/// It exists merely for error reporting, and should not be used otherwise.
typedef ErrorListener = void Function(
Object error,
StackTrace? stackTrace,
);
/// Builder for attachment thumbnails /// Builder for attachment thumbnails
typedef AttachmentThumbnailBuilder = Widget Function( typedef AttachmentThumbnailBuilder = Widget Function(
BuildContext, BuildContext,
@@ -153,6 +163,7 @@ class MessageInput extends StatefulWidget {
this.maxAttachmentSize = _kDefaultMaxAttachmentSize, this.maxAttachmentSize = _kDefaultMaxAttachmentSize,
this.compressedVideoQuality = VideoQuality.DefaultQuality, this.compressedVideoQuality = VideoQuality.DefaultQuality,
this.compressedVideoFrameRate = 30, this.compressedVideoFrameRate = 30,
this.onError,
}) : super(key: key); }) : super(key: key);
/// Message to edit /// Message to edit
@@ -233,22 +244,21 @@ class MessageInput extends StatefulWidget {
/// Customize the tile for the mentions overlay /// Customize the tile for the mentions overlay
final MentionTileBuilder? mentionsTileBuilder; final MentionTileBuilder? mentionsTileBuilder;
/// A callback for error reporting
final ErrorListener? onError;
@override @override
MessageInputState createState() => MessageInputState(); MessageInputState createState() => MessageInputState();
/// Use this method to get the current [StreamChatState] instance /// Use this method to get the current [StreamChatState] instance
static MessageInputState of(BuildContext context) { static MessageInputState of(BuildContext context) {
MessageInputState? messageInputState; MessageInputState? messageInputState;
messageInputState = context.findAncestorStateOfType<MessageInputState>(); messageInputState = context.findAncestorStateOfType<MessageInputState>();
assert(
if (messageInputState == null) { messageInputState != null,
throw Exception( 'You must have a MessageInput widget as ancestor of your widget tree',
// ignore: lines_longer_than_80_chars );
'You must have a MessageInput widget as ancestor of your widget tree'); return messageInputState!;
}
return messageInputState;
} }
} }
@@ -1989,7 +1999,7 @@ class MessageInputState extends State<MessageInput> {
} }
/// Sends the current message /// Sends the current message
void sendMessage() async { Future<void> sendMessage() async {
var text = textEditingController.text.trim(); var text = textEditingController.text.trim();
if (text.isEmpty && _attachments.isEmpty) { if (text.isEmpty && _attachments.isEmpty) {
return; return;
@@ -2005,9 +2015,7 @@ class MessageInputState extends State<MessageInput> {
textEditingController.clear(); textEditingController.clear();
_attachments.clear(); _attachments.clear();
if (widget.onQuotedMessageCleared != null) { widget.onQuotedMessageCleared?.call();
widget.onQuotedMessageCleared!();
}
setState(() { setState(() {
_messageIsPresent = false; _messageIsPresent = false;
@@ -2019,7 +2027,6 @@ class MessageInputState extends State<MessageInput> {
_mentionsOverlay?.remove(); _mentionsOverlay?.remove();
_mentionsOverlay = null; _mentionsOverlay = null;
Future sendingFuture;
Message message; Message message;
if (widget.editMessage != null) { if (widget.editMessage != null) {
message = widget.editMessage!.copyWith( message = widget.editMessage!.copyWith(
@@ -2057,26 +2064,32 @@ class MessageInputState extends State<MessageInput> {
_mentionedUsers.clear(); _mentionedUsers.clear();
if (widget.editMessage == null || try {
widget.editMessage!.status == MessageSendingStatus.failed || Future sendingFuture;
widget.editMessage!.status == MessageSendingStatus.sending) { if (widget.editMessage == null ||
sendingFuture = channel.sendMessage(message); widget.editMessage!.status == MessageSendingStatus.failed ||
} else { widget.editMessage!.status == MessageSendingStatus.sending) {
sendingFuture = channel.updateMessage(message); sendingFuture = channel.sendMessage(message);
} } else {
sendingFuture = channel.updateMessage(message);
}
if (!shouldUnfocus) { if (!shouldUnfocus) {
FocusScope.of(context).requestFocus(_focusNode); FocusScope.of(context).requestFocus(_focusNode);
} }
return sendingFuture.then((resp) { final resp = await sendingFuture;
if (resp.message?.type == 'error') { if (resp.message?.type == 'error') {
_parseExistingMessage(message); _parseExistingMessage(message);
} }
if (widget.onMessageSent != null) { widget.onMessageSent?.call(resp.message);
widget.onMessageSent!(resp.message); } catch (e, stk) {
if (widget.onError != null) {
widget.onError?.call(e, stk);
} else {
rethrow;
} }
}); }
} }
StreamSubscription? _keyboardListener; StreamSubscription? _keyboardListener;