Merge branch 'feature/new-ui' into feature/mono-repo
This commit is contained in:
@@ -14,6 +14,7 @@ import 'message_input.dart';
|
||||
import 'message_widget.dart';
|
||||
import 'stream_chat.dart';
|
||||
import 'stream_chat_theme.dart';
|
||||
import 'extension.dart';
|
||||
|
||||
class MessageActionsModal extends StatefulWidget {
|
||||
final Widget Function(BuildContext, Message) editMessageInputBuilder;
|
||||
@@ -89,6 +90,8 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutBack,
|
||||
builder: (context, val, snapshot) {
|
||||
final hasFileAttachment =
|
||||
widget.message.attachments?.any((it) => it.type == 'file') == true;
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => Navigator.maybePop(context),
|
||||
@@ -110,7 +113,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
child: Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: widget.reverse
|
||||
? CrossAxisAlignment.end
|
||||
@@ -135,6 +138,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
messageTheme: widget.messageTheme,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
IgnorePointer(
|
||||
child: MessageWidget(
|
||||
key: Key('MessageWidget'),
|
||||
@@ -150,8 +154,17 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
showThreadReplyIndicator: 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.0,
|
||||
horizontal:
|
||||
widget.message.text.isOnlyEmoji ? 0 : 16.0,
|
||||
),
|
||||
showReactionPickerIndicator:
|
||||
widget.showReactions &&
|
||||
(widget.message.status ==
|
||||
@@ -162,10 +175,10 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
shape: widget.messageShape,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: widget.reverse ? 8 : 0,
|
||||
left: widget.reverse ? 0 : 48,
|
||||
left: widget.reverse ? 0 : 40,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.75,
|
||||
@@ -180,36 +193,37 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.stretch,
|
||||
children: ListTile.divideTiles(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.greyWhisper,
|
||||
context: context,
|
||||
tiles: [
|
||||
if (widget.showReplyMessage &&
|
||||
(widget.message.status ==
|
||||
MessageSendingStatus.SENT ||
|
||||
widget.message.status == null) &&
|
||||
widget.message.parentId == null)
|
||||
_buildReplyButton(context),
|
||||
if (widget.showThreadReplyMessage &&
|
||||
(widget.message.status ==
|
||||
MessageSendingStatus.SENT ||
|
||||
widget.message.status == null) &&
|
||||
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),
|
||||
],
|
||||
).toList(),
|
||||
children: [
|
||||
if (widget.showReplyMessage &&
|
||||
(widget.message.status ==
|
||||
MessageSendingStatus.SENT ||
|
||||
widget.message.status == null) &&
|
||||
widget.message.parentId == null)
|
||||
_buildReplyButton(context),
|
||||
if (widget.showThreadReplyMessage &&
|
||||
(widget.message.status ==
|
||||
MessageSendingStatus.SENT ||
|
||||
widget.message.status == null) &&
|
||||
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),
|
||||
].insertBetween(
|
||||
Container(
|
||||
height: 1,
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.greyWhisper,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -410,136 +424,131 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
}
|
||||
|
||||
Widget _buildReplyButton(BuildContext context) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.reply(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Reply',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
if (widget.onReplyTap != null) {
|
||||
widget.onReplyTap(widget.message);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.reply(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Reply',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFlagButton(BuildContext context) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.icon_flag(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Flag',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () => _showFlagDialog(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.icon_flag(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Flag',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeleteButton(BuildContext context) {
|
||||
final isDeleteFailed =
|
||||
widget.message.status == MessageSendingStatus.FAILED_DELETE;
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.delete(
|
||||
color: Colors.red,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
isDeleteFailed ? 'Retry Deleting Message' : 'Delete Message',
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.headline
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
],
|
||||
return InkWell(
|
||||
onTap: () => _showDeleteDialog(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.delete(
|
||||
color: Colors.red,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
isDeleteFailed ? 'Retry Deleting Message' : 'Delete Message',
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.body
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
_showDeleteDialog();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCopyButton(BuildContext context) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.copy(
|
||||
size: 24,
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Copy Message',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
await Clipboard.setData(ClipboardData(text: widget.message.text));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.copy(
|
||||
size: 24,
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Copy Message',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEditMessage(BuildContext context) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.edit(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Edit Message',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
_showEditBottomSheet(context);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.edit(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Edit Message',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildResendMessage(BuildContext context) {
|
||||
final isUpdateFailed =
|
||||
widget.message.status == MessageSendingStatus.FAILED_UPDATE;
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.circle_up(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
isUpdateFailed ? 'Resend Edited Message' : 'Resend',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
final client = StreamChat.of(context).client;
|
||||
@@ -550,6 +559,21 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
channel.sendMessage(widget.message);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.circle_up(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
isUpdateFailed ? 'Resend Edited Message' : 'Resend',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -623,26 +647,28 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
||||
}
|
||||
|
||||
Widget _buildThreadReplyButton(BuildContext context) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Row(
|
||||
children: [
|
||||
StreamSvgIcon.thread(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Thread Reply',
|
||||
style: StreamChatTheme.of(context).textTheme.headline,
|
||||
),
|
||||
],
|
||||
),
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
if (widget.onThreadReplyTap != null) {
|
||||
widget.onThreadReplyTap(widget.message);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.thread(
|
||||
color: StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
'Thread Reply',
|
||||
style: StreamChatTheme.of(context).textTheme.body,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user