[MessageWidget] Show thread participants in case of thread.

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2021-01-05 18:10:16 +05:30
parent 82c73ac624
commit 28e01a89d4
4 changed files with 78 additions and 75 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ extension StringExtension on String {
} }
/// List extension /// List extension
extension ListX<T> on List<T> { extension IterableX<T> on Iterable<T> {
/// Insert any item<T> inBetween the list items /// Insert any item<T> inBetween the list items
List<T> insertBetween(T item) => expand((e) sync* { List<T> insertBetween(T item) => expand((e) sync* {
yield item; yield item;
+65 -63
View File
@@ -252,7 +252,7 @@ class _MessageWidgetState extends State<MessageWidget> {
bool get showInChannel => bool get showInChannel =>
widget.showInChannelIndicator && widget.message?.showInChannel == true; widget.showInChannelIndicator && widget.message?.showInChannel == true;
bool get _hasQuotedMessage => widget.message?.quotedMessage != null; bool get hasQuotedMessage => widget.message?.quotedMessage != null;
bool get isSendFailed => widget.message.status == MessageSendingStatus.FAILED; bool get isSendFailed => widget.message.status == MessageSendingStatus.FAILED;
@@ -264,6 +264,10 @@ class _MessageWidgetState extends State<MessageWidget> {
bool get isFailedState => isSendFailed || isUpdateFailed || isDeleteFailed; bool get isFailedState => isSendFailed || isUpdateFailed || isDeleteFailed;
bool get isGiphy =>
widget.message.attachments?.any((element) => element.type == 'giphy') ==
true;
bool get showBottomRow => bool get showBottomRow =>
showThreadReplyIndicator || showThreadReplyIndicator ||
showUsername || showUsername ||
@@ -272,13 +276,9 @@ class _MessageWidgetState extends State<MessageWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var leftPadding = widget.showUserAvatar != DisplayWidget.gone final avatarWidth = widget.messageTheme.avatarTheme.constraints.maxWidth;
? widget.messageTheme.avatarTheme.constraints.maxWidth + 14.5 var leftPadding =
: 6.0; widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 4.5;
final isGiphy =
widget.message.attachments?.any((element) => element.type == 'giphy') ==
true;
final isOnlyEmoji = final isOnlyEmoji =
widget.message.text.characters.every((c) => Emoji.byChar(c) != null); widget.message.text.characters.every((c) => Emoji.byChar(c) != null);
@@ -319,15 +319,13 @@ class _MessageWidgetState extends State<MessageWidget> {
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
if (widget.showUserAvatar == DisplayWidget.show) if (widget.showUserAvatar ==
DisplayWidget.show) ...[
_buildUserAvatar(), _buildUserAvatar(),
SizedBox(width: 6), SizedBox(width: 4),
],
if (widget.showUserAvatar == DisplayWidget.hide) if (widget.showUserAvatar == DisplayWidget.hide)
SizedBox( SizedBox(width: avatarWidth + 4),
width: widget.messageTheme.avatarTheme
.constraints.maxWidth +
8,
),
Flexible( Flexible(
child: PortalEntry( child: PortalEntry(
portal: Container( portal: Container(
@@ -380,22 +378,9 @@ class _MessageWidgetState extends State<MessageWidget> {
? BorderSide.none ? BorderSide.none
: widget.borderSide ?? : widget.borderSide ??
BorderSide( BorderSide(
color: Theme.of(context) color: widget
.brightness == .messageTheme
Brightness .messageBorderColor,
.dark
? StreamChatTheme.of(
context)
.colorTheme
.white
.withAlpha(
24)
: StreamChatTheme.of(
context)
.colorTheme
.black
.withAlpha(
24),
), ),
borderRadius: widget borderRadius: widget
.borderRadiusGeometry ?? .borderRadiusGeometry ??
@@ -412,7 +397,7 @@ class _MessageWidgetState extends State<MessageWidget> {
mainAxisSize: mainAxisSize:
MainAxisSize.min, MainAxisSize.min,
children: <Widget>[ children: <Widget>[
if (_hasQuotedMessage) if (hasQuotedMessage)
_buildQuotedMessage(), _buildQuotedMessage(),
..._parseAttachments( ..._parseAttachments(
context), context),
@@ -542,6 +527,8 @@ class _MessageWidgetState extends State<MessageWidget> {
} else { } else {
final showSendingIndicator = final showSendingIndicator =
widget.showSendingIndicator == DisplayWidget.show; widget.showSendingIndicator == DisplayWidget.show;
final threadParticipants = widget.message.threadParticipants;
final showThreadParticipants = threadParticipants?.isNotEmpty == true;
final replyCount = widget.message.replyCount; final replyCount = widget.message.replyCount;
final msg = replyCount != 0 final msg = replyCount != 0
? '$replyCount ${replyCount > 1 ? 'Thread Replies' : 'Thread Reply'}' ? '$replyCount ${replyCount > 1 ? 'Thread Replies' : 'Thread Reply'}'
@@ -554,19 +541,17 @@ class _MessageWidgetState extends State<MessageWidget> {
children.addAll([ children.addAll([
if (showSendingIndicator) _buildSendingIndicator(), if (showSendingIndicator) _buildSendingIndicator(),
// if (showReadList) if (showThreadReplyIndicator) ...[
// SizedBox.fromSize( if (showThreadParticipants)
// size: Size((widget.readList.length * 10.0) + 10, 17), SizedBox.fromSize(
// child: Padding( size: Size((threadParticipants.length * 8.0) + 10, 16),
// padding: const EdgeInsets.only(left: 4.0), child: _buildThreadParticipantsIndicator(),
// child: _buildReadIndicator(), ),
// ),
// ),
if (showThreadReplyIndicator)
InkWell( InkWell(
onTap: widget.onThreadTap != null ? onThreadTap : null, onTap: widget.onThreadTap != null ? onThreadTap : null,
child: Text(msg, style: widget.messageTheme?.replies), child: Text(msg, style: widget.messageTheme?.replies),
), ),
],
if (showUsername) if (showUsername)
Text( Text(
widget.message.user.name, widget.message.user.name,
@@ -596,7 +581,7 @@ class _MessageWidgetState extends State<MessageWidget> {
size: const Size(16, 32), size: const Size(16, 32),
painter: _ThreadReplyPainter( painter: _ThreadReplyPainter(
context: context, context: context,
color: widget.messageTheme.replyThreadColor, color: widget.messageTheme.messageBorderColor,
), ),
), ),
), ),
@@ -604,7 +589,7 @@ class _MessageWidgetState extends State<MessageWidget> {
(child) => Transform( (child) => Transform(
transform: Matrix4.rotationY(widget.reverse ? pi : 0), transform: Matrix4.rotationY(widget.reverse ? pi : 0),
alignment: Alignment.center, alignment: Alignment.center,
child: child, child: Container(height: 16, child: Center(child: child)),
), ),
), ),
].insertBetween(const SizedBox(width: 8.0)), ].insertBetween(const SizedBox(width: 8.0)),
@@ -630,9 +615,29 @@ class _MessageWidgetState extends State<MessageWidget> {
); );
} }
bool get isGiphy => Widget _buildThreadParticipantsIndicator() {
widget.message.attachments?.any((element) => element.type == 'giphy') == var padding = 0.0;
true; return Stack(
children: widget.message.threadParticipants.map((user) {
padding += 10.0;
return Positioned(
left: padding - 10,
bottom: 0,
top: 0,
child: Material(
color: Colors.white,
clipBehavior: Clip.antiAlias,
shape: CircleBorder(),
child: UserAvatar(
user: user,
constraints: BoxConstraints.loose(Size.fromRadius(8)),
showOnlineStatus: false,
),
),
);
}).toList(),
);
}
Widget _buildReactionIndicator( Widget _buildReactionIndicator(
BuildContext context, BuildContext context,
@@ -866,21 +871,18 @@ class _MessageWidgetState extends State<MessageWidget> {
Widget _buildUserAvatar() => Transform( Widget _buildUserAvatar() => Transform(
transform: Matrix4.rotationY(widget.reverse ? pi : 0), transform: Matrix4.rotationY(widget.reverse ? pi : 0),
alignment: Alignment.center, alignment: Alignment.center,
child: Padding( child: Transform.translate(
padding: const EdgeInsets.symmetric(horizontal: 4.0), offset: Offset(
child: Transform.translate( 0,
offset: Offset( widget.translateUserAvatar
0, ? widget.messageTheme.avatarTheme.constraints.maxHeight / 2
widget.translateUserAvatar : 0,
? widget.messageTheme.avatarTheme.constraints.maxHeight / 2 ),
: 0, child: UserAvatar(
), user: widget.message.user,
child: UserAvatar( onTap: widget.onUserAvatarTap,
user: widget.message.user, constraints: widget.messageTheme.avatarTheme.constraints,
onTap: widget.onUserAvatarTap, showOnlineStatus: false,
constraints: widget.messageTheme.avatarTheme.constraints,
showOnlineStatus: false,
),
), ),
), ),
); );
@@ -912,7 +914,7 @@ class _MessageWidgetState extends State<MessageWidget> {
if (widget.message.attachments if (widget.message.attachments
?.any((element) => element.ogScrapeUrl != null) == ?.any((element) => element.ogScrapeUrl != null) ==
true && true &&
!_hasQuotedMessage) !hasQuotedMessage)
_buildUrlAttachment(), _buildUrlAttachment(),
], ],
), ),
@@ -924,7 +926,7 @@ class _MessageWidgetState extends State<MessageWidget> {
widget.message.text.characters.every((c) => Emoji.byChar(c) != null); widget.message.text.characters.every((c) => Emoji.byChar(c) != null);
Color _getBackgroundColor() { Color _getBackgroundColor() {
if (_hasQuotedMessage) { if (hasQuotedMessage) {
return widget.messageTheme.messageBackgroundColor; return widget.messageTheme.messageBackgroundColor;
} }
+10 -10
View File
@@ -181,8 +181,8 @@ class StreamChatThemeData {
this.ownMessageTheme.messageBackgroundColor, this.ownMessageTheme.messageBackgroundColor,
avatarTheme: ownMessageTheme?.avatarTheme ?? avatarTheme: ownMessageTheme?.avatarTheme ??
this.ownMessageTheme.avatarTheme, this.ownMessageTheme.avatarTheme,
replyThreadColor: ownMessageTheme?.replyThreadColor ?? messageBorderColor: ownMessageTheme?.messageBorderColor ??
this.ownMessageTheme.replyThreadColor, this.ownMessageTheme.messageBorderColor,
) ?? ) ??
this.ownMessageTheme, this.ownMessageTheme,
otherMessageTheme: otherMessageTheme?.copyWith( otherMessageTheme: otherMessageTheme?.copyWith(
@@ -199,10 +199,10 @@ class StreamChatThemeData {
messageBackgroundColor: messageBackgroundColor:
otherMessageTheme?.messageBackgroundColor ?? otherMessageTheme?.messageBackgroundColor ??
this.otherMessageTheme.messageBackgroundColor, this.otherMessageTheme.messageBackgroundColor,
messageBorderColor: otherMessageTheme?.messageBorderColor ??
this.otherMessageTheme.messageBorderColor,
avatarTheme: otherMessageTheme?.avatarTheme ?? avatarTheme: otherMessageTheme?.avatarTheme ??
this.otherMessageTheme.avatarTheme, this.otherMessageTheme.avatarTheme,
replyThreadColor: ownMessageTheme?.replyThreadColor ??
this.ownMessageTheme.replyThreadColor,
) ?? ) ??
this.otherMessageTheme, this.otherMessageTheme,
reactionIcons: reactionIcons ?? this.reactionIcons, reactionIcons: reactionIcons ?? this.reactionIcons,
@@ -284,7 +284,7 @@ class StreamChatThemeData {
messageBackgroundColor: colorTheme.greyGainsboro, messageBackgroundColor: colorTheme.greyGainsboro,
reactionsBackgroundColor: colorTheme.white, reactionsBackgroundColor: colorTheme.white,
reactionsBorderColor: colorTheme.greyWhisper, reactionsBorderColor: colorTheme.greyWhisper,
replyThreadColor: colorTheme.greyWhisper, messageBorderColor: colorTheme.greyGainsboro,
avatarTheme: AvatarTheme( avatarTheme: AvatarTheme(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
constraints: BoxConstraints.tightFor( constraints: BoxConstraints.tightFor(
@@ -316,7 +316,7 @@ class StreamChatThemeData {
color: accentColor, color: accentColor,
), ),
messageBackgroundColor: colorTheme.white, messageBackgroundColor: colorTheme.white,
replyThreadColor: colorTheme.black.withAlpha(24), messageBorderColor: colorTheme.greyWhisper,
avatarTheme: AvatarTheme( avatarTheme: AvatarTheme(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
constraints: BoxConstraints.tightFor( constraints: BoxConstraints.tightFor(
@@ -646,9 +646,9 @@ class MessageTheme {
final TextStyle createdAt; final TextStyle createdAt;
final TextStyle replies; final TextStyle replies;
final Color messageBackgroundColor; final Color messageBackgroundColor;
final Color messageBorderColor;
final Color reactionsBackgroundColor; final Color reactionsBackgroundColor;
final Color reactionsBorderColor; final Color reactionsBorderColor;
final Color replyThreadColor;
final AvatarTheme avatarTheme; final AvatarTheme avatarTheme;
const MessageTheme({ const MessageTheme({
@@ -657,9 +657,9 @@ class MessageTheme {
this.messageAuthor, this.messageAuthor,
this.messageLinks, this.messageLinks,
this.messageBackgroundColor, this.messageBackgroundColor,
this.messageBorderColor,
this.reactionsBackgroundColor, this.reactionsBackgroundColor,
this.reactionsBorderColor, this.reactionsBorderColor,
this.replyThreadColor,
this.avatarTheme, this.avatarTheme,
this.createdAt, this.createdAt,
}); });
@@ -671,10 +671,10 @@ class MessageTheme {
TextStyle createdAt, TextStyle createdAt,
TextStyle replies, TextStyle replies,
Color messageBackgroundColor, Color messageBackgroundColor,
Color messageBorderColor,
AvatarTheme avatarTheme, AvatarTheme avatarTheme,
Color reactionsBackgroundColor, Color reactionsBackgroundColor,
Color reactionsBorderColor, Color reactionsBorderColor,
Color replyThreadColor,
}) => }) =>
MessageTheme( MessageTheme(
messageText: messageText ?? this.messageText, messageText: messageText ?? this.messageText,
@@ -683,12 +683,12 @@ class MessageTheme {
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
messageBackgroundColor: messageBackgroundColor:
messageBackgroundColor ?? this.messageBackgroundColor, messageBackgroundColor ?? this.messageBackgroundColor,
messageBorderColor: messageBorderColor ?? this.messageBorderColor,
avatarTheme: avatarTheme ?? this.avatarTheme, avatarTheme: avatarTheme ?? this.avatarTheme,
replies: replies ?? this.replies, replies: replies ?? this.replies,
reactionsBackgroundColor: reactionsBackgroundColor:
reactionsBackgroundColor ?? this.reactionsBackgroundColor, reactionsBackgroundColor ?? this.reactionsBackgroundColor,
reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor, reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor,
replyThreadColor: replyThreadColor ?? this.replyThreadColor,
); );
} }
+2 -1
View File
@@ -28,7 +28,8 @@ dependencies:
file_picker: ^2.0.12 file_picker: ^2.0.12
image_picker: ^0.6.7+2 image_picker: ^0.6.7+2
flutter_keyboard_visibility: ^3.3.0 flutter_keyboard_visibility: ^3.3.0
stream_chat: ^0.2.22 stream_chat:
path: ../stream-chat-dart
mime: ^0.9.6+3 mime: ^0.9.6+3
video_compress: ^2.1.1 video_compress: ^2.1.1
visibility_detector: ^0.1.5 visibility_detector: ^0.1.5