lint changes message

This commit is contained in:
Deven Joshi
2021-05-05 15:33:42 +05:30
parent 5ad74b8f2b
commit bda64e8764
2 changed files with 899 additions and 878 deletions
@@ -8,37 +8,11 @@ import 'package:stream_chat_flutter/src/reaction_picker.dart';
import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
import 'package:stream_chat_flutter/src/utils.dart'; import 'package:stream_chat_flutter/src/utils.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_flutter/src/extension.dart';
import 'extension.dart'; /// Constructs a modal with actions for a message
import 'message_input.dart';
import 'message_widget.dart';
import 'stream_chat.dart';
import 'stream_chat_theme.dart';
class MessageActionsModal extends StatefulWidget { class MessageActionsModal extends StatefulWidget {
final Widget Function(BuildContext, Message)? editMessageInputBuilder; /// Constructor for creating a [MessageActionsModal] widget
final OnMessageTap? onThreadReplyTap;
final OnMessageTap? onReplyTap;
final Message message;
final MessageTheme messageTheme;
final bool showReactions;
final OnMessageTap? onCopyTap;
final bool showDeleteMessage;
final bool showCopyMessage;
final bool showEditMessage;
final bool showResendMessage;
final bool showReplyMessage;
final bool showThreadReplyMessage;
final bool showFlagButton;
final bool reverse;
final ShapeBorder? messageShape;
final ShapeBorder? attachmentShape;
final DisplayWidget showUserAvatar;
final BorderRadius? attachmentBorderRadiusGeometry;
/// List of custom actions
final List<MessageAction> customActions;
const MessageActionsModal({ const MessageActionsModal({
Key? key, Key? key,
required this.message, required this.message,
@@ -63,6 +37,66 @@ class MessageActionsModal extends StatefulWidget {
this.onCopyTap, this.onCopyTap,
}) : super(key: key); }) : super(key: key);
/// Builder for edit message
final Widget Function(BuildContext, Message)? editMessageInputBuilder;
/// Callback for when thread reply is tapped
final OnMessageTap? onThreadReplyTap;
/// Callback for when reply is tapped
final OnMessageTap? onReplyTap;
/// Message in focus for actions
final Message message;
/// [MessageTheme] for message
final MessageTheme messageTheme;
/// Flag for showing reactions
final bool showReactions;
/// Callback when copy is tapped
final OnMessageTap? onCopyTap;
/// Callback when delete is tapped
final bool showDeleteMessage;
/// Flag for showing copy action
final bool showCopyMessage;
/// Flag for showing edit action
final bool showEditMessage;
/// Flag for showing resend action
final bool showResendMessage;
/// Flag for showing reply action
final bool showReplyMessage;
/// Flag for showing thread reply action
final bool showThreadReplyMessage;
/// Flag for showing flag action
final bool showFlagButton;
/// Flag for reversing message
final bool reverse;
/// [ShapeBorder] to apply to the widget
final ShapeBorder? messageShape;
/// [ShapeBorder] to apply to attachment
final ShapeBorder? attachmentShape;
/// Enum for displaying user avatar
final DisplayWidget showUserAvatar;
/// [BorderRadius] for attachment border
final BorderRadius? attachmentBorderRadiusGeometry;
/// List of custom actions
final List<MessageAction> customActions;
@override @override
_MessageActionsModalState createState() => _MessageActionsModalState(); _MessageActionsModalState createState() => _MessageActionsModalState();
} }
@@ -71,9 +105,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
bool _showActions = true; bool _showActions = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => _showMessageOptionsModal();
return _showMessageOptionsModal();
}
Widget _showMessageOptionsModal() { Widget _showMessageOptionsModal() {
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
@@ -120,138 +152,135 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
if (_showActions) if (_showActions)
TweenAnimationBuilder<double>( TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1), tween: Tween(begin: 0, end: 1),
duration: Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutBack, curve: Curves.easeInOutBack,
builder: (context, val, snapshot) { builder: (context, val, snapshot) => Transform.scale(
return Transform.scale( scale: val,
scale: val, child: Center(
child: Center( child: SingleChildScrollView(
child: SingleChildScrollView( child: Padding(
child: Padding( padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8), child: Column(
child: Column( crossAxisAlignment: widget.reverse
crossAxisAlignment: widget.reverse ? CrossAxisAlignment.end
? CrossAxisAlignment.end : CrossAxisAlignment.start,
: CrossAxisAlignment.start, children: <Widget>[
children: <Widget>[ if (widget.showReactions &&
if (widget.showReactions && (widget.message.status ==
(widget.message.status == MessageSendingStatus.sent))
MessageSendingStatus.sent)) Align(
Align( alignment: Alignment(
alignment: Alignment( user?.id == widget.message.user?.id
user?.id == widget.message.user?.id ? (divFactor > 1.0
? (divFactor > 1.0 ? 0.0
? 0.0 : (1.0 - divFactor))
: (1.0 - divFactor)) : (divFactor > 1.0
: (divFactor > 1.0 ? 0.0
? 0.0 : -(1.0 - divFactor)),
: -(1.0 - divFactor)), 0),
0), child: ReactionPicker(
child: ReactionPicker( message: widget.message,
message: widget.message,
),
),
SizedBox(height: 8),
IgnorePointer(
child: MessageWidget(
key: Key('MessageWidget'),
reverse: widget.reverse,
attachmentBorderRadiusGeometry:
widget.attachmentBorderRadiusGeometry,
message: widget.message.copyWith(
text: widget.message.text!.length > 200
? '${widget.message.text!.substring(0, 200)}...'
: widget.message.text,
),
messageTheme: widget.messageTheme,
showReactions: false,
showUsername: false,
showReplyMessage: false,
showUserAvatar: widget.showUserAvatar,
attachmentPadding: EdgeInsets.all(
hasFileAttachment ? 4 : 2,
),
showTimestamp: false,
translateUserAvatar: false,
padding: const EdgeInsets.all(0),
textPadding: EdgeInsets.symmetric(
vertical: 8,
horizontal: widget.message.text!.isOnlyEmoji
? 0
: 16.0,
),
showReactionPickerIndicator:
widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.sent),
showSendingIndicator: false,
shape: widget.messageShape,
attachmentShape: widget.attachmentShape,
), ),
), ),
SizedBox(height: 8), const SizedBox(height: 8),
Padding( IgnorePointer(
padding: EdgeInsets.only( child: MessageWidget(
left: widget.reverse ? 0 : 40, key: const Key('MessageWidget'),
reverse: widget.reverse,
attachmentBorderRadiusGeometry:
widget.attachmentBorderRadiusGeometry,
message: widget.message.copyWith(
text: widget.message.text!.length > 200
// ignore: lines_longer_than_80_chars
? '${widget.message.text!.substring(0, 200)}...'
: widget.message.text,
), ),
child: SizedBox( messageTheme: widget.messageTheme,
width: MediaQuery.of(context).size.width * 0.75, showReactions: false,
child: Material( showUsername: false,
color: StreamChatTheme.of(context) showReplyMessage: false,
.colorTheme showUserAvatar: widget.showUserAvatar,
.whiteSnow, attachmentPadding: EdgeInsets.all(
clipBehavior: Clip.hardEdge, hasFileAttachment ? 4 : 2,
shape: RoundedRectangleBorder( ),
borderRadius: BorderRadius.circular(16), showTimestamp: false,
), translateUserAvatar: false,
child: Column( padding: const EdgeInsets.all(0),
crossAxisAlignment: textPadding: EdgeInsets.symmetric(
CrossAxisAlignment.stretch, vertical: 8,
children: [ horizontal:
if (widget.showReplyMessage && widget.message.text!.isOnlyEmoji ? 0 : 16.0,
widget.message.status == ),
MessageSendingStatus.sent) showReactionPickerIndicator:
_buildReplyButton(context), widget.showReactions &&
if (widget.showThreadReplyMessage && (widget.message.status ==
(widget.message.status == MessageSendingStatus.sent),
MessageSendingStatus.sent) && showSendingIndicator: false,
widget.message.parentId == null) shape: widget.messageShape,
_buildThreadReplyButton(context), attachmentShape: widget.attachmentShape,
if (widget.showResendMessage) ),
_buildResendMessage(context), ),
if (widget.showEditMessage) const SizedBox(height: 8),
_buildEditMessage(context), Padding(
if (widget.showCopyMessage) padding: EdgeInsets.only(
_buildCopyButton(context), left: widget.reverse ? 0 : 40,
if (widget.showFlagButton) ),
_buildFlagButton(context), child: SizedBox(
if (widget.showDeleteMessage) width: MediaQuery.of(context).size.width * 0.75,
_buildDeleteButton(context), child: Material(
...widget.customActions.map((action) { color: StreamChatTheme.of(context)
return _buildCustomAction( .colorTheme
context, .whiteSnow,
action, clipBehavior: Clip.hardEdge,
); shape: RoundedRectangleBorder(
}) borderRadius: BorderRadius.circular(16),
].insertBetween( ),
Container( child: Column(
height: 1, crossAxisAlignment:
color: StreamChatTheme.of(context) CrossAxisAlignment.stretch,
.colorTheme children: [
.greyWhisper, if (widget.showReplyMessage &&
), widget.message.status ==
MessageSendingStatus.sent)
_buildReplyButton(context),
if (widget.showThreadReplyMessage &&
(widget.message.status ==
MessageSendingStatus.sent) &&
widget.message.parentId == null)
_buildThreadReplyButton(context),
if (widget.showResendMessage)
_buildResendMessage(context),
if (widget.showEditMessage)
_buildEditMessage(context),
if (widget.showCopyMessage)
_buildCopyButton(context),
if (widget.showFlagButton)
_buildFlagButton(context),
if (widget.showDeleteMessage)
_buildDeleteButton(context),
...widget.customActions
.map((action) => _buildCustomAction(
context,
action,
))
].insertBetween(
Container(
height: 1,
color: StreamChatTheme.of(context)
.colorTheme
.greyWhisper,
), ),
), ),
), ),
), ),
), ),
], ),
), ],
), ),
), ),
), ),
); ),
}, ),
), ),
], ],
), ),
@@ -261,23 +290,22 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
InkWell _buildCustomAction( InkWell _buildCustomAction(
BuildContext context, BuildContext context,
MessageAction messageAction, MessageAction messageAction,
) { ) =>
return InkWell( InkWell(
onTap: () { onTap: () {
messageAction.onTap?.call(widget.message); messageAction.onTap?.call(widget.message);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
child: Row( child: Row(
children: [ children: [
messageAction.leading ?? Offstage(), messageAction.leading ?? const Offstage(),
const SizedBox(width: 16), const SizedBox(width: 16),
messageAction.title ?? Offstage(), messageAction.title ?? const Offstage(),
], ],
),
), ),
), );
);
}
void _showFlagDialog() async { void _showFlagDialog() async {
final client = StreamChat.of(context).client; final client = StreamChat.of(context).client;
@@ -290,6 +318,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
size: 24, size: 24,
), ),
question: question:
// ignore: lines_longer_than_80_chars
'Do you want to send a copy of this message to a\nmoderator for further investigation?', 'Do you want to send a copy of this message to a\nmoderator for further investigation?',
okText: 'FLAG', okText: 'FLAG',
cancelText: 'CANCEL', cancelText: 'CANCEL',
@@ -371,52 +400,48 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
); );
} }
Widget _buildReplyButton(BuildContext context) { Widget _buildReplyButton(BuildContext context) => InkWell(
return InkWell( onTap: () {
onTap: () { Navigator.pop(context);
Navigator.pop(context); if (widget.onReplyTap != null) {
if (widget.onReplyTap != null) { widget.onReplyTap!(widget.message);
widget.onReplyTap!(widget.message); }
} },
}, child: Padding(
child: Padding( padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), child: Row(
child: Row( children: [
children: [ StreamSvgIcon.reply(
StreamSvgIcon.reply( color: StreamChatTheme.of(context).primaryIconTheme.color,
color: StreamChatTheme.of(context).primaryIconTheme.color, ),
), const SizedBox(width: 16),
const SizedBox(width: 16), Text(
Text( 'Reply',
'Reply', style: StreamChatTheme.of(context).textTheme.body,
style: StreamChatTheme.of(context).textTheme.body, ),
), ],
], ),
), ),
), );
);
}
Widget _buildFlagButton(BuildContext context) { Widget _buildFlagButton(BuildContext context) => InkWell(
return InkWell( onTap: _showFlagDialog,
onTap: _showFlagDialog, child: Padding(
child: Padding( padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), child: Row(
child: Row( children: [
children: [ StreamSvgIcon.iconFlag(
StreamSvgIcon.iconFlag( color: StreamChatTheme.of(context).primaryIconTheme.color,
color: StreamChatTheme.of(context).primaryIconTheme.color, ),
), const SizedBox(width: 16),
const SizedBox(width: 16), Text(
Text( 'Flag Message',
'Flag Message', style: StreamChatTheme.of(context).textTheme.body,
style: StreamChatTheme.of(context).textTheme.body, ),
), ],
], ),
), ),
), );
);
}
Widget _buildDeleteButton(BuildContext context) { Widget _buildDeleteButton(BuildContext context) {
final isDeleteFailed = final isDeleteFailed =
@@ -444,54 +469,50 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
); );
} }
Widget _buildCopyButton(BuildContext context) { Widget _buildCopyButton(BuildContext context) => InkWell(
return InkWell( onTap: () async {
onTap: () async { widget.onCopyTap?.call(widget.message);
widget.onCopyTap?.call(widget.message); Navigator.pop(context);
Navigator.pop(context); },
}, child: Padding(
child: Padding( padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), child: Row(
child: Row( children: [
children: [ StreamSvgIcon.copy(
StreamSvgIcon.copy( size: 24,
size: 24, color: StreamChatTheme.of(context).primaryIconTheme.color,
color: StreamChatTheme.of(context).primaryIconTheme.color, ),
), const SizedBox(width: 16),
const SizedBox(width: 16), Text(
Text( 'Copy Message',
'Copy Message', style: StreamChatTheme.of(context).textTheme.body,
style: StreamChatTheme.of(context).textTheme.body, ),
), ],
], ),
), ),
), );
);
}
Widget _buildEditMessage(BuildContext context) { Widget _buildEditMessage(BuildContext context) => InkWell(
return InkWell( onTap: () async {
onTap: () async { Navigator.pop(context);
Navigator.pop(context); _showEditBottomSheet(context);
_showEditBottomSheet(context); },
}, child: Padding(
child: Padding( padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), child: Row(
child: Row( children: [
children: [ StreamSvgIcon.edit(
StreamSvgIcon.edit( color: StreamChatTheme.of(context).primaryIconTheme.color,
color: StreamChatTheme.of(context).primaryIconTheme.color, ),
), const SizedBox(width: 16),
const SizedBox(width: 16), Text(
Text( 'Edit Message',
'Edit Message', style: StreamChatTheme.of(context).textTheme.body,
style: StreamChatTheme.of(context).textTheme.body, ),
), ],
], ),
), ),
), );
);
}
Widget _buildResendMessage(BuildContext context) { Widget _buildResendMessage(BuildContext context) {
final isUpdateFailed = final isUpdateFailed =
@@ -533,86 +554,81 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
isScrollControlled: true, isScrollControlled: true,
backgroundColor: backgroundColor:
StreamChatTheme.of(context).messageInputTheme.inputBackground, StreamChatTheme.of(context).messageInputTheme.inputBackground,
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(16), topLeft: Radius.circular(16),
topRight: Radius.circular(16), topRight: Radius.circular(16),
), ),
), ),
builder: (context) { builder: (context) => StreamChannel(
return StreamChannel( channel: channel,
channel: channel, child: Flex(
child: Flex( direction: Axis.vertical,
direction: Axis.vertical, mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, children: <Widget>[
children: <Widget>[ Padding(
Padding( padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), child: Row(
child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
children: <Widget>[ Padding(
Padding( padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8), child: StreamSvgIcon.edit(
child: StreamSvgIcon.edit( color:
color: StreamChatTheme.of(context) StreamChatTheme.of(context).colorTheme.greyGainsboro,
.colorTheme
.greyGainsboro,
),
), ),
Text( ),
'Edit Message', const Text(
style: TextStyle(fontWeight: FontWeight.bold), 'Edit Message',
), style: TextStyle(fontWeight: FontWeight.bold),
IconButton( ),
visualDensity: VisualDensity.compact, IconButton(
icon: StreamSvgIcon.closeSmall(), visualDensity: VisualDensity.compact,
onPressed: Navigator.of(context).pop, icon: StreamSvgIcon.closeSmall(),
), onPressed: Navigator.of(context).pop,
], ),
), ],
), ),
if (widget.editMessageInputBuilder != null)
widget.editMessageInputBuilder!(context, widget.message)
else
MessageInput(
editMessage: widget.message,
preMessageSending: (m) {
FocusScope.of(context).unfocus();
Navigator.pop(context);
return m;
},
),
],
),
);
},
);
}
Widget _buildThreadReplyButton(BuildContext context) {
return InkWell(
onTap: () {
Navigator.pop(context);
if (widget.onThreadReplyTap != null) {
widget.onThreadReplyTap!(widget.message);
}
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
child: Row(
children: [
StreamSvgIcon.thread(
color: StreamChatTheme.of(context).primaryIconTheme.color,
),
const SizedBox(width: 16),
Text(
'Thread Reply',
style: StreamChatTheme.of(context).textTheme.body,
), ),
if (widget.editMessageInputBuilder != null)
widget.editMessageInputBuilder!(context, widget.message)
else
MessageInput(
editMessage: widget.message,
preMessageSending: (m) {
FocusScope.of(context).unfocus();
Navigator.pop(context);
return m;
},
),
], ],
), ),
), ),
); );
} }
Widget _buildThreadReplyButton(BuildContext context) => InkWell(
onTap: () {
Navigator.pop(context);
if (widget.onThreadReplyTap != null) {
widget.onThreadReplyTap!(widget.message);
}
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
child: Row(
children: [
StreamSvgIcon.thread(
color: StreamChatTheme.of(context).primaryIconTheme.color,
),
const SizedBox(width: 16),
Text(
'Thread Reply',
style: StreamChatTheme.of(context).textTheme.body,
),
],
),
),
);
} }
File diff suppressed because it is too large Load Diff