migrate ui
This commit is contained in:
@@ -26,7 +26,7 @@ typedef AttachmentBuilder = Widget Function(
|
||||
Message,
|
||||
List<Attachment>,
|
||||
);
|
||||
typedef OnQuotedMessageTap = void Function(String);
|
||||
typedef OnQuotedMessageTap = void Function(String?);
|
||||
|
||||
/// The display behaviour of a widget
|
||||
enum DisplayWidget {
|
||||
@@ -51,46 +51,46 @@ enum DisplayWidget {
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageWidget extends StatefulWidget {
|
||||
/// Function called on mention tap
|
||||
final void Function(User) onMentionTap;
|
||||
final void Function(User)? onMentionTap;
|
||||
|
||||
/// The function called when tapping on replies
|
||||
final void Function(Message) onThreadTap;
|
||||
final void Function(Message) onReplyTap;
|
||||
final Widget Function(BuildContext, Message) editMessageInputBuilder;
|
||||
final Widget Function(BuildContext, Message) textBuilder;
|
||||
final void Function(Message)? onThreadTap;
|
||||
final void Function(Message)? onReplyTap;
|
||||
final Widget Function(BuildContext, Message)? editMessageInputBuilder;
|
||||
final Widget Function(BuildContext, Message)? textBuilder;
|
||||
|
||||
/// Function called on long press
|
||||
final void Function(BuildContext, Message) onMessageActions;
|
||||
final void Function(BuildContext, Message)? onMessageActions;
|
||||
|
||||
/// The message
|
||||
final Message message;
|
||||
|
||||
/// The message theme
|
||||
final MessageTheme messageTheme;
|
||||
final MessageTheme? messageTheme;
|
||||
|
||||
/// If true the widget will be mirrored
|
||||
final bool reverse;
|
||||
|
||||
/// The shape of the message text
|
||||
final ShapeBorder shape;
|
||||
final ShapeBorder? shape;
|
||||
|
||||
/// The shape of an attachment
|
||||
final ShapeBorder attachmentShape;
|
||||
final ShapeBorder? attachmentShape;
|
||||
|
||||
/// The borderside of the message text
|
||||
final BorderSide borderSide;
|
||||
final BorderSide? borderSide;
|
||||
|
||||
/// The borderside of an attachment
|
||||
final BorderSide attachmentBorderSide;
|
||||
final BorderSide? attachmentBorderSide;
|
||||
|
||||
/// The border radius of the message text
|
||||
final BorderRadiusGeometry borderRadiusGeometry;
|
||||
final BorderRadiusGeometry? borderRadiusGeometry;
|
||||
|
||||
/// The border radius of an attachment
|
||||
final BorderRadiusGeometry attachmentBorderRadiusGeometry;
|
||||
final BorderRadiusGeometry? attachmentBorderRadiusGeometry;
|
||||
|
||||
/// The padding of the widget
|
||||
final EdgeInsetsGeometry padding;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
/// The internal padding of the message text
|
||||
final EdgeInsetsGeometry textPadding;
|
||||
@@ -116,18 +116,18 @@ class MessageWidget extends StatefulWidget {
|
||||
final bool showInChannelIndicator;
|
||||
|
||||
/// The function called when tapping on UserAvatar
|
||||
final void Function(User) onUserAvatarTap;
|
||||
final void Function(User)? onUserAvatarTap;
|
||||
|
||||
/// The function called when tapping on a link
|
||||
final void Function(String) onLinkTap;
|
||||
final void Function(String)? onLinkTap;
|
||||
|
||||
/// Used in [MessageReactionsModal] and [MessageActionsModal]
|
||||
final bool showReactionPickerIndicator;
|
||||
|
||||
final List<Read> readList;
|
||||
final List<Read>? readList;
|
||||
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
final ShowMessageCallback? onShowMessage;
|
||||
final ValueChanged<ReturnActionType>? onReturnAction;
|
||||
|
||||
/// If true show the users username next to the timestamp of the message
|
||||
final bool showUsername;
|
||||
@@ -147,22 +147,22 @@ class MessageWidget extends StatefulWidget {
|
||||
final bool translateUserAvatar;
|
||||
|
||||
/// Function called when quotedMessage is tapped
|
||||
final OnQuotedMessageTap onQuotedMessageTap;
|
||||
final OnQuotedMessageTap? onQuotedMessageTap;
|
||||
|
||||
/// Function called when message is tapped
|
||||
final void Function(Message) onMessageTap;
|
||||
final void Function(Message)? onMessageTap;
|
||||
|
||||
/// List of custom actions shown on message long tap
|
||||
final List<MessageAction> customActions;
|
||||
|
||||
// Customize onTap on attachment
|
||||
final void Function(Message message, Attachment attachment) onAttachmentTap;
|
||||
final void Function(Message message, Attachment attachment)? onAttachmentTap;
|
||||
|
||||
///
|
||||
MessageWidget({
|
||||
Key key,
|
||||
@required this.message,
|
||||
@required this.messageTheme,
|
||||
Key? key,
|
||||
required this.message,
|
||||
required this.messageTheme,
|
||||
this.reverse = false,
|
||||
this.translateUserAvatar = true,
|
||||
this.shape,
|
||||
@@ -197,7 +197,7 @@ class MessageWidget extends StatefulWidget {
|
||||
this.editMessageInputBuilder,
|
||||
this.textBuilder,
|
||||
this.onReturnAction,
|
||||
Map<String, AttachmentBuilder> customAttachmentBuilders,
|
||||
Map<String, AttachmentBuilder>? customAttachmentBuilders,
|
||||
this.readList,
|
||||
this.padding,
|
||||
this.textPadding = const EdgeInsets.symmetric(
|
||||
@@ -222,7 +222,7 @@ class MessageWidget extends StatefulWidget {
|
||||
child: wrapAttachmentWidget(
|
||||
context,
|
||||
Material(
|
||||
color: messageTheme.messageBackgroundColor,
|
||||
color: messageTheme?.messageBackgroundColor,
|
||||
child: ImageGroup(
|
||||
size: Size(
|
||||
MediaQuery.of(context).size.width * 0.8,
|
||||
@@ -236,7 +236,8 @@ class MessageWidget extends StatefulWidget {
|
||||
),
|
||||
border,
|
||||
reverse,
|
||||
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
attachmentBorderRadiusGeometry as BorderRadius? ??
|
||||
BorderRadius.zero,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -255,13 +256,14 @@ class MessageWidget extends StatefulWidget {
|
||||
onReturnAction: onReturnAction,
|
||||
onAttachmentTap: onAttachmentTap != null
|
||||
? () {
|
||||
onAttachmentTap?.call(message, attachments[0]);
|
||||
onAttachmentTap.call(message, attachments[0]);
|
||||
}
|
||||
: null,
|
||||
),
|
||||
border,
|
||||
reverse,
|
||||
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
attachmentBorderRadiusGeometry as BorderRadius? ??
|
||||
BorderRadius.zero,
|
||||
);
|
||||
},
|
||||
'video': (context, message, attachments) {
|
||||
@@ -286,7 +288,7 @@ class MessageWidget extends StatefulWidget {
|
||||
onReturnAction: onReturnAction,
|
||||
onAttachmentTap: onAttachmentTap != null
|
||||
? () {
|
||||
onAttachmentTap?.call(message, attachment);
|
||||
onAttachmentTap(message, attachment);
|
||||
}
|
||||
: null,
|
||||
);
|
||||
@@ -294,11 +296,12 @@ class MessageWidget extends StatefulWidget {
|
||||
),
|
||||
border,
|
||||
reverse,
|
||||
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
attachmentBorderRadiusGeometry as BorderRadius? ??
|
||||
BorderRadius.zero,
|
||||
);
|
||||
},
|
||||
'giphy': (context, message, attachments) {
|
||||
var border = RoundedRectangleBorder(
|
||||
final border = RoundedRectangleBorder(
|
||||
side: BorderSide.none,
|
||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
);
|
||||
@@ -309,7 +312,6 @@ class MessageWidget extends StatefulWidget {
|
||||
children: attachments.map((attachment) {
|
||||
return GiphyAttachment(
|
||||
attachment: attachment,
|
||||
messageTheme: messageTheme,
|
||||
message: message,
|
||||
size: Size(
|
||||
MediaQuery.of(context).size.width * 0.8,
|
||||
@@ -322,7 +324,8 @@ class MessageWidget extends StatefulWidget {
|
||||
),
|
||||
border,
|
||||
reverse,
|
||||
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
attachmentBorderRadiusGeometry as BorderRadius? ??
|
||||
BorderRadius.zero,
|
||||
);
|
||||
},
|
||||
'file': (context, message, attachments) {
|
||||
@@ -349,7 +352,8 @@ class MessageWidget extends StatefulWidget {
|
||||
),
|
||||
border,
|
||||
reverse,
|
||||
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
attachmentBorderRadiusGeometry as BorderRadius? ??
|
||||
BorderRadius.zero,
|
||||
);
|
||||
})
|
||||
.insertBetween(SizedBox(
|
||||
@@ -381,7 +385,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
|
||||
bool get showInChannel => widget.showInChannelIndicator;
|
||||
|
||||
bool get hasQuotedMessage => widget.message?.quotedMessage != null;
|
||||
bool get hasQuotedMessage => widget.message.quotedMessage != null;
|
||||
|
||||
bool get isSendFailed => widget.message.status == MessageSendingStatus.failed;
|
||||
|
||||
@@ -394,17 +398,17 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
bool get isFailedState => isSendFailed || isUpdateFailed || isDeleteFailed;
|
||||
|
||||
bool get isGiphy =>
|
||||
widget.message.attachments?.any((element) => element.type == 'giphy') ==
|
||||
widget.message.attachments.any((element) => element.type == 'giphy') ==
|
||||
true;
|
||||
|
||||
bool get hasNonUrlAttachments =>
|
||||
widget.message.attachments
|
||||
?.where((it) => it.ogScrapeUrl == null)
|
||||
?.isNotEmpty ==
|
||||
.where((it) => it.ogScrapeUrl == null)
|
||||
.isNotEmpty ==
|
||||
true;
|
||||
|
||||
bool get hasUrlAttachments =>
|
||||
widget.message.attachments?.any((it) => it.ogScrapeUrl != null) == true;
|
||||
widget.message.attachments.any((it) => it.ogScrapeUrl != null) == true;
|
||||
|
||||
bool get showBottomRow =>
|
||||
showThreadReplyIndicator ||
|
||||
@@ -415,12 +419,13 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
isDeleted;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => widget.message.attachments?.isNotEmpty == true;
|
||||
bool get wantKeepAlive => widget.message.attachments.isNotEmpty == true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final avatarWidth = widget.messageTheme.avatarTheme.constraints.maxWidth;
|
||||
final avatarWidth =
|
||||
widget.messageTheme?.avatarTheme?.constraints.maxWidth ?? 40;
|
||||
var leftPadding =
|
||||
widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 0.5;
|
||||
|
||||
@@ -429,7 +434,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
child: Portal(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
widget.onMessageTap(widget.message);
|
||||
widget.onMessageTap!(widget.message);
|
||||
},
|
||||
onLongPress: widget.message.isDeleted && !isFailedState
|
||||
? null
|
||||
@@ -460,7 +465,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
if (widget.showUserAvatar ==
|
||||
DisplayWidget.show) ...[
|
||||
DisplayWidget.show &&
|
||||
widget.message.user != null) ...[
|
||||
_buildUserAvatar(),
|
||||
SizedBox(width: 4),
|
||||
],
|
||||
@@ -533,13 +539,14 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
),
|
||||
shape: widget.shape ??
|
||||
RoundedRectangleBorder(
|
||||
side:
|
||||
widget.borderSide ??
|
||||
BorderSide(
|
||||
color: widget
|
||||
side: widget
|
||||
.borderSide ??
|
||||
BorderSide(
|
||||
color: widget
|
||||
.messageTheme
|
||||
.messageBorderColor,
|
||||
),
|
||||
?.messageBorderColor ??
|
||||
Colors.grey,
|
||||
),
|
||||
borderRadius: widget
|
||||
.borderRadiusGeometry ??
|
||||
BorderRadius.zero,
|
||||
@@ -616,14 +623,14 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
|
||||
Widget _buildQuotedMessage() {
|
||||
final isMyMessage =
|
||||
widget.message.user.id == StreamChat.of(context).user.id;
|
||||
final onTap = widget.message?.quotedMessage?.isDeleted != true &&
|
||||
widget.message.user?.id == StreamChat.of(context).user?.id;
|
||||
final onTap = widget.message.quotedMessage?.isDeleted != true &&
|
||||
widget.onQuotedMessageTap != null
|
||||
? () => widget.onQuotedMessageTap(widget.message.quotedMessageId)
|
||||
? () => widget.onQuotedMessageTap!(widget.message.quotedMessageId)
|
||||
: null;
|
||||
return QuotedMessageWidget(
|
||||
onTap: onTap,
|
||||
message: widget.message.quotedMessage,
|
||||
message: widget.message.quotedMessage!,
|
||||
messageTheme: isMyMessage
|
||||
? StreamChatTheme.of(context).otherMessageTheme
|
||||
: StreamChatTheme.of(context).ownMessageTheme,
|
||||
@@ -660,12 +667,12 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
|
||||
var children = <Widget>[];
|
||||
|
||||
final threadParticipants = widget.message?.threadParticipants?.take(2);
|
||||
final threadParticipants = widget.message.threadParticipants?.take(2);
|
||||
final showThreadParticipants = threadParticipants?.isNotEmpty == true;
|
||||
final replyCount = widget.message.replyCount;
|
||||
|
||||
var msg = 'Thread Reply';
|
||||
if (showThreadReplyIndicator && replyCount > 1) {
|
||||
if (showThreadReplyIndicator && replyCount! > 1) {
|
||||
msg = '$replyCount Thread Replies';
|
||||
}
|
||||
|
||||
@@ -674,9 +681,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
var message = widget.message;
|
||||
if (showInChannel) {
|
||||
final channel = StreamChannel.of(context);
|
||||
message = await channel.getMessage(widget.message.parentId);
|
||||
message = await channel.getMessage(widget.message.parentId!);
|
||||
}
|
||||
return widget.onThreadTap(message);
|
||||
return widget.onThreadTap!(message);
|
||||
} catch (e, stk) {
|
||||
print(e);
|
||||
print(stk);
|
||||
@@ -690,7 +697,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
if (showInChannel || showThreadReplyIndicator) ...[
|
||||
if (showThreadParticipants)
|
||||
SizedBox.fromSize(
|
||||
size: Size((threadParticipants.length * 8.0) + 8, 16),
|
||||
size: Size((threadParticipants!.length * 8.0) + 8, 16),
|
||||
child: _buildThreadParticipantsIndicator(threadParticipants),
|
||||
),
|
||||
InkWell(
|
||||
@@ -700,16 +707,16 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
],
|
||||
if (showUsername)
|
||||
Text(
|
||||
widget.message.user.name,
|
||||
widget.message.user!.name,
|
||||
maxLines: 1,
|
||||
key: usernameKey,
|
||||
style: widget.messageTheme.messageAuthor,
|
||||
style: widget.messageTheme?.messageAuthor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (showTimeStamp)
|
||||
Text(
|
||||
Jiffy(widget.message.createdAt.toLocal()).jm,
|
||||
style: widget.messageTheme.createdAt,
|
||||
style: widget.messageTheme?.createdAt,
|
||||
),
|
||||
if (showSendingIndicator) _buildSendingIndicator(),
|
||||
]);
|
||||
@@ -724,13 +731,13 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: context.textScaleFactor *
|
||||
(widget.messageTheme.replies.fontSize / 2),
|
||||
((widget.messageTheme?.replies?.fontSize ?? 1) / 2),
|
||||
),
|
||||
child: CustomPaint(
|
||||
size: Size(16, 32) * context.textScaleFactor,
|
||||
painter: _ThreadReplyPainter(
|
||||
context: context,
|
||||
color: widget.messageTheme.messageBorderColor,
|
||||
color: widget.messageTheme?.messageBorderColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -758,7 +765,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
var urlAttachment = widget.message.attachments
|
||||
.firstWhere((element) => element.ogScrapeUrl != null);
|
||||
|
||||
var host = Uri.parse(urlAttachment.ogScrapeUrl).host;
|
||||
var host = Uri.parse(urlAttachment.ogScrapeUrl!).host;
|
||||
var splitList = host.split('.');
|
||||
var hostName = splitList.length == 3 ? splitList[1] : splitList[0];
|
||||
var hostDisplayName = urlAttachment.authorName?.capitalize() ??
|
||||
@@ -768,7 +775,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
return UrlAttachment(
|
||||
urlAttachment: urlAttachment,
|
||||
hostDisplayName: hostDisplayName,
|
||||
textPadding: widget.textPadding,
|
||||
textPadding: widget.textPadding as EdgeInsets,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -801,15 +808,16 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Widget _buildReactionIndicator(
|
||||
BuildContext context,
|
||||
) {
|
||||
final ownId = StreamChat.of(context).user.id;
|
||||
final ownId = StreamChat.of(context).user!.id;
|
||||
final reactionsMap = <String, Reaction>{};
|
||||
widget.message.latestReactions?.forEach((element) {
|
||||
if (!reactionsMap.containsKey(element.type) || element.user.id == ownId) {
|
||||
if (!reactionsMap.containsKey(element.type) ||
|
||||
element.user!.id == ownId) {
|
||||
reactionsMap[element.type] = element;
|
||||
}
|
||||
});
|
||||
final reactionsList = reactionsMap.values.toList()
|
||||
..sort((a, b) => a.user.id == ownId ? 1 : -1);
|
||||
..sort((a, b) => a.user!.id == ownId ? 1 : -1);
|
||||
|
||||
return AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 300),
|
||||
@@ -822,9 +830,13 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
key: ValueKey('${widget.message.id}.reactions'),
|
||||
reverse: widget.reverse,
|
||||
flipTail: widget.reverse,
|
||||
backgroundColor: widget.messageTheme.reactionsBackgroundColor,
|
||||
borderColor: widget.messageTheme.reactionsBorderColor,
|
||||
maskColor: widget.messageTheme.reactionsMaskColor,
|
||||
backgroundColor:
|
||||
widget.messageTheme?.reactionsBackgroundColor ??
|
||||
Colors.transparent,
|
||||
borderColor: widget.messageTheme?.reactionsBorderColor ??
|
||||
Colors.transparent,
|
||||
maskColor: widget.messageTheme?.reactionsMaskColor ??
|
||||
Colors.transparent,
|
||||
reactions: reactionsList,
|
||||
),
|
||||
)
|
||||
@@ -845,9 +857,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
onCopyTap: (message) =>
|
||||
Clipboard.setData(ClipboardData(text: message.text)),
|
||||
attachmentBorderRadiusGeometry:
|
||||
widget.attachmentBorderRadiusGeometry,
|
||||
widget.attachmentBorderRadiusGeometry as BorderRadius?,
|
||||
showUserAvatar:
|
||||
widget.message.user.id == channel.client.state.user.id
|
||||
widget.message.user!.id == channel.client.state.user!.id
|
||||
? DisplayWidget.gone
|
||||
: DisplayWidget.show,
|
||||
messageTheme: widget.messageTheme,
|
||||
@@ -864,11 +876,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
widget.showResendMessage && (isSendFailed || isUpdateFailed),
|
||||
showCopyMessage: widget.showCopyMessage &&
|
||||
!isFailedState &&
|
||||
widget.message.text?.trim()?.isNotEmpty == true,
|
||||
widget.message.text?.trim().isNotEmpty == true,
|
||||
showEditMessage: widget.showEditMessage &&
|
||||
!isDeleteFailed &&
|
||||
widget.message.attachments
|
||||
?.any((element) => element.type == 'giphy') !=
|
||||
.any((element) => element.type == 'giphy') !=
|
||||
true,
|
||||
showReactions: widget.showReactions,
|
||||
showReplyMessage: widget.showReplyMessage &&
|
||||
@@ -894,9 +906,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
channel: channel,
|
||||
child: MessageReactionsModal(
|
||||
attachmentBorderRadiusGeometry:
|
||||
widget.attachmentBorderRadiusGeometry,
|
||||
widget.attachmentBorderRadiusGeometry as BorderRadius?,
|
||||
showUserAvatar:
|
||||
widget.message.user.id == channel.client.state.user.id
|
||||
widget.message.user!.id == channel.client.state.user!.id
|
||||
? DisplayWidget.gone
|
||||
: DisplayWidget.show,
|
||||
onUserAvatarTap: widget.onUserAvatarTap,
|
||||
@@ -914,7 +926,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
|
||||
ShapeBorder _getDefaultAttachmentShape(BuildContext context) {
|
||||
final hasFiles =
|
||||
widget.message.attachments?.any((it) => it.type == 'file') == true;
|
||||
widget.message.attachments.any((it) => it.type == 'file') == true;
|
||||
return RoundedRectangleBorder(
|
||||
side: hasFiles
|
||||
? widget.attachmentBorderSide ??
|
||||
@@ -940,13 +952,13 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
final attachmentGroups = <String, List<Attachment>>{};
|
||||
|
||||
widget.message.attachments
|
||||
.where((element) => element.ogScrapeUrl == null)
|
||||
.where((element) => element.ogScrapeUrl == null && element.type != null)
|
||||
.forEach((e) {
|
||||
if (attachmentGroups[e.type] == null) {
|
||||
attachmentGroups[e.type] = [];
|
||||
attachmentGroups[e.type!] = [];
|
||||
}
|
||||
|
||||
attachmentGroups[e.type].add(e);
|
||||
attachmentGroups[e.type]?.add(e);
|
||||
});
|
||||
|
||||
final attachmentList = <Widget>[];
|
||||
@@ -954,7 +966,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
attachmentGroups.forEach((type, attachments) {
|
||||
final attachmentBuilder = widget.attachmentBuilders[type];
|
||||
|
||||
if (attachmentBuilder == null) return SizedBox();
|
||||
if (attachmentBuilder == null) return;
|
||||
final attachmentWidget = attachmentBuilder(
|
||||
context,
|
||||
widget.message,
|
||||
@@ -967,10 +979,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
padding: widget.attachmentPadding,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: attachmentList?.insertBetween(SizedBox(
|
||||
height: widget.attachmentPadding.vertical / 2,
|
||||
)) ??
|
||||
[],
|
||||
children: attachmentList.insertBetween(SizedBox(
|
||||
height: widget.attachmentPadding.vertical / 2,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -982,7 +993,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}
|
||||
|
||||
if (widget.onMessageActions != null) {
|
||||
widget.onMessageActions(context, widget.message);
|
||||
widget.onMessageActions!(context, widget.message);
|
||||
} else {
|
||||
_showMessageActionModalBottomSheet(context);
|
||||
}
|
||||
@@ -990,7 +1001,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}
|
||||
|
||||
Widget _buildSendingIndicator() {
|
||||
final style = widget.messageTheme.createdAt;
|
||||
final style = widget.messageTheme?.createdAt;
|
||||
final message = widget.message;
|
||||
|
||||
if (hasNonUrlAttachments &&
|
||||
@@ -1002,8 +1013,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}).length;
|
||||
if (uploadRemaining == 0) {
|
||||
return StreamSvgIcon.check(
|
||||
size: style.fontSize,
|
||||
color: IconTheme.of(context).color.withOpacity(0.5),
|
||||
size: style!.fontSize,
|
||||
color: IconTheme.of(context).color!.withOpacity(0.5),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
@@ -1015,14 +1026,14 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Widget child = SendingIndicator(
|
||||
message: message,
|
||||
isMessageRead: isMessageRead,
|
||||
size: style.fontSize,
|
||||
size: style!.fontSize,
|
||||
);
|
||||
if (isMessageRead) {
|
||||
child = Row(
|
||||
children: [
|
||||
if (StreamChannel.of(context).channel.memberCount > 2)
|
||||
if (StreamChannel.of(context).channel.memberCount! > 2)
|
||||
Text(
|
||||
widget.readList.length.toString(),
|
||||
widget.readList!.length.toString(),
|
||||
style: style.copyWith(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
),
|
||||
@@ -1042,21 +1053,23 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
offset: Offset(
|
||||
0,
|
||||
widget.translateUserAvatar
|
||||
? widget.messageTheme.avatarTheme.constraints.maxHeight / 2
|
||||
? (widget.messageTheme?.avatarTheme?.constraints.maxHeight ??
|
||||
40) /
|
||||
2
|
||||
: 0,
|
||||
),
|
||||
child: UserAvatar(
|
||||
user: widget.message.user,
|
||||
user: widget.message.user!,
|
||||
onTap: widget.onUserAvatarTap,
|
||||
constraints: widget.messageTheme.avatarTheme.constraints,
|
||||
borderRadius: widget.messageTheme.avatarTheme.borderRadius,
|
||||
constraints: widget.messageTheme?.avatarTheme!.constraints,
|
||||
borderRadius: widget.messageTheme?.avatarTheme!.borderRadius,
|
||||
showOnlineStatus: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _buildTextBubble() {
|
||||
if (widget.message.text.trim().isEmpty) return Offstage();
|
||||
if (widget.message.text!.trim().isEmpty) return Offstage();
|
||||
return Transform(
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
alignment: Alignment.center,
|
||||
@@ -1066,15 +1079,15 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Padding(
|
||||
padding: isOnlyEmoji ? EdgeInsets.zero : widget.textPadding,
|
||||
child: widget.textBuilder != null
|
||||
? widget.textBuilder(context, widget.message)
|
||||
? widget.textBuilder!(context, widget.message)
|
||||
: MessageText(
|
||||
onLinkTap: widget.onLinkTap,
|
||||
message: widget.message,
|
||||
onMentionTap: widget.onMentionTap,
|
||||
messageTheme: isOnlyEmoji
|
||||
? widget.messageTheme.copyWith(
|
||||
? widget.messageTheme?.copyWith(
|
||||
messageText:
|
||||
widget.messageTheme.messageText.copyWith(
|
||||
widget.messageTheme?.messageText!.copyWith(
|
||||
fontSize: 42,
|
||||
))
|
||||
: widget.messageTheme,
|
||||
@@ -1086,11 +1099,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
);
|
||||
}
|
||||
|
||||
bool get isOnlyEmoji => widget.message.text.isOnlyEmoji;
|
||||
bool get isOnlyEmoji => widget.message.text!.isOnlyEmoji;
|
||||
|
||||
Color _getBackgroundColor() {
|
||||
Color? _getBackgroundColor() {
|
||||
if (hasQuotedMessage) {
|
||||
return widget.messageTheme.messageBackgroundColor;
|
||||
return widget.messageTheme?.messageBackgroundColor;
|
||||
}
|
||||
|
||||
if (hasUrlAttachments) {
|
||||
@@ -1105,7 +1118,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
return Colors.transparent;
|
||||
}
|
||||
|
||||
return widget.messageTheme.messageBackgroundColor;
|
||||
return widget.messageTheme?.messageBackgroundColor;
|
||||
}
|
||||
|
||||
void retryMessage(BuildContext context) {
|
||||
@@ -1127,15 +1140,15 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}
|
||||
|
||||
class _ThreadReplyPainter extends CustomPainter {
|
||||
final Color color;
|
||||
final BuildContext context;
|
||||
final Color? color;
|
||||
final BuildContext? context;
|
||||
|
||||
const _ThreadReplyPainter({this.context, @required this.color});
|
||||
const _ThreadReplyPainter({this.context, required this.color});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = color ?? StreamChatTheme.of(context).colorTheme.greyGainsboro
|
||||
..color = color ?? StreamChatTheme.of(context!).colorTheme.greyGainsboro
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
Reference in New Issue
Block a user