fix reaction modal ui

This commit is contained in:
Salvatore Giordano
2020-10-16 12:50:58 +02:00
parent c4a890d069
commit b0ad9c673e
8 changed files with 175 additions and 112 deletions
+1 -1
View File
@@ -154,7 +154,7 @@ class ChannelBottomSheet extends StatelessWidget {
height: 83,
child: ListView(
padding: EdgeInsets.only(
left: (MediaQuery.of(context).size.width / 2) - 48,
left: (MediaQuery.of(context).size.width / 2) - 80,
),
scrollDirection: Axis.horizontal,
children: snapshot.data.map((m) {
+1
View File
@@ -1,5 +1,6 @@
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/reaction_picker.dart';
+110 -68
View File
@@ -22,6 +22,7 @@ class MessageReactionsModal extends StatelessWidget {
final bool showReply;
final bool reverse;
final ShapeBorder messageShape;
final void Function(User) onUserAvatarTap;
const MessageReactionsModal({
Key key,
@@ -35,6 +36,7 @@ class MessageReactionsModal extends StatelessWidget {
this.editMessageInputBuilder,
this.messageShape,
this.reverse,
this.onUserAvatarTap,
}) : super(key: key);
@override
@@ -87,79 +89,119 @@ class MessageReactionsModal extends StatelessWidget {
),
),
SizedBox(
height: 8,
height: 16,
),
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,
),
],
);
},
),
),
)
Container(
constraints: BoxConstraints.loose(Size.fromHeight(400)),
child: _buildReactionCard(context),
),
],
),
],
);
}
Padding _buildReactionCard(BuildContext context) {
final currentUser = StreamChat.of(context).user;
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
child: Card(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'Message Reactions',
style: Theme.of(context).textTheme.headline6,
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16,
bottom: 16,
),
child: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 16,
childAspectRatio: 0.75,
mainAxisSpacing: 22,
),
itemCount: message.latestReactions.length,
itemBuilder: (context, i) {
final reaction = message.latestReactions[i];
return _buildReaction(
reaction,
currentUser,
context,
);
},
),
),
),
],
),
),
);
}
Column _buildReaction(
Reaction reaction,
User currentUser,
BuildContext context,
) {
final isCurrentUser = reaction.user.id == currentUser.id;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
UserAvatar(
onTap: onUserAvatarTap,
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,
),
],
);
}
}
+1
View File
@@ -485,6 +485,7 @@ class _MessageWidgetState extends State<MessageWidget> {
return StreamChannel(
channel: channel,
child: MessageReactionsModal(
onUserAvatarTap: widget.onUserAvatarTap,
messageTheme: widget.messageTheme,
messageShape: widget.shape ?? _getDefaultShape(context),
reverse: widget.reverse,
+56 -37
View File
@@ -1,4 +1,7 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
import '../stream_chat_flutter.dart';
@@ -23,44 +26,60 @@ class ReactionPicker extends StatelessWidget {
@override
Widget build(BuildContext context) {
final reactionAssets = StreamChatTheme.of(context).reactionIcons;
return Material(
color: messageTheme.ownReactionsBackgroundColor,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: reactionAssets.map((reactionIcon) {
final ownReactionIndex = message.ownReactions?.indexWhere(
(reaction) => reaction.type == reactionIcon.type) ??
-1;
return IconButton(
iconSize: 24,
icon: Icon(
reactionIcon.iconData,
color: ownReactionIndex != -1
? StreamChatTheme.of(context).accentColor
: Theme.of(context).iconTheme.color,
return Stack(
fit: StackFit.passthrough,
children: [
Material(
color: messageTheme.ownReactionsBackgroundColor,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: reactionAssets.map((reactionIcon) {
final ownReactionIndex = message.ownReactions?.indexWhere(
(reaction) => reaction.type == reactionIcon.type) ??
-1;
return IconButton(
iconSize: 24,
icon: Icon(
reactionIcon.iconData,
color: ownReactionIndex != -1
? StreamChatTheme.of(context).accentColor
: Theme.of(context).iconTheme.color,
),
onPressed: () {
if (ownReactionIndex != -1) {
removeReaction(
context,
message.ownReactions[ownReactionIndex],
);
} else {
sendReaction(
context,
reactionIcon.type,
);
}
},
);
}).toList(),
),
),
Positioned(
right: 14,
bottom: 0,
child: CustomPaint(
painter: ReactionBubblePainter(
messageTheme.ownReactionsBackgroundColor,
messageTheme.ownReactionsBorderColor,
2,
),
onPressed: () {
if (ownReactionIndex != -1) {
removeReaction(
context,
message.ownReactions[ownReactionIndex],
);
} else {
sendReaction(
context,
reactionIcon.type,
);
}
},
);
}).toList(),
),
),
),
],
);
}