Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/ios/Flutter/.last_build_id
Original file line number Diff line number Diff line change
@@ -1 +1 @@
06fe8d0d3d89937a6d33b1033e75ae96
0289cdadbd29bab804f275e3c5907d07
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ PODS:
- Firebase/Messaging (6.26.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 4.4.1)
- firebase_core (0.5.0):
- firebase_core (0.5.0-1):
- Firebase/CoreOnly (~> 6.26.0)
- Flutter
- firebase_messaging (7.0.2):
- firebase_messaging (7.0.3):
- Firebase/CoreOnly (~> 6.26.0)
- Firebase/Messaging (~> 6.26.0)
- firebase_core
Expand Down Expand Up @@ -233,8 +233,8 @@ SPEC CHECKSUMS:
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
Firebase: 7cf5f9c67f03cb3b606d1d6535286e1080e57eb6
firebase_core: 3134fe79d257d430f163b558caf52a10a87efe8a
firebase_messaging: 2844c37f9ce87c0904b38fe435223161b1a71528
firebase_core: 00e54a4744164a6b5a250b96dd1ad5afaba7a342
firebase_messaging: 666d9994651b1ecf8c582b52dd913f3fa58c17ef
FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
FirebaseCore: f42e5e5f382cdcf6b617ed737bf6c871a6947b17
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
Expand Down
4 changes: 3 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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',
);

Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: example
description: A new Flutter project.

version: 1.0.28+30
version: 1.0.30+32

environment:
sdk: ">=2.2.2 <3.0.0"
Expand Down
Binary file modified fonts/stream-icons.ttf
Binary file not shown.
39 changes: 30 additions & 9 deletions lib/src/message_actions_modal.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/reaction_picker.dart';
import 'package:stream_chat_flutter/src/stream_channel.dart';
Expand All @@ -18,6 +20,7 @@ class MessageActionsModal extends StatelessWidget {
final MessageTheme messageTheme;
final bool showReactions;
final bool showDeleteMessage;
final bool showCopyMessage;
final bool showEditMessage;
final bool showReply;
final bool reverse;
Expand All @@ -27,19 +30,19 @@ class MessageActionsModal extends StatelessWidget {
Key key,
@required this.message,
@required this.messageTheme,
this.showReactions,
this.showDeleteMessage,
this.showEditMessage,
this.showReactions = true,
this.showDeleteMessage = true,
this.showEditMessage = true,
this.onThreadTap,
this.showReply,
this.showCopyMessage = true,
this.showReply = true,
this.editMessageInputBuilder,
this.messageShape,
this.reverse,
this.reverse = false,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final channel = StreamChannel.of(context).channel;
return Stack(
children: [
Positioned.fill(
Expand Down Expand Up @@ -68,13 +71,13 @@ class MessageActionsModal extends StatelessWidget {
message.status == null))
Center(
child: ReactionPicker(
channel: channel,
message: message,
messageTheme: messageTheme,
),
),
AbsorbPointer(
child: MessageWidget(
key: Key('MessageWidget'),
reverse: reverse,
message: message,
messageTheme: messageTheme,
Expand Down Expand Up @@ -103,13 +106,14 @@ class MessageActionsModal extends StatelessWidget {
children: ListTile.divideTiles(
context: context,
tiles: [
if (showEditMessage) _buildEditMessage(context),
if (showReply &&
(message.status == MessageSendingStatus.SENT ||
message.status == null) &&
message.parentId == null)
_buildReplyButton(context),
if (showEditMessage) _buildEditMessage(context),
if (showDeleteMessage) _buildDeleteButton(context),
if (showCopyMessage) _buildCopyButton(context),
],
).toList(),
),
Expand Down Expand Up @@ -142,6 +146,23 @@ class MessageActionsModal extends StatelessWidget {
);
}

Widget _buildCopyButton(BuildContext context) {
return ListTile(
title: Text(
'Copy message',
style: Theme.of(context).textTheme.headline6,
),
leading: Icon(
StreamIcons.copy,
color: StreamChatTheme.of(context).primaryIconTheme.color,
),
onTap: () async {
await Clipboard.setData(ClipboardData(text: message.text));
Navigator.pop(context);
},
);
}

Widget _buildEditMessage(BuildContext context) {
return ListTile(
title: Text(
Expand Down Expand Up @@ -256,7 +277,7 @@ class MessageActionsModal extends StatelessWidget {
style: Theme.of(context).textTheme.headline6,
),
leading: Icon(
StreamIcons.Thread_Reply,
StreamIcons.sorting_up,
color: StreamChatTheme.of(context).primaryIconTheme.color,
),
onTap: () {
Expand Down
199 changes: 199 additions & 0 deletions lib/src/message_reactions_modal.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
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_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 reverse;
final bool showReactions;
final ShapeBorder messageShape;
final void Function(User) onUserAvatarTap;

const MessageReactionsModal({
Key key,
@required this.message,
@required this.messageTheme,
this.showReactions = true,
this.onThreadTap,
this.editMessageInputBuilder,
this.messageShape,
this.reverse = false,
this.onUserAvatarTap,
}) : super(key: key);

@override
Widget build(BuildContext context) {
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(
message: message,
messageTheme: messageTheme,
),
),
AbsorbPointer(
child: MessageWidget(
key: Key('MessageWidget'),
reverse: reverse,
message: message,
messageTheme: messageTheme,
showReactions: false,
showUsername: false,
showReplyIndicator: false,
showTimestamp: false,
showSendingIndicator: DisplayWidget.gone,
shape: messageShape,
),
),
SizedBox(
height: 16,
),
if (message.latestReactions?.isNotEmpty == true)
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,
),
],
);
}
}
Loading