add reactions modal

This commit is contained in:
Salvatore Giordano
2020-10-16 12:42:56 +02:00
parent ab1e855cfe
commit c4a890d069
4 changed files with 197 additions and 5 deletions
+3 -1
View File
@@ -75,7 +75,9 @@ void main() async {
);
await client.setUser(
User(id: 'super-band-9'),
User(id: 'super-band-9', extraData: {
'name': 'John Doe',
}),
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A',
);
+1 -1
View File
@@ -1,7 +1,7 @@
name: example
description: A new Flutter project.
version: 1.0.28+30
version: 1.0.29+31
environment:
sdk: ">=2.2.2 <3.0.0"
+165
View File
@@ -0,0 +1,165 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
import 'package:stream_chat_flutter/src/reaction_picker.dart';
import 'package:stream_chat_flutter/src/stream_channel.dart';
import 'package:stream_chat_flutter/src/stream_chat.dart';
import 'package:stream_chat_flutter/src/user_avatar.dart';
import 'message_widget.dart';
import 'stream_chat_theme.dart';
class MessageReactionsModal extends StatelessWidget {
final Widget Function(BuildContext, Message) editMessageInputBuilder;
final void Function(Message) onThreadTap;
final Message message;
final MessageTheme messageTheme;
final bool showReactions;
final bool showDeleteMessage;
final bool showEditMessage;
final bool showReply;
final bool reverse;
final ShapeBorder messageShape;
const MessageReactionsModal({
Key key,
@required this.message,
@required this.messageTheme,
this.showReactions,
this.showDeleteMessage,
this.showEditMessage,
this.onThreadTap,
this.showReply,
this.editMessageInputBuilder,
this.messageShape,
this.reverse,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final channel = StreamChannel.of(context).channel;
return Stack(
children: [
Positioned.fill(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context);
},
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Container(
color: Colors.transparent,
),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (showReactions &&
(message.status == MessageSendingStatus.SENT ||
message.status == null))
Center(
child: ReactionPicker(
channel: channel,
message: message,
messageTheme: messageTheme,
),
),
AbsorbPointer(
child: MessageWidget(
reverse: reverse,
message: message,
messageTheme: messageTheme,
showReactions: false,
showUsername: false,
showReplyIndicator: false,
showTimestamp: false,
showSendingIndicator: DisplayWidget.gone,
shape: messageShape,
),
),
SizedBox(
height: 8,
),
if (message.latestReactions.isNotEmpty)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
child: Card(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: GridView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(16.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 16,
childAspectRatio: 0.8,
mainAxisSpacing: 22,
),
itemCount: message.latestReactions.length,
itemBuilder: (context, i) {
final reaction = message.latestReactions[i];
final isCurrentUser =
reaction.user.id == StreamChat.of(context).user.id;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
UserAvatar(
user: reaction.user,
constraints: BoxConstraints.tightFor(
height: 64,
width: 64,
),
borderRadius: BorderRadius.circular(32),
),
Positioned(
child: ReactionBubble(
reactions: [reaction],
borderColor: isCurrentUser
? messageTheme.ownReactionsBorderColor
: messageTheme.otherReactionsBorderColor,
backgroundColor: isCurrentUser
? messageTheme.ownReactionsBackgroundColor
: messageTheme
.otherReactionsBackgroundColor,
flipTail: !isCurrentUser,
),
bottom: 0,
left: isCurrentUser ? 0 : null,
right: isCurrentUser ? 0 : null,
),
],
),
Text(
reaction.user.name,
style: Theme.of(context).textTheme.subtitle2,
textAlign: TextAlign.center,
),
],
);
},
),
),
)
],
),
],
);
}
}
+28 -3
View File
@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:jiffy/jiffy.dart';
import 'package:stream_chat_flutter/src/message_actions_modal.dart';
import 'package:stream_chat_flutter/src/message_reactions_modal.dart';
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -437,7 +438,7 @@ class _MessageWidgetState extends State<MessageWidget> {
!widget.message.isDeleted)
? Container(
child: GestureDetector(
onTap: () => onLongPress(context),
onTap: () => _showMessageReactionsModalBottomSheet(context),
child: FractionallySizedBox(
widthFactor: 0.5,
child: Row(
@@ -452,7 +453,7 @@ class _MessageWidgetState extends State<MessageWidget> {
);
}
void _showMessageModalBottomSheet(BuildContext context) {
void _showMessageActionModalBottomSheet(BuildContext context) {
final channel = StreamChannel.of(context).channel;
showDialog(
context: context,
@@ -476,6 +477,30 @@ class _MessageWidgetState extends State<MessageWidget> {
});
}
void _showMessageReactionsModalBottomSheet(BuildContext context) {
final channel = StreamChannel.of(context).channel;
showDialog(
context: context,
builder: (context) {
return StreamChannel(
channel: channel,
child: MessageReactionsModal(
messageTheme: widget.messageTheme,
messageShape: widget.shape ?? _getDefaultShape(context),
reverse: widget.reverse,
showDeleteMessage: widget.showDeleteMessage,
message: widget.message,
editMessageInputBuilder: widget.editMessageInputBuilder,
onThreadTap: widget.onThreadTap,
showEditMessage: widget.showEditMessage,
showReactions: widget.showReactions,
showReply:
widget.showReplyIndicator && widget.onThreadTap != null,
),
);
});
}
ContinuousRectangleBorder _getDefaultShape(BuildContext context) {
return ContinuousRectangleBorder(
side: widget.attachmentBorderSide ??
@@ -581,7 +606,7 @@ class _MessageWidgetState extends State<MessageWidget> {
if (widget.onMessageActions != null) {
widget.onMessageActions(context, widget.message);
} else {
_showMessageModalBottomSheet(context);
_showMessageActionModalBottomSheet(context);
}
return;
}