[MessageWidget] Show thread participants in case of thread.
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user