From 769258bb53453abf7e8566b7fd6c46f0cd882ec1 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 15 Jul 2021 19:00:03 +0530 Subject: [PATCH 1/8] [UI-KIT] Fix channel_image.dart, remove defaultChannelPreview from theme Signed-off-by: xsahil03x --- .../lib/src/channel_image.dart | 202 +++++++++--------- .../lib/src/group_image.dart | 118 +++++----- .../lib/src/stream_chat_theme.dart | 7 - 3 files changed, 164 insertions(+), 163 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_image.dart index 9ac07033..21737814 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_image.dart @@ -83,121 +83,117 @@ class ChannelImage extends StatelessWidget { Widget build(BuildContext context) { final streamChat = StreamChat.of(context); final channel = this.channel ?? StreamChannel.of(context).channel; + + assert(channel.state != null, 'Channel ${channel.id} is not initialized'); + + final chatThemeData = StreamChatTheme.of(context); + final colorTheme = chatThemeData.colorTheme; + final previewTheme = chatThemeData.channelPreviewTheme.avatarTheme; + return BetterStreamBuilder>( stream: channel.extraDataStream, initialData: channel.extraData, - builder: (context, data) { - String? image; - final chatThemeData = StreamChatTheme.of(context); - if (data.containsKey('image') == true) { - image = data['image']; - } else if (channel.state?.members.length == 2) { - final otherMember = channel.state?.members - .firstWhere((member) => member.user?.id != streamChat.user?.id); - return BetterStreamBuilder( - stream: streamChat.client.state.usersStream - .map((users) => - users[otherMember?.userId] ?? otherMember!.user!) - .distinct(), - initialData: otherMember!.user, - builder: (context, user) => UserAvatar( - borderRadius: borderRadius ?? - chatThemeData - .channelPreviewTheme.avatarTheme?.borderRadius, - user: user ?? otherMember.user!, - constraints: constraints ?? - chatThemeData - .channelPreviewTheme.avatarTheme?.constraints, - onTap: onTap != null ? (_) => onTap!() : null, - selected: selected, - selectionColor: selectionColor ?? - chatThemeData.colorTheme.accentPrimary, - selectionThickness: selectionThickness, - )); - } else { - final images = channel.state?.members - .where((member) => - member.user?.id != streamChat.user?.id && - member.user?.extraData['image'] != null) - .take(4) - // ignore: cast_nullable_to_non_nullable - .map((e) => e.user?.extraData['image'] as String) - .toList(); - return GroupImage( - images: images ?? [], - borderRadius: borderRadius ?? - chatThemeData.channelPreviewTheme.avatarTheme?.borderRadius, - constraints: constraints ?? - chatThemeData.channelPreviewTheme.avatarTheme?.constraints, - onTap: onTap, - selected: selected, - selectionColor: - selectionColor ?? chatThemeData.colorTheme.accentPrimary, - selectionThickness: selectionThickness, - ); - } + builder: (context, extraData) { + final channelImage = extraData['image']; - Widget child = ClipRRect( - borderRadius: borderRadius ?? - chatThemeData.channelPreviewTheme.avatarTheme?.borderRadius, - child: Container( - constraints: constraints ?? - chatThemeData.channelPreviewTheme.avatarTheme?.constraints, - decoration: BoxDecoration( - color: chatThemeData.colorTheme.accentPrimary, - ), - child: Stack( - alignment: Alignment.center, - fit: StackFit.expand, - children: [ - if (image != null) - CachedNetworkImage( - imageUrl: image, - errorWidget: (_, __, ___) => Center( - child: Text( - data.containsKey('name') ? data['name'][0] : '', - style: TextStyle( - color: chatThemeData.colorTheme.barsBg, - fontWeight: FontWeight.bold, - ), + if (channelImage != null) { + Widget child = ClipRRect( + borderRadius: borderRadius ?? previewTheme?.borderRadius, + child: Container( + constraints: constraints ?? previewTheme?.constraints, + decoration: BoxDecoration(color: colorTheme.accentPrimary), + child: InkWell( + onTap: onTap, + child: CachedNetworkImage( + imageUrl: channelImage, + errorWidget: (_, __, ___) => Center( + child: Text( + extraData['name']?[0] ?? '', + style: TextStyle( + color: colorTheme.barsBg, + fontWeight: FontWeight.bold, ), ), - fit: BoxFit.cover, - ) - else - chatThemeData.defaultChannelImage( - context, - channel, - ), - Material( - color: Colors.transparent, - child: InkWell( - onTap: onTap, ), + fit: BoxFit.cover, ), - ], - ), - ), - ); - if (selected) { - child = ClipRRect( - key: const Key('selectedImage'), - borderRadius: (borderRadius ?? - chatThemeData.ownMessageTheme.avatarTheme?.borderRadius ?? - BorderRadius.zero) + - BorderRadius.circular(selectionThickness), - child: Container( - constraints: constraints ?? - chatThemeData.ownMessageTheme.avatarTheme?.constraints, - color: selectionColor ?? chatThemeData.colorTheme.accentPrimary, - child: Padding( - padding: EdgeInsets.all(selectionThickness), - child: child, ), ), ); + + if (selected) { + child = ClipRRect( + key: const Key('selectedImage'), + borderRadius: BorderRadius.circular(selectionThickness) + + (borderRadius ?? + previewTheme?.borderRadius ?? + BorderRadius.zero), + child: Container( + constraints: constraints ?? previewTheme?.constraints, + color: selectionColor ?? colorTheme.accentPrimary, + child: Padding( + padding: EdgeInsets.all(selectionThickness), + child: child, + ), + ), + ); + } + return child; } - return child; + + final currentUser = streamChat.user!; + final otherMembers = channel.state!.members + .where((it) => it.userId != currentUser.id) + .toList(growable: false); + + // our own space, no other members + if (otherMembers.isEmpty) { + return BetterStreamBuilder( + stream: streamChat.client.state.userStream.map((it) => it!), + initialData: currentUser, + builder: (context, user) => UserAvatar( + borderRadius: borderRadius ?? previewTheme?.borderRadius, + user: user, + constraints: constraints ?? previewTheme?.constraints, + onTap: onTap != null ? (_) => onTap!() : null, + selected: selected, + selectionColor: selectionColor ?? colorTheme.accentPrimary, + selectionThickness: selectionThickness, + ), + ); + } + + // 1-1 Conversation + if (otherMembers.length == 1) { + final member = otherMembers.first; + final user = member.user!; + return BetterStreamBuilder( + stream: streamChat.client.state.usersStream + .map((users) => users[member.userId ?? user.id] ?? user) + .distinct(), + initialData: user, + builder: (context, user) => UserAvatar( + borderRadius: borderRadius ?? previewTheme?.borderRadius, + user: user, + constraints: constraints ?? previewTheme?.constraints, + onTap: onTap != null ? (_) => onTap!() : null, + selected: selected, + selectionColor: selectionColor ?? colorTheme.accentPrimary, + selectionThickness: selectionThickness, + ), + ); + } + + // Group conversation + return GroupImage( + members: otherMembers, + borderRadius: borderRadius ?? previewTheme?.borderRadius, + constraints: constraints ?? previewTheme?.constraints, + onTap: onTap, + selected: selected, + selectionColor: selectionColor ?? colorTheme.accentPrimary, + selectionThickness: selectionThickness, + ); }, ); } diff --git a/packages/stream_chat_flutter/lib/src/group_image.dart b/packages/stream_chat_flutter/lib/src/group_image.dart index 3513bda2..62b8b7b5 100644 --- a/packages/stream_chat_flutter/lib/src/group_image.dart +++ b/packages/stream_chat_flutter/lib/src/group_image.dart @@ -1,4 +1,3 @@ -import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -7,7 +6,7 @@ class GroupImage extends StatelessWidget { /// Constructor for creating a [GroupImage] const GroupImage({ Key? key, - required this.images, + required this.members, this.constraints, this.onTap, this.borderRadius, @@ -17,7 +16,7 @@ class GroupImage extends StatelessWidget { }) : super(key: key); /// List of images to display - final List images; + final List members; /// Constraints on the widget final BoxConstraints? constraints; @@ -39,20 +38,22 @@ class GroupImage extends StatelessWidget { @override Widget build(BuildContext context) { - Widget? avatar; - final streamChatTheme = StreamChatTheme.of(context); + final streamChat = StreamChat.of(context); + final channel = StreamChannel.of(context).channel; - avatar = GestureDetector( + assert(channel.state != null, 'Channel ${channel.id} is not initialized'); + + final streamChatTheme = StreamChatTheme.of(context); + final colorTheme = streamChatTheme.colorTheme; + final previewTheme = streamChatTheme.channelPreviewTheme.avatarTheme; + + Widget avatar = GestureDetector( onTap: onTap, child: ClipRRect( - borderRadius: borderRadius ?? - streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius, + borderRadius: borderRadius ?? previewTheme?.borderRadius, child: Container( - constraints: constraints ?? - streamChatTheme.ownMessageTheme.avatarTheme?.constraints, - decoration: BoxDecoration( - color: streamChatTheme.colorTheme.accentPrimary, - ), + constraints: constraints ?? previewTheme?.constraints, + decoration: BoxDecoration(color: colorTheme.accentPrimary), child: Flex( direction: Axis.vertical, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -62,48 +63,62 @@ class GroupImage extends StatelessWidget { child: Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.stretch, - children: images - .take(2) - .map((url) => Flexible( - fit: FlexFit.tight, - child: FittedBox( - fit: BoxFit.cover, - clipBehavior: Clip.antiAlias, - child: Transform.scale( - scale: 1.2, - child: CachedNetworkImage( - imageUrl: url, - fit: BoxFit.cover, - ), - ), + children: members.take(2).map((member) { + final user = member.user!; + return Flexible( + fit: FlexFit.tight, + child: FittedBox( + fit: BoxFit.cover, + clipBehavior: Clip.antiAlias, + child: Transform.scale( + scale: 1.2, + child: BetterStreamBuilder( + stream: streamChat.client.state.usersStream + .map((users) => + users[member.userId ?? user.id] ?? user) + .distinct(), + initialData: user, + builder: (context, user) => UserAvatar( + user: user, + borderRadius: BorderRadius.zero, ), - )) - .toList(), + ), + ), + ), + ); + }).toList(), ), ), - if (images.length > 2) + if (members.length > 2) Flexible( fit: FlexFit.tight, child: Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.stretch, - children: images - .skip(2) - .map((url) => Flexible( - fit: FlexFit.tight, - child: FittedBox( - fit: BoxFit.cover, - clipBehavior: Clip.antiAlias, - child: Transform.scale( - scale: 1.2, - child: CachedNetworkImage( - imageUrl: url, - fit: BoxFit.cover, - ), - ), + children: members.skip(2).take(2).map((member) { + final user = member.user!; + return Flexible( + fit: FlexFit.tight, + child: FittedBox( + fit: BoxFit.cover, + clipBehavior: Clip.antiAlias, + child: Transform.scale( + scale: 1.2, + child: BetterStreamBuilder( + stream: streamChat.client.state.usersStream + .map((users) => + users[member.userId ?? user.id] ?? user) + .distinct(), + initialData: user, + builder: (context, user) => UserAvatar( + user: user, + borderRadius: BorderRadius.zero, ), - )) - .toList(), + ), + ), + ), + ); + }).toList(), ), ), ], @@ -114,14 +129,11 @@ class GroupImage extends StatelessWidget { if (selected) { avatar = ClipRRect( - borderRadius: (borderRadius ?? - streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius ?? - BorderRadius.zero) + - BorderRadius.circular(selectionThickness), + borderRadius: BorderRadius.circular(selectionThickness) + + (borderRadius ?? previewTheme?.borderRadius ?? BorderRadius.zero), child: Container( - color: selectionColor ?? streamChatTheme.colorTheme.accentPrimary, - height: 64, - width: 64, + constraints: constraints ?? previewTheme?.constraints, + color: selectionColor ?? colorTheme.accentPrimary, child: Padding( padding: EdgeInsets.all(selectionThickness), child: avatar, diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart index 72b04a80..6956ff3d 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart @@ -103,7 +103,6 @@ class StreamChatThemeData { required this.otherMessageTheme, required this.ownMessageTheme, required this.messageInputTheme, - required this.defaultChannelImage, required this.defaultUserImage, required this.primaryIconTheme, required this.reactionIcons, @@ -145,9 +144,6 @@ class StreamChatThemeData { /// Theme dedicated to the [MessageInput] widget final MessageInputTheme messageInputTheme; - /// The widget that will be built when the channel image is unavailable - final Widget Function(BuildContext, Channel) defaultChannelImage; - /// The widget that will be built when the user image is unavailable final Widget Function(BuildContext, User) defaultUserImage; @@ -179,7 +175,6 @@ class StreamChatThemeData { textTheme: this.textTheme.merge(textTheme), colorTheme: this.colorTheme.merge(colorTheme), primaryIconTheme: this.primaryIconTheme.merge(primaryIconTheme), - defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage, defaultUserImage: defaultUserImage ?? this.defaultUserImage, channelPreviewTheme: this.channelPreviewTheme.merge(channelPreviewTheme), @@ -199,7 +194,6 @@ class StreamChatThemeData { textTheme: textTheme.merge(other.textTheme), colorTheme: colorTheme.merge(other.colorTheme), primaryIconTheme: other.primaryIconTheme, - defaultChannelImage: other.defaultChannelImage, defaultUserImage: other.defaultUserImage, channelPreviewTheme: channelPreviewTheme.merge(other.channelPreviewTheme), channelTheme: channelTheme.merge(other.channelTheme), @@ -223,7 +217,6 @@ class StreamChatThemeData { textTheme: textTheme, colorTheme: colorTheme, primaryIconTheme: iconTheme, - defaultChannelImage: (context, channel) => const SizedBox(), defaultUserImage: (context, user) => Center( child: CachedNetworkImage( filterQuality: FilterQuality.high, From 6f8dbf7e00e9822e6aa67bddfbb19e5533823249 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 15 Jul 2021 19:02:15 +0530 Subject: [PATCH 2/8] ChannelPreview: Minor refactoring Signed-off-by: xsahil03x --- .../lib/src/channel_preview.dart | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_preview.dart b/packages/stream_chat_flutter/lib/src/channel_preview.dart index 231b5f94..b6d89168 100644 --- a/packages/stream_chat_flutter/lib/src/channel_preview.dart +++ b/packages/stream_chat_flutter/lib/src/channel_preview.dart @@ -81,20 +81,9 @@ class ChannelPreview extends StatelessWidget { contentPadding: const EdgeInsets.symmetric( horizontal: 8, ), - onTap: () { - if (onTap != null) { - onTap!(channel); - } - }, - onLongPress: () { - if (onLongPress != null) { - onLongPress!(channel); - } - }, - leading: leading ?? - ChannelImage( - onTap: onImageTap, - ), + onTap: () => onTap?.call(channel), + onLongPress: () => onLongPress?.call(channel), + leading: leading ?? ChannelImage(onTap: onImageTap), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ From c2563c9d5f72a262572f605d0c43a203f7c95b9a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 12:19:50 +0530 Subject: [PATCH 3/8] chore: fix merge conflicts Signed-off-by: xsahil03x --- packages/stream_chat_flutter/lib/src/stream_chat_theme.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart index 0c56fd0d..c62e92ec 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart @@ -55,7 +55,6 @@ class StreamChatThemeData { MessageTheme? otherMessageTheme, MessageTheme? ownMessageTheme, MessageInputTheme? messageInputTheme, - Widget Function(BuildContext, Channel)? defaultChannelImage, Widget Function(BuildContext, User)? defaultUserImage, IconThemeData? primaryIconTheme, List? reactionIcons, @@ -79,7 +78,6 @@ class StreamChatThemeData { otherMessageTheme: otherMessageTheme, ownMessageTheme: ownMessageTheme, messageInputTheme: messageInputTheme, - defaultChannelImage: defaultChannelImage, defaultUserImage: defaultUserImage, primaryIconTheme: primaryIconTheme, reactionIcons: reactionIcons, From d2402ba3d006ea7df6c63e01403d3485c9470176 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 13:35:51 +0530 Subject: [PATCH 4/8] fix: tests Signed-off-by: xsahil03x --- .../lib/src/channel_image.dart | 18 ++-- .../lib/src/group_image.dart | 94 ++++++++++--------- .../test/src/channel_header_test.dart | 24 +++-- .../test/src/channel_image_test.dart | 48 +++------- .../test/src/channel_preview_test.dart | 4 +- 5 files changed, 94 insertions(+), 94 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_image.dart index 21737814..803feed8 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_image.dart @@ -166,15 +166,17 @@ class ChannelImage extends StatelessWidget { // 1-1 Conversation if (otherMembers.length == 1) { final member = otherMembers.first; - final user = member.user!; - return BetterStreamBuilder( - stream: streamChat.client.state.usersStream - .map((users) => users[member.userId ?? user.id] ?? user) - .distinct(), - initialData: user, - builder: (context, user) => UserAvatar( + return BetterStreamBuilder( + stream: channel.state!.membersStream.map( + (members) => members.firstWhere( + (it) => it.userId == member.userId, + orElse: () => member, + ), + ), + initialData: member, + builder: (context, member) => UserAvatar( borderRadius: borderRadius ?? previewTheme?.borderRadius, - user: user, + user: member.user!, constraints: constraints ?? previewTheme?.constraints, onTap: onTap != null ? (_) => onTap!() : null, selected: selected, diff --git a/packages/stream_chat_flutter/lib/src/group_image.dart b/packages/stream_chat_flutter/lib/src/group_image.dart index 62b8b7b5..13a3c5f7 100644 --- a/packages/stream_chat_flutter/lib/src/group_image.dart +++ b/packages/stream_chat_flutter/lib/src/group_image.dart @@ -38,7 +38,6 @@ class GroupImage extends StatelessWidget { @override Widget build(BuildContext context) { - final streamChat = StreamChat.of(context); final channel = StreamChannel.of(context).channel; assert(channel.state != null, 'Channel ${channel.id} is not initialized'); @@ -63,30 +62,34 @@ class GroupImage extends StatelessWidget { child: Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.stretch, - children: members.take(2).map((member) { - final user = member.user!; - return Flexible( - fit: FlexFit.tight, - child: FittedBox( - fit: BoxFit.cover, - clipBehavior: Clip.antiAlias, - child: Transform.scale( - scale: 1.2, - child: BetterStreamBuilder( - stream: streamChat.client.state.usersStream - .map((users) => - users[member.userId ?? user.id] ?? user) - .distinct(), - initialData: user, - builder: (context, user) => UserAvatar( - user: user, - borderRadius: BorderRadius.zero, + children: members + .take(2) + .map( + (member) => Flexible( + fit: FlexFit.tight, + child: FittedBox( + fit: BoxFit.cover, + clipBehavior: Clip.antiAlias, + child: Transform.scale( + scale: 1.2, + child: BetterStreamBuilder( + stream: channel.state!.membersStream.map( + (members) => members.firstWhere( + (it) => it.userId == member.userId, + orElse: () => member, + ), + ), + initialData: member, + builder: (context, member) => UserAvatar( + user: member.user!, + borderRadius: BorderRadius.zero, + ), + ), ), ), ), - ), - ); - }).toList(), + ) + .toList(), ), ), if (members.length > 2) @@ -95,30 +98,35 @@ class GroupImage extends StatelessWidget { child: Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.stretch, - children: members.skip(2).take(2).map((member) { - final user = member.user!; - return Flexible( - fit: FlexFit.tight, - child: FittedBox( - fit: BoxFit.cover, - clipBehavior: Clip.antiAlias, - child: Transform.scale( - scale: 1.2, - child: BetterStreamBuilder( - stream: streamChat.client.state.usersStream - .map((users) => - users[member.userId ?? user.id] ?? user) - .distinct(), - initialData: user, - builder: (context, user) => UserAvatar( - user: user, - borderRadius: BorderRadius.zero, + children: members + .skip(2) + .take(2) + .map( + (member) => Flexible( + fit: FlexFit.tight, + child: FittedBox( + fit: BoxFit.cover, + clipBehavior: Clip.antiAlias, + child: Transform.scale( + scale: 1.2, + child: BetterStreamBuilder( + stream: channel.state!.membersStream.map( + (members) => members.firstWhere( + (it) => it.userId == member.userId, + orElse: () => member, + ), + ), + initialData: member, + builder: (context, member) => UserAvatar( + user: member.user!, + borderRadius: BorderRadius.zero, + ), + ), ), ), ), - ), - ); - }).toList(), + ) + .toList(), ), ), ], diff --git a/packages/stream_chat_flutter/test/src/channel_header_test.dart b/packages/stream_chat_flutter/test/src/channel_header_test.dart index 87f3d028..bf259ae6 100644 --- a/packages/stream_chat_flutter/test/src/channel_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_header_test.dart @@ -14,10 +14,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); @@ -76,10 +78,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); @@ -141,10 +145,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); @@ -207,10 +213,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); @@ -281,10 +289,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); @@ -346,10 +356,12 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); diff --git a/packages/stream_chat_flutter/test/src/channel_image_test.dart b/packages/stream_chat_flutter/test/src/channel_image_test.dart index ba913a77..1f7623db 100644 --- a/packages/stream_chat_flutter/test/src/channel_image_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_image_test.dart @@ -132,9 +132,10 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final currentUser = OwnUser(id: 'user-id'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(currentUser); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ @@ -143,36 +144,7 @@ void main() { when(() => channel.extraData).thenReturn({ 'name': 'test', }); - when(() => channelState.membersStream).thenAnswer((i) => Stream.value([ - Member( - userId: 'user-id', - user: User( - id: 'user-id', - extraData: { - 'image': 'testimage1', - }, - ), - ), - Member( - userId: 'user-id2', - user: User( - id: 'user-id2', - extraData: { - 'image': 'testimage2', - }, - ), - ), - Member( - userId: 'user-id3', - user: User( - id: 'user-id3', - extraData: { - 'image': 'testimage3', - }, - ), - ), - ])); - when(() => channelState.members).thenReturn([ + final members = [ Member( userId: 'user-id', user: User( @@ -200,7 +172,10 @@ void main() { }, ), ), - ]); + ]; + when(() => channelState.members).thenReturn(members); + when(() => channelState.membersStream) + .thenAnswer((_) => Stream.value(members)); await tester.pumpWidget(MaterialApp( home: StreamChat( @@ -215,10 +190,11 @@ void main() { )); final image = tester.widget(find.byType(GroupImage)); - expect(image.images, [ - 'testimage2', - 'testimage3', - ]); + final otherMembers = members.where((it) => it.userId != currentUser.id); + expect( + image.members.map((it) => it.user?.id), + otherMembers.map((it) => it.user?.id), + ); }, ); diff --git a/packages/stream_chat_flutter/test/src/channel_preview_test.dart b/packages/stream_chat_flutter/test/src/channel_preview_test.dart index baa82614..31a1710f 100644 --- a/packages/stream_chat_flutter/test/src/channel_preview_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_preview_test.dart @@ -13,11 +13,13 @@ void main() { final clientState = MockClientState(); final channel = MockChannel(); final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); when(() => channel.cid).thenReturn('cid'); when(() => client.state).thenReturn(clientState); - when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.user).thenReturn(user); + when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); From 8dcd5cde647329e49e982f05164570682095cfb8 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 13:59:28 +0530 Subject: [PATCH 5/8] refactor!: rename ChannelImage -> ChannelAvatar, GroupImage -> GroupAvatar Signed-off-by: xsahil03x --- .../src/{channel_image.dart => channel_avatar.dart} | 8 ++++---- .../stream_chat_flutter/lib/src/channel_header.dart | 4 ++-- .../lib/src/channel_list_view.dart | 2 +- .../stream_chat_flutter/lib/src/channel_preview.dart | 4 ++-- .../lib/src/{group_image.dart => group_avatar.dart} | 6 +++--- .../stream_chat_flutter/lib/stream_chat_flutter.dart | 2 +- .../test/src/channel_header_test.dart | 6 +++--- .../test/src/channel_image_test.dart | 12 ++++++------ .../test/src/channel_preview_test.dart | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) rename packages/stream_chat_flutter/lib/src/{channel_image.dart => channel_avatar.dart} (97%) rename packages/stream_chat_flutter/lib/src/{group_image.dart => group_avatar.dart} (97%) diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_avatar.dart similarity index 97% rename from packages/stream_chat_flutter/lib/src/channel_image.dart rename to packages/stream_chat_flutter/lib/src/channel_avatar.dart index 803feed8..4ab6ba31 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_avatar.dart @@ -1,6 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/group_image.dart'; +import 'package:stream_chat_flutter/src/group_avatar.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; @@ -45,9 +45,9 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// The widget renders the ui based on the first ancestor of type /// [StreamChatTheme]. /// Modify it to change the widget appearance. -class ChannelImage extends StatelessWidget { +class ChannelAvatar extends StatelessWidget { /// Instantiate a new ChannelImage - const ChannelImage({ + const ChannelAvatar({ Key? key, this.channel, this.constraints, @@ -187,7 +187,7 @@ class ChannelImage extends StatelessWidget { } // Group conversation - return GroupImage( + return GroupAvatar( members: otherMembers, borderRadius: borderRadius ?? previewTheme?.borderRadius, constraints: constraints ?? previewTheme?.constraints, diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 16c1f1b7..8f586516 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -98,7 +98,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { final Widget? leading; /// AppBar actions - /// By default it shows the [ChannelImage] + /// By default it shows the [ChannelAvatar] final List? actions; @override @@ -147,7 +147,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { Padding( padding: const EdgeInsets.only(right: 10), child: Center( - child: ChannelImage( + child: ChannelAvatar( borderRadius: chatThemeData.channelTheme .channelHeaderTheme.avatarTheme?.borderRadius, constraints: chatThemeData.channelTheme diff --git a/packages/stream_chat_flutter/lib/src/channel_list_view.dart b/packages/stream_chat_flutter/lib/src/channel_list_view.dart index 06f1aee9..83f196df 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_view.dart @@ -620,7 +620,7 @@ class _ChannelListViewState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - ChannelImage( + ChannelAvatar( channel: channel, borderRadius: BorderRadius.circular(32), selected: selected, diff --git a/packages/stream_chat_flutter/lib/src/channel_preview.dart b/packages/stream_chat_flutter/lib/src/channel_preview.dart index b6d89168..bf615248 100644 --- a/packages/stream_chat_flutter/lib/src/channel_preview.dart +++ b/packages/stream_chat_flutter/lib/src/channel_preview.dart @@ -55,7 +55,7 @@ class ChannelPreview extends StatelessWidget { final Widget? subtitle; /// Widget rendering the leading element, by default - /// it shows the [ChannelImage] + /// it shows the [ChannelAvatar] final Widget? leading; /// Widget rendering the trailing element, @@ -83,7 +83,7 @@ class ChannelPreview extends StatelessWidget { ), onTap: () => onTap?.call(channel), onLongPress: () => onLongPress?.call(channel), - leading: leading ?? ChannelImage(onTap: onImageTap), + leading: leading ?? ChannelAvatar(onTap: onImageTap), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/packages/stream_chat_flutter/lib/src/group_image.dart b/packages/stream_chat_flutter/lib/src/group_avatar.dart similarity index 97% rename from packages/stream_chat_flutter/lib/src/group_image.dart rename to packages/stream_chat_flutter/lib/src/group_avatar.dart index 13a3c5f7..4a16279e 100644 --- a/packages/stream_chat_flutter/lib/src/group_image.dart +++ b/packages/stream_chat_flutter/lib/src/group_avatar.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Widget for constructing a group of images -class GroupImage extends StatelessWidget { - /// Constructor for creating a [GroupImage] - const GroupImage({ +class GroupAvatar extends StatelessWidget { + /// Constructor for creating a [GroupAvatar] + const GroupAvatar({ Key? key, required this.members, this.constraints, diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 45c0f32e..2b2485c4 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -3,7 +3,7 @@ export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; export 'src/attachment/attachment.dart'; export 'src/back_button.dart'; export 'src/channel_header.dart'; -export 'src/channel_image.dart'; +export 'src/channel_avatar.dart'; export 'src/channel_list_header.dart'; export 'src/channel_list_view.dart'; export 'src/channel_name.dart'; diff --git a/packages/stream_chat_flutter/test/src/channel_header_test.dart b/packages/stream_chat_flutter/test/src/channel_header_test.dart index bf259ae6..211a7132 100644 --- a/packages/stream_chat_flutter/test/src/channel_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_header_test.dart @@ -65,7 +65,7 @@ void main() { )); expect(find.text('test'), findsOneWidget); - expect(find.byType(ChannelImage), findsOneWidget); + expect(find.byType(ChannelAvatar), findsOneWidget); expect(find.byType(StreamBackButton), findsOneWidget); expect(find.byType(ChannelInfo), findsOneWidget); }, @@ -271,7 +271,7 @@ void main() { expect(find.text('test'), findsNothing); expect(find.byType(StreamBackButton), findsNothing); - expect(find.byType(ChannelImage), findsNothing); + expect(find.byType(ChannelAvatar), findsNothing); expect(find.byType(ChannelInfo), findsNothing); expect(find.text('leading'), findsOneWidget); expect(find.text('title'), findsOneWidget); @@ -415,7 +415,7 @@ void main() { )); await tester.tap(find.byType(StreamBackButton)); - await tester.tap(find.byType(ChannelImage)); + await tester.tap(find.byType(ChannelAvatar)); await tester.tap(find.byType(ChannelName)); expect(backPressed, true); diff --git a/packages/stream_chat_flutter/test/src/channel_image_test.dart b/packages/stream_chat_flutter/test/src/channel_image_test.dart index 1f7623db..5eea5569 100644 --- a/packages/stream_chat_flutter/test/src/channel_image_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_image_test.dart @@ -2,7 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/src/group_image.dart'; +import 'package:stream_chat_flutter/src/group_avatar.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'mocks.dart'; @@ -35,7 +35,7 @@ void main() { child: StreamChannel( channel: channel, child: const Scaffold( - body: ChannelImage(), + body: ChannelAvatar(), ), ), ), @@ -113,7 +113,7 @@ void main() { child: StreamChannel( channel: channel, child: const Scaffold( - body: ChannelImage(), + body: ChannelAvatar(), ), ), ), @@ -183,13 +183,13 @@ void main() { child: StreamChannel( channel: channel, child: const Scaffold( - body: ChannelImage(), + body: ChannelAvatar(), ), ), ), )); - final image = tester.widget(find.byType(GroupImage)); + final image = tester.widget(find.byType(GroupAvatar)); final otherMembers = members.where((it) => it.userId != currentUser.id); expect( image.members.map((it) => it.user?.id), @@ -225,7 +225,7 @@ void main() { child: StreamChannel( channel: channel, child: const Scaffold( - body: ChannelImage( + body: ChannelAvatar( selected: true, ), ), diff --git a/packages/stream_chat_flutter/test/src/channel_preview_test.dart b/packages/stream_chat_flutter/test/src/channel_preview_test.dart index 31a1710f..6add0c60 100644 --- a/packages/stream_chat_flutter/test/src/channel_preview_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_preview_test.dart @@ -80,7 +80,7 @@ void main() { expect(find.text('test name'), findsOneWidget); expect(find.text('1'), findsOneWidget); expect(find.text('hello'), findsOneWidget); - expect(find.byType(ChannelImage), findsOneWidget); + expect(find.byType(ChannelAvatar), findsOneWidget); }, ); } From 4533828fe83d1dd48b98b78c2928a4e5f4f49b47 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 14:42:22 +0530 Subject: [PATCH 6/8] chore: fix analyzer issues Signed-off-by: xsahil03x --- packages/stream_chat_flutter/lib/src/message_input.dart | 6 +++--- packages/stream_chat_flutter/lib/stream_chat_flutter.dart | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 9dca6c6b..5a4f6822 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -1859,11 +1859,11 @@ class MessageInputState extends State { } if (camera) { - PickedFile? pickedFile; + XFile? pickedFile; if (fileType == DefaultAttachmentTypes.image) { - pickedFile = await _imagePicker.getImage(source: ImageSource.camera); + pickedFile = await _imagePicker.pickImage(source: ImageSource.camera); } else if (fileType == DefaultAttachmentTypes.video) { - pickedFile = await _imagePicker.getVideo(source: ImageSource.camera); + pickedFile = await _imagePicker.pickVideo(source: ImageSource.camera); } if (pickedFile == null) { return; diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 2b2485c4..39aabb85 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -2,8 +2,8 @@ export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; export 'src/attachment/attachment.dart'; export 'src/back_button.dart'; -export 'src/channel_header.dart'; export 'src/channel_avatar.dart'; +export 'src/channel_header.dart'; export 'src/channel_list_header.dart'; export 'src/channel_list_view.dart'; export 'src/channel_name.dart'; diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 70a02f56..ce7ba0e5 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: flutter_svg: ^0.22.0 http_parser: ^4.0.0 image_gallery_saver: ^1.6.9 - image_picker: ^0.8.0 + image_picker: ^0.8.2 jiffy: ^4.1.0 lottie: ^1.0.1 meta: ^1.3.0 From cb0f47e02c3ee4fdd5f56bcb12b97b906d802797 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 14:48:07 +0530 Subject: [PATCH 7/8] fix: tutorial_part_3.dart Signed-off-by: xsahil03x --- packages/stream_chat_flutter/example/lib/tutorial_part_3.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/example/lib/tutorial_part_3.dart b/packages/stream_chat_flutter/example/lib/tutorial_part_3.dart index 99e9ceab..78081c85 100644 --- a/packages/stream_chat_flutter/example/lib/tutorial_part_3.dart +++ b/packages/stream_chat_flutter/example/lib/tutorial_part_3.dart @@ -114,7 +114,7 @@ class ChannelListPage extends StatelessWidget { ), ); }, - leading: ChannelImage( + leading: ChannelAvatar( channel: channel, ), title: ChannelName( From 9a3d094282d07f7ee2cd252dca90aab8147d0fca Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 16 Jul 2021 14:51:32 +0530 Subject: [PATCH 8/8] chore: fix analyzer warnings Signed-off-by: xsahil03x --- .../test/src/channel_image_test.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/channel_image_test.dart b/packages/stream_chat_flutter/test/src/channel_image_test.dart index 5eea5569..7c620774 100644 --- a/packages/stream_chat_flutter/test/src/channel_image_test.dart +++ b/packages/stream_chat_flutter/test/src/channel_image_test.dart @@ -74,7 +74,7 @@ void main() { userId: 'user-id2', user: User( id: 'user-id2', - extraData: { + extraData: const { 'image': 'testimage', }, ), @@ -85,7 +85,7 @@ void main() { userId: 'user-id2', user: User( id: 'user-id2', - extraData: { + extraData: const { 'image': 'testimage', }, ), @@ -98,7 +98,7 @@ void main() { when(() => clientState.usersStream).thenAnswer((i) => Stream.value({ 'user-id2': User( id: 'user-id2', - extraData: { + extraData: const { 'image': 'testimage', }, ), @@ -149,7 +149,7 @@ void main() { userId: 'user-id', user: User( id: 'user-id', - extraData: { + extraData: const { 'image': 'testimage1', }, ), @@ -158,7 +158,7 @@ void main() { userId: 'user-id2', user: User( id: 'user-id2', - extraData: { + extraData: const { 'image': 'testimage2', }, ), @@ -167,7 +167,7 @@ void main() { userId: 'user-id3', user: User( id: 'user-id3', - extraData: { + extraData: const { 'image': 'testimage3', }, ),