merge origin/develop into ref/segregate-api-layer

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2021-06-15 17:32:09 +05:30
62 changed files with 2287 additions and 1620 deletions
@@ -27,6 +27,8 @@ class MessageActionsModal extends StatefulWidget {
this.showResendMessage = true,
this.showThreadReplyMessage = true,
this.showFlagButton = true,
this.showPinButton = true,
this.showPinHighlight = false,
this.showUserAvatar = DisplayWidget.show,
this.editMessageInputBuilder,
this.messageShape,
@@ -35,6 +37,7 @@ class MessageActionsModal extends StatefulWidget {
this.customActions = const [],
this.attachmentBorderRadiusGeometry,
this.onCopyTap,
this.textBuilder,
}) : super(key: key);
/// Builder for edit message
@@ -79,6 +82,12 @@ class MessageActionsModal extends StatefulWidget {
/// Flag for showing flag action
final bool showFlagButton;
/// Flag for showing pin action
final bool showPinButton;
/// Display Pin Highlight
final bool showPinHighlight;
/// Flag for reversing message
final bool reverse;
@@ -97,6 +106,9 @@ class MessageActionsModal extends StatefulWidget {
/// List of custom actions
final List<MessageAction> customActions;
/// Customize the MessageWidget textBuilder
final Widget Function(BuildContext context, Message message)? textBuilder;
@override
_MessageActionsModalState createState() => _MessageActionsModalState();
}
@@ -135,6 +147,127 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
widget.message.attachments.any((it) => it.type == 'file') == true;
final streamChatThemeData = StreamChatTheme.of(context);
final numberOfReactions = streamChatThemeData.reactionIcons.length;
final shiftFactor =
numberOfReactions < 5 ? (5 - numberOfReactions) * 0.1 : 0.0;
final child = Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: widget.reverse
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: <Widget>[
if (widget.showReactions &&
(widget.message.status == MessageSendingStatus.sent))
Align(
alignment: Alignment(
user?.id == widget.message.user?.id
? (divFactor >= 1.0
? -0.2 - shiftFactor
: (1.2 - divFactor))
: (divFactor >= 1.0
? 0.2 + shiftFactor
: -(1.2 - divFactor)),
0),
child: ReactionPicker(
message: widget.message,
),
),
const SizedBox(height: 8),
IgnorePointer(
child: MessageWidget(
key: const Key('MessageWidget'),
reverse: widget.reverse,
attachmentBorderRadiusGeometry: widget
.attachmentBorderRadiusGeometry
?.mirrorBorderIfReversed(reverse: !widget.reverse),
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,
),
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,
showPinHighlight: false,
textBuilder: widget.textBuilder,
),
),
const SizedBox(height: 8),
Padding(
padding: EdgeInsets.only(
left: widget.reverse ? 0 : 40,
),
child: SizedBox(
width: mediaQueryData.size.width * 0.75,
child: Material(
color: streamChatThemeData.colorTheme.whiteSnow,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
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.showPinButton) _buildPinButton(context),
if (widget.showDeleteMessage)
_buildDeleteButton(context),
...widget.customActions
.map((action) => _buildCustomAction(
context,
action,
))
].insertBetween(
Container(
height: 1,
color: streamChatThemeData.colorTheme.greyWhisper,
),
),
),
),
),
),
],
),
),
),
);
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => Navigator.maybePop(context),
@@ -156,132 +289,11 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
tween: Tween(begin: 0, end: 1),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutBack,
builder: (context, val, snapshot) => Transform.scale(
builder: (context, val, child) => Transform.scale(
scale: val,
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: widget.reverse
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: <Widget>[
if (widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.sent))
Align(
alignment: Alignment(
user?.id == widget.message.user?.id
? (divFactor >= 1.0
? -0.2
: (1.2 - divFactor))
: (divFactor >= 1.0
? 0.2
: -(1.2 - divFactor)),
0),
child: ReactionPicker(
message: widget.message,
),
),
const SizedBox(height: 8),
IgnorePointer(
child: MessageWidget(
key: const Key('MessageWidget'),
reverse: widget.reverse,
attachmentBorderRadiusGeometry: widget
.attachmentBorderRadiusGeometry
?.mirrorBorderIfReversed(
reverse: !widget.reverse),
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,
),
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,
),
),
const SizedBox(height: 8),
Padding(
padding: EdgeInsets.only(
left: widget.reverse ? 0 : 40,
),
child: SizedBox(
width: mediaQueryData.size.width * 0.75,
child: Material(
color: streamChatThemeData.colorTheme.whiteSnow,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
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: streamChatThemeData
.colorTheme.greyWhisper,
),
),
),
),
),
),
],
),
),
),
),
child: child,
),
child: child,
),
],
),
@@ -360,6 +372,21 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
}
}
void _togglePin() async {
final channel = StreamChannel.of(context).channel;
Navigator.pop(context);
try {
if (!widget.message.pinned) {
await channel.pinMessage(widget.message);
} else {
await channel.unpinMessage(widget.message);
}
} catch (e) {
_showErrorAlert();
}
}
void _showDeleteDialog() async {
setState(() {
_showActions = false;
@@ -452,6 +479,29 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
);
}
Widget _buildPinButton(BuildContext context) {
final streamChatThemeData = StreamChatTheme.of(context);
return InkWell(
onTap: _togglePin,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
child: Row(
children: [
StreamSvgIcon.pin(
color: streamChatThemeData.primaryIconTheme.color,
size: 24,
),
const SizedBox(width: 16),
Text(
'${widget.message.pinned ? 'Unpin from' : 'Pin to'} Conversation',
style: streamChatThemeData.textTheme.body,
),
],
),
),
);
}
Widget _buildDeleteButton(BuildContext context) {
final isDeleteFailed =
widget.message.status == MessageSendingStatus.failed_delete;