added new overlays and docs
This commit is contained in:
@@ -475,7 +475,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
_emojiOverlay != null ||
|
_emojiOverlay != null ||
|
||||||
_mentionsOverlay != null,
|
_mentionsOverlay != null,
|
||||||
overlayBuilder: (context, offset) {
|
overlayBuilder: (context, offset) {
|
||||||
late Widget child;
|
late Widget? child;
|
||||||
|
|
||||||
if (_commandsOverlay != null) {
|
if (_commandsOverlay != null) {
|
||||||
child = _buildCommandsOverlayEntry();
|
child = _buildCommandsOverlayEntry();
|
||||||
@@ -487,7 +487,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
return CenterAbout(
|
return CenterAbout(
|
||||||
position: Offset(offset.dx, offset.dy),
|
position: Offset(offset.dx, offset.dy),
|
||||||
child: child,
|
child: child ?? const SizedBox(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: child,
|
child: child,
|
||||||
@@ -922,7 +922,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCommandsOverlayEntry() {
|
Widget? _buildCommandsOverlayEntry() {
|
||||||
final text = textEditingController.text.trimLeft();
|
final text = textEditingController.text.trimLeft();
|
||||||
final commands = StreamChannel.of(context)
|
final commands = StreamChannel.of(context)
|
||||||
.channel
|
.channel
|
||||||
@@ -931,6 +931,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
.where((c) => c.name.contains(text.replaceFirst('/', '')))
|
.where((c) => c.name.contains(text.replaceFirst('/', '')))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
[];
|
[];
|
||||||
|
|
||||||
|
if (commands.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
@@ -1312,7 +1317,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMentionsOverlayEntry() {
|
Widget? _buildMentionsOverlayEntry() {
|
||||||
final splits = textEditingController.text
|
final splits = textEditingController.text
|
||||||
.substring(0, textEditingController.value.selection.start)
|
.substring(0, textEditingController.value.selection.start)
|
||||||
.split('@');
|
.split('@');
|
||||||
@@ -1332,6 +1337,10 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
.toList() ??
|
.toList() ??
|
||||||
[];
|
[];
|
||||||
|
|
||||||
|
if (members.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
final renderBox = context.findRenderObject() as RenderBox;
|
final renderBox = context.findRenderObject() as RenderBox;
|
||||||
final size = renderBox.size;
|
final size = renderBox.size;
|
||||||
@@ -1410,7 +1419,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEmojiOverlay() {
|
Widget? _buildEmojiOverlay() {
|
||||||
final splits = textEditingController.text
|
final splits = textEditingController.text
|
||||||
.substring(0, textEditingController.value.selection.start)
|
.substring(0, textEditingController.value.selection.start)
|
||||||
.split(':');
|
.split(':');
|
||||||
@@ -1421,6 +1430,10 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
.map(Emoji.byName)
|
.map(Emoji.byName)
|
||||||
.where((e) => e != null);
|
.where((e) => e != null);
|
||||||
|
|
||||||
|
if (emojis.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
final renderBox = context.findRenderObject() as RenderBox;
|
final renderBox = context.findRenderObject() as RenderBox;
|
||||||
final size = renderBox.size;
|
final size = renderBox.size;
|
||||||
|
|||||||
@@ -1,49 +1,66 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Class to create an overlay anchored to a child widget
|
||||||
class AnchoredOverlay extends StatelessWidget {
|
class AnchoredOverlay extends StatelessWidget {
|
||||||
final bool showOverlay;
|
/// Constructor for creating an [AnchoredOverlay]
|
||||||
final Widget Function(BuildContext, Offset anchor) overlayBuilder;
|
const AnchoredOverlay({
|
||||||
final Widget child;
|
Key? key,
|
||||||
|
|
||||||
AnchoredOverlay({
|
|
||||||
this.showOverlay = false,
|
this.showOverlay = false,
|
||||||
required this.overlayBuilder,
|
required this.overlayBuilder,
|
||||||
required this.child,
|
required this.child,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// Show or hide overlay
|
||||||
|
final bool showOverlay;
|
||||||
|
|
||||||
|
/// Builder for creating overlay widget
|
||||||
|
final Widget Function(BuildContext, Offset anchor) overlayBuilder;
|
||||||
|
|
||||||
|
/// Child to which overlay is anchored
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => SizedBox(
|
||||||
return new Container(
|
child: LayoutBuilder(
|
||||||
child: new LayoutBuilder(
|
builder: (BuildContext context, BoxConstraints constraints) =>
|
||||||
builder: (BuildContext context, BoxConstraints constraints) {
|
OverlayBuilder(
|
||||||
return new OverlayBuilder(
|
showOverlay: showOverlay,
|
||||||
showOverlay: showOverlay,
|
overlayBuilder: (BuildContext overlayContext) {
|
||||||
overlayBuilder: (BuildContext overlayContext) {
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
RenderBox box = context.findRenderObject() as RenderBox;
|
if (box != null) {
|
||||||
final center =
|
final center = box.size
|
||||||
box.size.center(box.localToGlobal(const Offset(0.0, 0.0)));
|
.center(box.localToGlobal(const Offset(0, 0)));
|
||||||
return overlayBuilder(overlayContext, center);
|
return overlayBuilder(overlayContext, center);
|
||||||
},
|
} else {
|
||||||
child: child,
|
return const SizedBox();
|
||||||
);
|
}
|
||||||
}),
|
},
|
||||||
);
|
child: child,
|
||||||
}
|
)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Class for creating a declarative-ish overlay
|
||||||
class OverlayBuilder extends StatefulWidget {
|
class OverlayBuilder extends StatefulWidget {
|
||||||
final bool showOverlay;
|
/// Constructor for creating an [OverlayBuilder]
|
||||||
final Widget Function(BuildContext) overlayBuilder;
|
const OverlayBuilder({
|
||||||
final Widget child;
|
Key? key,
|
||||||
|
|
||||||
OverlayBuilder({
|
|
||||||
this.showOverlay = false,
|
this.showOverlay = false,
|
||||||
required this.overlayBuilder,
|
required this.overlayBuilder,
|
||||||
required this.child,
|
required this.child,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// Show or hide overlay
|
||||||
|
final bool showOverlay;
|
||||||
|
|
||||||
|
/// Builder for creating overlay widget
|
||||||
|
final Widget Function(BuildContext) overlayBuilder;
|
||||||
|
|
||||||
|
/// Child to which overlay is anchored
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_OverlayBuilderState createState() => new _OverlayBuilderState();
|
_OverlayBuilderState createState() => _OverlayBuilderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OverlayBuilderState extends State<OverlayBuilder> {
|
class _OverlayBuilderState extends State<OverlayBuilder> {
|
||||||
@@ -112,31 +129,35 @@ class _OverlayBuilderState extends State<OverlayBuilder> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => widget.child;
|
||||||
return widget.child;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Class to position Overlay
|
||||||
class CenterAbout extends StatelessWidget {
|
class CenterAbout extends StatelessWidget {
|
||||||
final Offset position;
|
/// Constructor for creating an [CenterAbout]
|
||||||
final Widget child;
|
const CenterAbout({
|
||||||
|
Key? key,
|
||||||
CenterAbout({
|
|
||||||
required this.position,
|
required this.position,
|
||||||
required this.child,
|
required this.child,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// Position of child
|
||||||
|
final Offset position;
|
||||||
|
|
||||||
|
/// Child widget to which overlay is attached
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
return Positioned(
|
return Positioned(
|
||||||
bottom: size.height - position.dy,
|
bottom: size.height - position.dy,
|
||||||
left: position.dx,
|
left: position.dx,
|
||||||
child: FractionalTranslation(
|
child: FractionalTranslation(
|
||||||
translation: const Offset(-0.5, 0.0),
|
translation: const Offset(-0.5, 0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 32.0),
|
padding: const EdgeInsets.only(bottom: 32),
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user