diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 012a2c9f..e02386d9 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -69,7 +69,6 @@ class MessageActionsModal extends StatelessWidget { message.status == null)) Center( child: ReactionPicker( - channel: channel, message: message, messageTheme: messageTheme, ), diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 90e1fb97..6a7f398d 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/reaction_bubble.dart'; import 'package:stream_chat_flutter/src/reaction_picker.dart'; -import 'package:stream_chat_flutter/src/stream_channel.dart'; import 'package:stream_chat_flutter/src/stream_chat.dart'; import 'package:stream_chat_flutter/src/user_avatar.dart'; @@ -28,20 +27,19 @@ class MessageReactionsModal extends StatelessWidget { Key key, @required this.message, @required this.messageTheme, - this.showReactions, + this.showReactions = true, this.showDeleteMessage, this.showEditMessage, this.onThreadTap, this.showReply, this.editMessageInputBuilder, this.messageShape, - this.reverse, + this.reverse = false, this.onUserAvatarTap, }) : super(key: key); @override Widget build(BuildContext context) { - final channel = StreamChannel.of(context).channel; return Stack( children: [ Positioned.fill( @@ -70,7 +68,6 @@ class MessageReactionsModal extends StatelessWidget { message.status == null)) Center( child: ReactionPicker( - channel: channel, message: message, messageTheme: messageTheme, ), @@ -91,7 +88,7 @@ class MessageReactionsModal extends StatelessWidget { SizedBox( height: 16, ), - if (message.latestReactions.isNotEmpty) + if (message.latestReactions?.isNotEmpty == true) Container( constraints: BoxConstraints.loose(Size.fromHeight(400)), child: _buildReactionCard(context), diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index ef4eba2d..8135bea7 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -519,8 +519,9 @@ class _MessageWidgetState extends State { List _parseAttachments(BuildContext context) { final images = widget.message.attachments - .where((element) => element.type == 'image') - .toList(); + ?.where((element) => element.type == 'image') + ?.toList() ?? + []; if (images.length > 1) { return [ diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 4f6cdf91..5855b59f 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -13,13 +13,11 @@ class ReactionPicker extends StatelessWidget { const ReactionPicker({ Key key, @required this.message, - @required this.channel, @required this.messageTheme, }) : super(key: key); final Message message; final MessageTheme messageTheme; - final Channel channel; @override Widget build(BuildContext context) { @@ -83,13 +81,13 @@ class ReactionPicker extends StatelessWidget { /// Add a reaction to the message void sendReaction(BuildContext context, String reactionType) { - channel.sendReaction(message, reactionType); + StreamChannel.of(context).channel.sendReaction(message, reactionType); Navigator.of(context).pop(); } /// Remove a reaction from the message void removeReaction(BuildContext context, Reaction reaction) { - channel.deleteReaction(message, reaction); + StreamChannel.of(context).channel.deleteReaction(message, reaction); Navigator.of(context).pop(); } } diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index a3d5b6f5..a86206eb 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -70,7 +70,7 @@ class UserAvatar extends StatelessWidget { : StreamChatTheme.of(context).defaultUserImage(context, user), ), ), - if (showOnlineStatus && user.online) + if (showOnlineStatus && user.online == true) Positioned( top: 0, right: 0, diff --git a/test/src/channel_preview_test.dart b/test/src/channel_preview_test.dart index 122e2283..94c45ac2 100644 --- a/test/src/channel_preview_test.dart +++ b/test/src/channel_preview_test.dart @@ -3,13 +3,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -class MockClient extends Mock implements Client {} - -class MockClientState extends Mock implements ClientState {} - -class MockChannel extends Mock implements Channel {} - -class MockChannelState extends Mock implements ChannelClientState {} +import 'mocks.dart'; void main() { testWidgets( diff --git a/test/src/message_reaction_modal_test.dart b/test/src/message_reaction_modal_test.dart new file mode 100644 index 00000000..566d02a0 --- /dev/null +++ b/test/src/message_reaction_modal_test.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:stream_chat_flutter/src/message_reactions_modal.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import 'mocks.dart'; + +void main() { + testWidgets( + 'it should show one thumbs from the picker', + (WidgetTester tester) async { + final themeData = ThemeData(); + final streamTheme = StreamChatThemeData.getDefaultTheme(themeData); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: StreamChatTheme( + data: streamTheme, + child: Container( + child: MessageReactionsModal( + message: Message( + text: 'test', + user: User( + id: 'test-user', + ), + ), + messageTheme: streamTheme.ownMessageTheme, + ), + ), + ), + ), + ); + + expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsOneWidget); + }, + ); + + testWidgets( + 'it should show two reactions', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + + when(client.state).thenReturn(clientState); + when(clientState.user).thenReturn(OwnUser(id: 'user-id')); + + final themeData = ThemeData(); + final streamTheme = StreamChatThemeData.getDefaultTheme(themeData); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: StreamChat( + streamChatThemeData: streamTheme, + client: client, + child: Container( + child: MessageReactionsModal( + message: Message( + text: 'test', + user: User( + id: 'test-user', + ), + latestReactions: [ + Reaction( + type: 'thumbs_up', + user: User(id: 'test'), + ), + Reaction( + type: 'love', + user: User(id: 'test'), + ), + ], + ), + messageTheme: streamTheme.ownMessageTheme, + ), + ), + ), + ), + ); + await tester.pump(); + + expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsNWidgets(2)); + expect(find.byIcon(StreamIcons.love_reaction), findsNWidgets(2)); + expect(find.text('test'), findsNWidgets(2)); + }, + ); +} diff --git a/test/src/mocks.dart b/test/src/mocks.dart new file mode 100644 index 00000000..37fa5530 --- /dev/null +++ b/test/src/mocks.dart @@ -0,0 +1,10 @@ +import 'package:mockito/mockito.dart'; +import 'package:stream_chat/stream_chat.dart'; + +class MockClient extends Mock implements Client {} + +class MockClientState extends Mock implements ClientState {} + +class MockChannel extends Mock implements Channel {} + +class MockChannelState extends Mock implements ChannelClientState {}