diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index e848b8ff..07bb3fa8 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -14,6 +14,8 @@ PODS: - Reachability - path_provider (0.0.1): - Flutter + - path_provider_macos (0.0.1): + - Flutter - Reachability (3.2) - screen (0.0.1): - Flutter @@ -38,6 +40,7 @@ DEPENDENCIES: - image_picker (from `.symlinks/plugins/image_picker/ios`) - keyboard_visibility (from `.symlinks/plugins/keyboard_visibility/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) + - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) - screen (from `.symlinks/plugins/screen/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) @@ -64,6 +67,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/keyboard_visibility/ios" path_provider: :path: ".symlinks/plugins/path_provider/ios" + path_provider_macos: + :path: ".symlinks/plugins/path_provider_macos/ios" screen: :path: ".symlinks/plugins/screen/ios" sqflite: @@ -87,6 +92,7 @@ SPEC CHECKSUMS: image_picker: e3eacd46b94694dde7cf2705955cece853aa1a8f keyboard_visibility: 96a24de806fe6823c3ad956c01ba2ec6d056616f path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d + path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 diff --git a/example/lib/main.dart b/example/lib/main.dart index 15efe5e5..a28a4320 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,13 +3,13 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; void main() async { final client = Client( - 's2dxdhpxd94g', + 'b67pax5b2wdq', logLevel: Level.INFO, ); await client.setUser( User(id: 'falling-mountain-7'), - 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNDE5MjI5YTMtODRhMC00MDZiLTkzNzEtN2NlOWE0ZTBhNjc2In0.J3SjGH4e4v7b3cg5EgWkljTxXj_HeHpCWn5ujEVv_H8', + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZmFsbGluZy1tb3VudGFpbi03In0.AKgRXHMQQMz6vJAKszXdY8zMFfsAgkoUeZHlI-Szz9E', ); runApp(MyApp(client)); @@ -38,11 +38,11 @@ class ChannelListPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( body: ChannelListView( -// filter: { -// 'members': { -// '\$in': [StreamChat.of(context).user.id], -// } -// }, + filter: { + 'members': { + '\$in': [StreamChat.of(context).user.id], + } + }, sort: [SortOption('last_message_at')], pagination: PaginationParams( limit: 20, diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index 92664339..8174c290 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -89,7 +89,7 @@ class ChannelPreview extends StatelessWidget { initialData: channel.state.typingEvents, builder: (context, snapshot) { final typings = snapshot.data; - final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5; + final opacity = channel.state.unreadCount > 0 ? 1.0 : 0.5; return typings.isNotEmpty ? _buildTypings(typings, context, opacity) : _buildLastMessage(context, opacity); diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 79c9f55f..8df9670c 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -118,10 +118,6 @@ class _MessageInputState extends State { } AnimatedCrossFade _animateSendButton(BuildContext context) { - print( - '_messageIsPresent || _attachments.isNotEmpty: ${_messageIsPresent || _attachments.isNotEmpty}'); - print('_attachments.isNotEmpty: ${_attachments.isNotEmpty}'); - print('_messageIsPresent: ${_messageIsPresent}'); return AnimatedCrossFade( crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) ? CrossFadeState.showFirst @@ -214,46 +210,58 @@ class _MessageInputState extends State { RenderBox renderBox = context.findRenderObject(); final size = renderBox.size; - final offset = renderBox.localToGlobal(Offset.zero); - return OverlayEntry(builder: (_) { + return OverlayEntry(builder: (context) { return Positioned( - top: offset.dy - size.height, + bottom: size.height + MediaQuery.of(context).viewInsets.bottom, left: 0, right: 0, child: Material( color: StreamChatTheme.of(context).primaryColor, - child: Flex( - mainAxisSize: MainAxisSize.min, - direction: Axis.vertical, - children: [ - ListView( - padding: const EdgeInsets.all(0), - shrinkWrap: true, - children: commands - .map((c) => ListTile( - title: Text.rich( - TextSpan( - text: '${c.name}', - style: TextStyle(fontWeight: FontWeight.bold), - children: [ - TextSpan( - text: ' ${c.args}', - style: TextStyle( - fontWeight: FontWeight.w300, + child: Container( + constraints: BoxConstraints.loose(Size.fromHeight(400)), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + spreadRadius: -8, + blurRadius: 5.0, + offset: Offset(0, -4), + ), + ], + color: StreamChatTheme.of(context).primaryColor, + ), + child: Flex( + mainAxisSize: MainAxisSize.min, + direction: Axis.vertical, + children: [ + ListView( + padding: const EdgeInsets.all(0), + shrinkWrap: true, + children: commands + .map((c) => ListTile( + title: Text.rich( + TextSpan( + text: '${c.name}', + style: TextStyle(fontWeight: FontWeight.bold), + children: [ + TextSpan( + text: ' ${c.args}', + style: TextStyle( + fontWeight: FontWeight.w300, + ), ), - ), - ], + ], + ), ), - ), - subtitle: Text(c.description), - onTap: () { - _setCommand(c); - }, - )) - .toList(), - ), - ], + subtitle: Text(c.description), + onTap: () { + _setCommand(c); + }, + )) + .toList(), + ), + ], + ), ), ), ); @@ -388,71 +396,7 @@ class _MessageInputState extends State { color: Colors.transparent, child: IconButton( onPressed: () { - showModalBottomSheet( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(32), - topRight: Radius.circular(32), - ), - ), - context: context, - builder: (_) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - title: Text( - 'Add a file', - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - ), - ListTile( - leading: Icon(Icons.image), - title: Text('Upload a photo'), - onTap: () { - _pickFile(FileType.IMAGE, false); - Navigator.pop(context); - }, - ), - ListTile( - leading: Icon(Icons.video_library), - title: Text('Upload a video'), - onTap: () { - _pickFile(FileType.VIDEO, false); - Navigator.pop(context); - }, - ), - ListTile( - leading: Icon(Icons.camera_alt), - title: Text('Photo from camera'), - onTap: () { - ImagePicker.pickImage(source: ImageSource.camera); - _pickFile(FileType.IMAGE, true); - Navigator.pop(context); - }, - ), - ListTile( - leading: Icon(Icons.videocam), - title: Text('Video from camera'), - onTap: () { - _pickFile(FileType.VIDEO, true); - Navigator.pop(context); - }, - ), - ListTile( - leading: Icon(Icons.insert_drive_file), - title: Text('Upload a file'), - onTap: () { - _pickFile(FileType.ANY, false); - Navigator.pop(context); - }, - ), - ], - ); - }); + _showAttachmentModal(); }, icon: Icon( Icons.add_circle_outline, @@ -461,6 +405,74 @@ class _MessageInputState extends State { ); } + void _showAttachmentModal() { + showModalBottomSheet( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(32), + topRight: Radius.circular(32), + ), + ), + context: context, + builder: (_) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + title: Text( + 'Add a file', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + ListTile( + leading: Icon(Icons.image), + title: Text('Upload a photo'), + onTap: () { + _pickFile(FileType.IMAGE, false); + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.video_library), + title: Text('Upload a video'), + onTap: () { + _pickFile(FileType.VIDEO, false); + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.camera_alt), + title: Text('Photo from camera'), + onTap: () { + ImagePicker.pickImage(source: ImageSource.camera); + _pickFile(FileType.IMAGE, true); + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.videocam), + title: Text('Video from camera'), + onTap: () { + _pickFile(FileType.VIDEO, true); + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.insert_drive_file), + title: Text('Upload a file'), + onTap: () { + _pickFile(FileType.ANY, false); + Navigator.pop(context); + }, + ), + ], + ); + }); + } + void _pickFile(FileType type, bool camera) async { File file; @@ -599,21 +611,23 @@ class _MessageInputState extends State { void initState() { super.initState(); - _keyboardListener = - KeyboardVisibilityNotification().addNewListener(onHide: () { - if (_commandsOverlay != null) { - _commandsOverlay.remove(); - } - }, onShow: () { - if (_commandsOverlay != null) { - if (_textController.text.startsWith('/')) { - WidgetsBinding.instance.addPostFrameCallback((_) { - _commandsOverlay = _buildOverlayEntry(); - Overlay.of(context).insert(_commandsOverlay); - }); + _keyboardListener = KeyboardVisibilityNotification().addNewListener( + onHide: () { + if (_commandsOverlay != null) { + _commandsOverlay.remove(); } - } - }); + }, + onShow: () { + if (_commandsOverlay != null) { + if (_textController.text.startsWith('/')) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _commandsOverlay = _buildOverlayEntry(); + Overlay.of(context).insert(_commandsOverlay); + }); + } + } + }, + ); if (widget.editMessage != null) { _textController = TextEditingController(text: widget.editMessage.text); diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index b1f51ef0..7e81cd51 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -687,26 +687,25 @@ class _MessageWidgetState extends State } Row _buildReactionRow() { - final List children = - widget.message.reactionCounts.keys.map((reactionType) { - return Text( - reactionToEmoji[reactionType] ?? '?', - ) as Widget; - }).toList(); - - children.add(Padding( - padding: const EdgeInsets.only(left: 4.0), - child: Text( - widget.message.reactionCounts.values - .fold(0, (t, v) => v + t) - .toString(), - style: TextStyle(color: Colors.white), - ), - )); return Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, - children: children, + children: [ + ...widget.message.reactionCounts.keys.map((reactionType) { + return Text( + reactionToEmoji[reactionType] ?? '?', + ); + }), + Padding( + padding: const EdgeInsets.only(left: 4.0), + child: Text( + widget.message.reactionCounts.values + .fold(0, (t, v) => v + t) + .toString(), + style: TextStyle(color: Colors.white), + ), + ), + ], ); }