[ReactionBubble] Add masked spacing
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -232,6 +232,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
flipTail: !reverse,
|
flipTail: !reverse,
|
||||||
borderColor: messageTheme.reactionsBorderColor,
|
borderColor: messageTheme.reactionsBorderColor,
|
||||||
backgroundColor: messageTheme.reactionsBackgroundColor,
|
backgroundColor: messageTheme.reactionsBackgroundColor,
|
||||||
|
maskColor: messageTheme.reactionsMaskColor,
|
||||||
highlightOwnReactions: false,
|
highlightOwnReactions: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -447,6 +447,9 @@ class _MessageWidgetState extends State<MessageWidget> {
|
|||||||
StreamChatTheme.of(context)
|
StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
.white,
|
.white,
|
||||||
|
StreamChatTheme.of(context)
|
||||||
|
.colorTheme
|
||||||
|
.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -694,6 +697,7 @@ class _MessageWidgetState extends State<MessageWidget> {
|
|||||||
flipTail: widget.reverse,
|
flipTail: widget.reverse,
|
||||||
backgroundColor: widget.messageTheme.reactionsBackgroundColor,
|
backgroundColor: widget.messageTheme.reactionsBackgroundColor,
|
||||||
borderColor: widget.messageTheme.reactionsBorderColor,
|
borderColor: widget.messageTheme.reactionsBorderColor,
|
||||||
|
maskColor: widget.messageTheme.reactionsMaskColor,
|
||||||
reactions: reactionsList,
|
reactions: reactionsList,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
@required this.reactions,
|
@required this.reactions,
|
||||||
@required this.borderColor,
|
@required this.borderColor,
|
||||||
@required this.backgroundColor,
|
@required this.backgroundColor,
|
||||||
|
@required this.maskColor,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.flipTail = false,
|
this.flipTail = false,
|
||||||
this.highlightOwnReactions = true,
|
this.highlightOwnReactions = true,
|
||||||
@@ -20,6 +21,7 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
final List<Reaction> reactions;
|
final List<Reaction> reactions;
|
||||||
final Color borderColor;
|
final Color borderColor;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
final Color maskColor;
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
final bool flipTail;
|
final bool flipTail;
|
||||||
final bool highlightOwnReactions;
|
final bool highlightOwnReactions;
|
||||||
@@ -38,51 +40,58 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
Transform.translate(
|
Transform.translate(
|
||||||
offset: Offset(reverse ? offset : -offset, 0),
|
offset: Offset(reverse ? offset : -offset, 0),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: const EdgeInsets.all(2),
|
||||||
vertical: 4,
|
|
||||||
horizontal: totalReactions > 1 ? 4 : 0,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
color: maskColor,
|
||||||
color: borderColor,
|
|
||||||
),
|
|
||||||
color: backgroundColor,
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||||
),
|
),
|
||||||
child: LayoutBuilder(
|
child: Container(
|
||||||
builder: (context, constraints) {
|
padding: EdgeInsets.symmetric(
|
||||||
return Flex(
|
vertical: 4,
|
||||||
direction: Axis.horizontal,
|
horizontal: totalReactions > 1 ? 4 : 0,
|
||||||
mainAxisSize: MainAxisSize.min,
|
),
|
||||||
children: [
|
decoration: BoxDecoration(
|
||||||
if (constraints.maxWidth < double.infinity)
|
border: Border.all(
|
||||||
...reactions
|
color: borderColor,
|
||||||
.take((constraints.maxWidth) ~/ 22)
|
),
|
||||||
.map((reaction) {
|
color: backgroundColor,
|
||||||
return _buildReaction(
|
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||||
reactionIcons,
|
),
|
||||||
reaction,
|
child: LayoutBuilder(
|
||||||
context,
|
builder: (context, constraints) {
|
||||||
);
|
return Flex(
|
||||||
}).toList(),
|
direction: Axis.horizontal,
|
||||||
if (constraints.maxWidth == double.infinity)
|
mainAxisSize: MainAxisSize.min,
|
||||||
...reactions.map((reaction) {
|
children: [
|
||||||
return _buildReaction(
|
if (constraints.maxWidth < double.infinity)
|
||||||
reactionIcons,
|
...reactions
|
||||||
reaction,
|
.take((constraints.maxWidth) ~/ 22)
|
||||||
context,
|
.map((reaction) {
|
||||||
);
|
return _buildReaction(
|
||||||
}).toList(),
|
reactionIcons,
|
||||||
],
|
reaction,
|
||||||
);
|
context,
|
||||||
},
|
);
|
||||||
|
}).toList(),
|
||||||
|
if (constraints.maxWidth == double.infinity)
|
||||||
|
...reactions.map((reaction) {
|
||||||
|
return _buildReaction(
|
||||||
|
reactionIcons,
|
||||||
|
reaction,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 2,
|
||||||
left: reverse ? null : 11,
|
left: reverse ? null : 13,
|
||||||
right: !reverse ? null : 11,
|
right: !reverse ? null : 13,
|
||||||
child: _buildReactionsTail(context),
|
child: _buildReactionsTail(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -136,6 +145,7 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
painter: ReactionBubblePainter(
|
painter: ReactionBubblePainter(
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
|
maskColor,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return Transform(
|
return Transform(
|
||||||
@@ -149,14 +159,20 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
class ReactionBubblePainter extends CustomPainter {
|
class ReactionBubblePainter extends CustomPainter {
|
||||||
final Color color;
|
final Color color;
|
||||||
final Color borderColor;
|
final Color borderColor;
|
||||||
|
final Color maskColor;
|
||||||
|
|
||||||
ReactionBubblePainter(
|
ReactionBubblePainter(
|
||||||
this.color,
|
this.color,
|
||||||
this.borderColor,
|
this.borderColor,
|
||||||
|
this.maskColor,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
|
_drawOvalMask(size, canvas);
|
||||||
|
|
||||||
|
_drawMask(size, canvas);
|
||||||
|
|
||||||
_drawOval(size, canvas);
|
_drawOval(size, canvas);
|
||||||
|
|
||||||
_drawOvalBorder(size, canvas);
|
_drawOvalBorder(size, canvas);
|
||||||
@@ -166,6 +182,21 @@ class ReactionBubblePainter extends CustomPainter {
|
|||||||
_drawBorder(size, canvas);
|
_drawBorder(size, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _drawOvalMask(Size size, Canvas canvas) {
|
||||||
|
final paint = Paint()
|
||||||
|
..color = maskColor
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
|
final path = Path();
|
||||||
|
path.addOval(
|
||||||
|
Rect.fromCircle(
|
||||||
|
center: Offset(4, 3),
|
||||||
|
radius: 4,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
void _drawOvalBorder(Size size, Canvas canvas) {
|
void _drawOvalBorder(Size size, Canvas canvas) {
|
||||||
final paint = Paint()
|
final paint = Paint()
|
||||||
..color = borderColor
|
..color = borderColor
|
||||||
@@ -236,6 +267,27 @@ class ReactionBubblePainter extends CustomPainter {
|
|||||||
canvas.drawPath(path, paint);
|
canvas.drawPath(path, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _drawMask(Size size, Canvas canvas) {
|
||||||
|
final paint = Paint()
|
||||||
|
..color = maskColor
|
||||||
|
..strokeWidth = 1
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
|
final dy = -2.2;
|
||||||
|
final startAngle = 1.1;
|
||||||
|
final sweepAngle = 1.2;
|
||||||
|
final path = Path();
|
||||||
|
path.addArc(
|
||||||
|
Rect.fromCircle(
|
||||||
|
center: Offset(1, dy),
|
||||||
|
radius: 6,
|
||||||
|
),
|
||||||
|
-pi * startAngle,
|
||||||
|
-pi / sweepAngle,
|
||||||
|
);
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ class StreamChatThemeData {
|
|||||||
messageBackgroundColor: colorTheme.greyGainsboro,
|
messageBackgroundColor: colorTheme.greyGainsboro,
|
||||||
reactionsBackgroundColor: colorTheme.white,
|
reactionsBackgroundColor: colorTheme.white,
|
||||||
reactionsBorderColor: colorTheme.greyWhisper,
|
reactionsBorderColor: colorTheme.greyWhisper,
|
||||||
|
reactionsMaskColor: colorTheme.whiteSnow,
|
||||||
messageBorderColor: colorTheme.greyGainsboro,
|
messageBorderColor: colorTheme.greyGainsboro,
|
||||||
avatarTheme: AvatarTheme(
|
avatarTheme: AvatarTheme(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
@@ -249,6 +250,7 @@ class StreamChatThemeData {
|
|||||||
otherMessageTheme: MessageTheme(
|
otherMessageTheme: MessageTheme(
|
||||||
reactionsBackgroundColor: colorTheme.greyGainsboro,
|
reactionsBackgroundColor: colorTheme.greyGainsboro,
|
||||||
reactionsBorderColor: colorTheme.white,
|
reactionsBorderColor: colorTheme.white,
|
||||||
|
reactionsMaskColor: colorTheme.whiteSnow,
|
||||||
messageText: textTheme.body,
|
messageText: textTheme.body,
|
||||||
createdAt: textTheme.footnote.copyWith(color: colorTheme.grey),
|
createdAt: textTheme.footnote.copyWith(color: colorTheme.grey),
|
||||||
replies: textTheme.footnoteBold.copyWith(color: accentColor),
|
replies: textTheme.footnoteBold.copyWith(color: accentColor),
|
||||||
@@ -710,6 +712,7 @@ class MessageTheme {
|
|||||||
final Color messageBorderColor;
|
final Color messageBorderColor;
|
||||||
final Color reactionsBackgroundColor;
|
final Color reactionsBackgroundColor;
|
||||||
final Color reactionsBorderColor;
|
final Color reactionsBorderColor;
|
||||||
|
final Color reactionsMaskColor;
|
||||||
final AvatarTheme avatarTheme;
|
final AvatarTheme avatarTheme;
|
||||||
|
|
||||||
const MessageTheme({
|
const MessageTheme({
|
||||||
@@ -721,6 +724,7 @@ class MessageTheme {
|
|||||||
this.messageBorderColor,
|
this.messageBorderColor,
|
||||||
this.reactionsBackgroundColor,
|
this.reactionsBackgroundColor,
|
||||||
this.reactionsBorderColor,
|
this.reactionsBorderColor,
|
||||||
|
this.reactionsMaskColor,
|
||||||
this.avatarTheme,
|
this.avatarTheme,
|
||||||
this.createdAt,
|
this.createdAt,
|
||||||
});
|
});
|
||||||
@@ -736,6 +740,7 @@ class MessageTheme {
|
|||||||
AvatarTheme avatarTheme,
|
AvatarTheme avatarTheme,
|
||||||
Color reactionsBackgroundColor,
|
Color reactionsBackgroundColor,
|
||||||
Color reactionsBorderColor,
|
Color reactionsBorderColor,
|
||||||
|
Color reactionsMaskColor,
|
||||||
}) =>
|
}) =>
|
||||||
MessageTheme(
|
MessageTheme(
|
||||||
messageText: messageText ?? this.messageText,
|
messageText: messageText ?? this.messageText,
|
||||||
@@ -750,6 +755,7 @@ class MessageTheme {
|
|||||||
reactionsBackgroundColor:
|
reactionsBackgroundColor:
|
||||||
reactionsBackgroundColor ?? this.reactionsBackgroundColor,
|
reactionsBackgroundColor ?? this.reactionsBackgroundColor,
|
||||||
reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor,
|
reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor,
|
||||||
|
reactionsMaskColor: reactionsMaskColor ?? this.reactionsMaskColor,
|
||||||
);
|
);
|
||||||
|
|
||||||
MessageTheme merge(MessageTheme other) {
|
MessageTheme merge(MessageTheme other) {
|
||||||
@@ -767,6 +773,7 @@ class MessageTheme {
|
|||||||
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
||||||
reactionsBackgroundColor: other.reactionsBackgroundColor,
|
reactionsBackgroundColor: other.reactionsBackgroundColor,
|
||||||
reactionsBorderColor: other.reactionsBorderColor,
|
reactionsBorderColor: other.reactionsBorderColor,
|
||||||
|
reactionsMaskColor: other.reactionsMaskColor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user