add reactions
This commit is contained in:
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final client = Client('qk4nn7rpcn75');
|
final client = Client('qk4nn7rpcn75', logLevel: Level.INFO);
|
||||||
|
|
||||||
await client.setUser(
|
await client.setUser(
|
||||||
User(id: 'wild-breeze-7'),
|
User(id: 'wild-breeze-7'),
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
? widget.threadBuilder(context, message)
|
? widget.threadBuilder(context, message)
|
||||||
: null);
|
: null);
|
||||||
};
|
};
|
||||||
} else {
|
} else if (widget.threadBuilder != null) {
|
||||||
_onThreadTap = (message) {
|
_onThreadTap = (message) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
|
|||||||
+100
-71
@@ -222,21 +222,34 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (widget.message.text.trim().isNotEmpty) {
|
if (widget.message.text.trim().isNotEmpty) {
|
||||||
column.children.add(Container(
|
final topPadding = widget.message.latestReactions.isNotEmpty ? 36.0 : 0.0;
|
||||||
margin: EdgeInsets.only(
|
column.children.add(Stack(
|
||||||
top: nOfAttachmentWidgets > 0 ? 5 : 0,
|
overflow: Overflow.visible,
|
||||||
),
|
children: <Widget>[
|
||||||
decoration: _buildBoxDecoration(
|
widget.message.latestReactions.isNotEmpty
|
||||||
isMyMessage, isLastUser || nOfAttachmentWidgets > 0),
|
? Positioned(
|
||||||
padding: EdgeInsets.all(10),
|
left: isMyMessage ? 0 : null,
|
||||||
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
right: !isMyMessage ? 0 : null,
|
||||||
child: MarkdownBody(
|
top: 0,
|
||||||
data: '${widget.message.text}',
|
child: _buildReactions(isMyMessage))
|
||||||
onTapLink: (link) {
|
: SizedBox(),
|
||||||
_launchURL(link);
|
Container(
|
||||||
},
|
margin: EdgeInsets.only(
|
||||||
styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)),
|
top: nOfAttachmentWidgets > 0 ? (topPadding) : (topPadding),
|
||||||
),
|
),
|
||||||
|
decoration: _buildBoxDecoration(
|
||||||
|
isMyMessage, isLastUser || nOfAttachmentWidgets > 0),
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
||||||
|
child: MarkdownBody(
|
||||||
|
data: '${widget.message.text}',
|
||||||
|
onTapLink: (link) {
|
||||||
|
_launchURL(link);
|
||||||
|
},
|
||||||
|
styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,73 +266,72 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: reactionToEmoji.keys.map((reactionType) {
|
||||||
IconButton(
|
return IconButton(
|
||||||
iconSize: fontSize + 10,
|
iconSize: fontSize + 10,
|
||||||
icon: Text(
|
icon: Text(
|
||||||
'♥️',
|
reactionToEmoji[reactionType],
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
sendReaction('love');
|
sendReaction(reactionType);
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
IconButton(
|
}).toList(),
|
||||||
iconSize: fontSize + 10,
|
|
||||||
icon: Text(
|
|
||||||
'😂',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
sendReaction('haha');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
iconSize: fontSize + 10,
|
|
||||||
icon: Text(
|
|
||||||
'👍',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
sendReaction('like');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
iconSize: fontSize + 10,
|
|
||||||
icon: Text(
|
|
||||||
'😕',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
sendReaction('sad');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
iconSize: fontSize + 10,
|
|
||||||
icon: Text(
|
|
||||||
'😡',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
sendReaction('angry');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
iconSize: fontSize + 10,
|
|
||||||
icon: Text(
|
|
||||||
'😲',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
sendReaction('wow');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildReactions(bool isMyMessage) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
||||||
|
child: Stack(
|
||||||
|
overflow: Overflow.visible,
|
||||||
|
children: <Widget>[
|
||||||
|
widget.message.latestReactions.isNotEmpty
|
||||||
|
? Positioned(
|
||||||
|
left: isMyMessage ? 0 : null,
|
||||||
|
right: !isMyMessage ? 0 : null,
|
||||||
|
bottom: 1,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: ReactionBubblePainter(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
|
AnimatedContainer(
|
||||||
|
transform: Matrix4.translationValues(
|
||||||
|
-16 * (isMyMessage ? 1.0 : -1.0), 0, 0),
|
||||||
|
padding: widget.message.latestReactions.isNotEmpty
|
||||||
|
? const EdgeInsets.all(8)
|
||||||
|
: EdgeInsets.zero,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(14))),
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: <Widget>[]
|
||||||
|
..addAll(widget.message.latestReactions.map((reaction) {
|
||||||
|
return Text(reactionToEmoji[reaction.type] ?? '?');
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, String> reactionToEmoji = {
|
||||||
|
'love': '♥️',
|
||||||
|
'haha': '😂',
|
||||||
|
'like': '👍',
|
||||||
|
'sad': '😕',
|
||||||
|
'angry': '😡',
|
||||||
|
'wow': '😲',
|
||||||
|
};
|
||||||
|
|
||||||
void sendReaction(String reactionType) {
|
void sendReaction(String reactionType) {
|
||||||
StreamChannel.of(context)
|
StreamChannel.of(context)
|
||||||
.channelClient
|
.channelClient
|
||||||
@@ -437,3 +449,20 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return widget.message.attachments.isNotEmpty;
|
return widget.message.attachments.isNotEmpty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReactionBubblePainter extends CustomPainter {
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final paint = Paint()..color = Colors.black;
|
||||||
|
final path = Path();
|
||||||
|
path.arcToPoint(Offset(-5, 0));
|
||||||
|
path.arcToPoint(Offset(0, 10), radius: Radius.circular(16));
|
||||||
|
path.arcToPoint(Offset(5, 0), radius: Radius.circular(16));
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user