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