diff --git a/packages/stream_chat_flutter/lib/src/overlays.dart b/packages/stream_chat_flutter/lib/src/anchored_overlay.dart similarity index 98% rename from packages/stream_chat_flutter/lib/src/overlays.dart rename to packages/stream_chat_flutter/lib/src/anchored_overlay.dart index ce6a9a4e..d79e19df 100644 --- a/packages/stream_chat_flutter/lib/src/overlays.dart +++ b/packages/stream_chat_flutter/lib/src/anchored_overlay.dart @@ -110,12 +110,10 @@ class _OverlayBuilderState extends State { } void addToOverlay(OverlayEntry entry) async { - print('addToOverlay'); Overlay.of(context)?.insert(entry); } void hideOverlay() { - print('hideOverlay'); overlayEntry?.remove(); overlayEntry = null; } diff --git a/packages/stream_chat_flutter/lib/src/commands_overlay.dart b/packages/stream_chat_flutter/lib/src/commands_overlay.dart index aec35da9..ffaec928 100644 --- a/packages/stream_chat_flutter/lib/src/commands_overlay.dart +++ b/packages/stream_chat_flutter/lib/src/commands_overlay.dart @@ -1,33 +1,34 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/src/extension.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Overlay for displaying commands that can be used class CommandsOverlay extends StatelessWidget { /// Constructor for creating a [CommandsOverlay] - const CommandsOverlay( - this.context, { + const CommandsOverlay({ required this.text, required this.onCommandResult, + required this.size, + required this.channel, Key? key, }) : super(key: key); - /// Context of the upper tree - final BuildContext context; + /// The size of the overlay + final Size size; /// Query for searching commands final String text; + /// The channel to search for users + final Channel channel; + /// Callback called when a command is selected final ValueChanged onCommandResult; @override - Widget build(BuildContext otherContext) { + Widget build(BuildContext context) { final _streamChatTheme = StreamChatTheme.of(context); - final commands = StreamChannel.of(context) - .channel - .config - ?.commands + final commands = channel.config?.commands .where((c) => c.name.contains(text.replaceFirst('/', ''))) .toList() ?? []; @@ -36,8 +37,6 @@ class CommandsOverlay extends StatelessWidget { return const SizedBox(); } - final size = MediaQuery.of(context).size; - return Padding( padding: const EdgeInsets.all(4), child: Card( @@ -48,7 +47,7 @@ class CommandsOverlay extends StatelessWidget { color: _streamChatTheme.colorTheme.barsBg, clipBehavior: Clip.hardEdge, child: Container( - constraints: BoxConstraints.loose(Size(size.width - 16, 400)), + constraints: BoxConstraints.loose(size), decoration: BoxDecoration( color: _streamChatTheme.colorTheme.barsBg, borderRadius: BorderRadius.circular(8)), diff --git a/packages/stream_chat_flutter/lib/src/emoji_overlay.dart b/packages/stream_chat_flutter/lib/src/emoji_overlay.dart index 211b18b1..c37dd687 100644 --- a/packages/stream_chat_flutter/lib/src/emoji_overlay.dart +++ b/packages/stream_chat_flutter/lib/src/emoji_overlay.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/src/emoji/emoji.dart'; import 'package:stream_chat_flutter/src/extension.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:substring_highlight/substring_highlight.dart'; /// Overlay for displaying emoji that can be used diff --git a/packages/stream_chat_flutter/lib/src/mentions_overlay.dart b/packages/stream_chat_flutter/lib/src/mentions_overlay.dart index 823e920d..57d286d9 100644 --- a/packages/stream_chat_flutter/lib/src/mentions_overlay.dart +++ b/packages/stream_chat_flutter/lib/src/mentions_overlay.dart @@ -4,20 +4,24 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Overlay for displaying users that can be mentioned class MentionsOverlay extends StatelessWidget { /// Constructor for creating a [MentionsOverlay] - const MentionsOverlay( - this.context, { + const MentionsOverlay({ required this.query, required this.onMentionResult, + required this.size, + required this.channel, this.mentionsTileBuilder, Key? key, }) : super(key: key); - /// Context of the upper tree - final BuildContext context; + /// The size of the overlay + final Size size; /// Query for searching users final String query; + /// The channel to search for users + final Channel channel; + /// Callback called when a user is selected final ValueChanged onMentionResult; @@ -25,19 +29,18 @@ class MentionsOverlay extends StatelessWidget { final MentionTileBuilder? mentionsTileBuilder; @override - Widget build(BuildContext otherContext) { + Widget build(BuildContext context) { final _streamChatTheme = StreamChatTheme.of(context); Future>? queryMembers; - final channelState = StreamChannel.of(context); if (query.isNotEmpty) { - queryMembers = channelState.channel + queryMembers = channel .queryMembers(filter: Filter.autoComplete('name', query)) .then((res) => res.members); } - final members = channelState.channel.state?.members + final members = channel.state?.members .where((m) => m.user?.name.toLowerCase().contains(query) == true) .toList() ?? []; @@ -46,9 +49,6 @@ class MentionsOverlay extends StatelessWidget { return const SizedBox(); } - // ignore: cast_nullable_to_non_nullable - final renderBox = context.findRenderObject() as RenderBox; - final size = renderBox.size; final child = Card( margin: const EdgeInsets.all(8), elevation: 2, @@ -58,7 +58,7 @@ class MentionsOverlay extends StatelessWidget { ), clipBehavior: Clip.hardEdge, child: Container( - constraints: BoxConstraints.loose(Size(size.width - 16, 200)), + constraints: BoxConstraints.loose(size), decoration: BoxDecoration( color: _streamChatTheme.colorTheme.barsBg, ), diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 54cc7bae..a6795a9e 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -14,7 +14,7 @@ import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/commands_overlay.dart'; import 'package:stream_chat_flutter/src/emoji_overlay.dart'; import 'package:stream_chat_flutter/src/mentions_overlay.dart'; -import 'package:stream_chat_flutter/src/overlays.dart'; +import 'package:stream_chat_flutter/src/anchored_overlay.dart'; import 'package:stream_chat_flutter/src/emoji/emoji.dart'; import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/media_list_view.dart'; @@ -923,7 +923,14 @@ class MessageInputState extends State { Widget _buildCommandsOverlayEntry() { final text = textEditingController.text.trimLeft(); - return CommandsOverlay(context, text: text, onCommandResult: _setCommand); +// ignore: cast_nullable_to_non_nullable + final renderObject = context.findRenderObject() as RenderBox; + return CommandsOverlay( + channel: StreamChannel.of(context).channel, + size: Size(renderObject.size.width - 16, 400), + text: text, + onCommandResult: _setCommand, + ); } Widget _buildFilePickerSection() { @@ -1141,27 +1148,35 @@ class MessageInputState extends State { .split('@'); final query = splits.last.toLowerCase(); - return MentionsOverlay(context, query: query, onMentionResult: (user) { - if (user != null) { - _mentionedUsers.add(user); - } + // ignore: cast_nullable_to_non_nullable + final renderObject = context.findRenderObject() as RenderBox; - splits[splits.length - 1] = user!.name; - final rejoin = splits.join('@'); + return MentionsOverlay( + channel: StreamChannel.of(context).channel, + size: Size(renderObject.size.width - 16, 400), + query: query, + onMentionResult: (user) { + if (user != null) { + _mentionedUsers.add(user); + } - textEditingController.value = TextEditingValue( - text: rejoin + - textEditingController.text - .substring(textEditingController.selection.start), - selection: TextSelection.collapsed( - offset: rejoin.length, - ), - ); - _debounce!.cancel(); - setState(() { - _mentionsOverlay = null; - }); - }); + splits[splits.length - 1] = user!.name; + final rejoin = splits.join('@'); + + textEditingController.value = TextEditingValue( + text: rejoin + + textEditingController.text + .substring(textEditingController.selection.start), + selection: TextSelection.collapsed( + offset: rejoin.length, + ), + ); + _debounce!.cancel(); + setState(() { + _mentionsOverlay = null; + }); + }, + ); } Widget _buildEmojiOverlay() {