diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 12024e08..ee0bb635 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -573,6 +573,10 @@ class _MessageInputState extends State { file = await FilePicker.getFile(type: type); } + if (file == null) { + return; + } + final channel = StreamChannel.of(context).channel; final bytes = await file.readAsBytes(); @@ -717,6 +721,7 @@ class _MessageInputState extends State { imageUrl: attachment.type == FileType.IMAGE ? attachment.url : null, assetUrl: attachment.url, type: type, + localUri: attachment.file.uri, ); }); } diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 427c5419..033d695b 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -1,3 +1,4 @@ +import 'dart:io'; import 'dart:math'; import 'package:cached_network_image/cached_network_image.dart'; @@ -450,6 +451,32 @@ class _MessageWidgetState extends State ); } + Widget _buildSendingError(Widget child) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.message.status == MessageSendingStatus.FAILED) + Text( + 'MESSAGE FAILED · CLICK TO TRY AGAIN', + style: _messageTheme.messageText.copyWith( + color: Colors.black.withOpacity(.5), + fontSize: 11, + ), + ), + if (widget.message.status == MessageSendingStatus.FAILED_UPDATE) + Text( + 'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN', + style: _messageTheme.messageText.copyWith( + color: Colors.black.withOpacity(.5), + fontSize: 11, + ), + ), + child, + ], + ); + } + Padding _buildMessageText( int nOfAttachmentWidgets, String text, @@ -465,62 +492,41 @@ class _MessageWidgetState extends State _buildBoxDecoration(_isLastUser || nOfAttachmentWidgets > 0), padding: EdgeInsets.all(10), constraints: BoxConstraints.loose(Size.fromWidth(300)), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.message.status == MessageSendingStatus.FAILED) - Text( - 'MESSAGE FAILED · CLICK TO TRY AGAIN', - style: _messageTheme.messageText.copyWith( - color: Colors.black.withOpacity(.5), - fontSize: 11, - ), - ), - if (widget.message.status == MessageSendingStatus.FAILED_UPDATE) - Text( - 'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN', - style: _messageTheme.messageText.copyWith( - color: Colors.black.withOpacity(.5), - fontSize: 11, - ), - ), - MarkdownBody( - data: text, - onTapLink: (link) { - if (link.startsWith('@')) { - final mentionedUser = - widget.message.mentionedUsers.firstWhere( - (u) => '@${u.name.replaceAll(' ', '')}' == link, - orElse: () => null, - ); + child: _buildSendingError( + MarkdownBody( + data: text, + onTapLink: (link) { + if (link.startsWith('@')) { + final mentionedUser = widget.message.mentionedUsers.firstWhere( + (u) => '@${u.name.replaceAll(' ', '')}' == link, + orElse: () => null, + ); - if (widget.onMentionTap != null) { - widget.onMentionTap(mentionedUser); - } else { - print('tap on ${mentionedUser.name}'); - } + if (widget.onMentionTap != null) { + widget.onMentionTap(mentionedUser); } else { - _launchURL(link); + print('tap on ${mentionedUser.name}'); } - }, - styleSheet: MarkdownStyleSheet.fromTheme( - Theme.of(context).copyWith( - textTheme: Theme.of(context).textTheme.apply( - bodyColor: _messageTheme.messageText.color, - decoration: _messageTheme.messageText.decoration, - decorationColor: - _messageTheme.messageText.decorationColor, - decorationStyle: - _messageTheme.messageText.decorationStyle, - fontFamily: _messageTheme.messageText.fontFamily, - ), - ), - ).copyWith( - p: _messageTheme.messageText, + } else { + _launchURL(link); + } + }, + styleSheet: MarkdownStyleSheet.fromTheme( + Theme.of(context).copyWith( + textTheme: Theme.of(context).textTheme.apply( + bodyColor: _messageTheme.messageText.color, + decoration: _messageTheme.messageText.decoration, + decorationColor: + _messageTheme.messageText.decorationColor, + decorationStyle: + _messageTheme.messageText.decorationStyle, + fontFamily: _messageTheme.messageText.fontFamily, + ), ), + ).copyWith( + p: _messageTheme.messageText, ), - ], + ), ), ), ); @@ -896,42 +902,54 @@ class _MessageWidgetState extends State Widget _buildImage( Attachment attachment, ) { - return GestureDetector( - onTap: () { - print(attachment.toJson()); - Navigator.push(context, MaterialPageRoute(builder: (_) { - return FullScreenImage( - url: attachment.imageUrl ?? - attachment.assetUrl ?? - attachment.thumbUrl, + return Hero( + tag: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl, + child: CachedNetworkImage( + imageBuilder: (context, provider) { + return GestureDetector( + child: Image(image: provider), + onTap: () { + print(attachment.toJson()); + Navigator.push(context, MaterialPageRoute(builder: (_) { + return FullScreenImage( + url: attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl, + ); + })); + }, ); - })); - }, - child: Hero( - tag: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl, - child: CachedNetworkImage( - placeholder: (_, __) { - return Container( - width: 200, - height: 140, - ); - }, - imageUrl: - attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl, - errorWidget: (context, url, error) { - return Container( - width: 200, - height: 140, - color: Color(0xffd0021B).withAlpha(26), - child: Center( - child: Icon( - Icons.error_outline, - color: Colors.white, - ), - ), - ); - }, - fit: BoxFit.cover, + }, + placeholder: (_, __) { + return Container( + width: 200, + height: 140, + ); + }, + imageUrl: + attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl, + errorWidget: (context, url, error) => _buildErrorImage(attachment), + fit: BoxFit.cover, + ), + ); + } + + Widget _buildErrorImage(Attachment attachment) { + if (attachment.localUri != null) { + return Image.file( + File(attachment.localUri.path), + ); + } + return Center( + child: Container( + width: 200, + height: 140, + color: Color(0xffd0021B).withAlpha(26), + child: Center( + child: Icon( + Icons.error_outline, + color: Colors.white, + ), ), ), ); @@ -956,6 +974,9 @@ class _MessageWidgetState extends State videoPlayerController: videoController, autoInitialize: true, errorBuilder: (_, e) { + if (attachment.thumbUrl == null) { + return _buildErrorImage(attachment); + } return Stack( children: [ Container(