refactor(ui): remove context from Commands and Mentions overlays

This commit is contained in:
Salvatore Giordano
2021-09-10 10:52:59 +02:00
parent 19472027cc
commit 377789c421
5 changed files with 61 additions and 49 deletions
@@ -110,12 +110,10 @@ class _OverlayBuilderState extends State<OverlayBuilder> {
}
void addToOverlay(OverlayEntry entry) async {
print('addToOverlay');
Overlay.of(context)?.insert(entry);
}
void hideOverlay() {
print('hideOverlay');
overlayEntry?.remove();
overlayEntry = null;
}
@@ -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<Command> 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)),
@@ -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
@@ -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<User?> 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<List<Member>>? 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,
),
@@ -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<MessageInput> {
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<MessageInput> {
.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() {