fix: message input (#382)
* feat: Added mentions suffix builder * feat: Added builders for mentions and theme element for message input expanded button * refactor: refactored PR to suit other style * fix: fixes trailing commas and changes names * doc: added documentation to new elements * doc: added documentation to new elements
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../stream_chat_flutter.dart';
|
||||||
|
|
||||||
|
/// This widget is used for showing user tiles for mentions
|
||||||
|
/// Use [title], [subtitle], [leading], [trailing] for substituting widgets in respective positions
|
||||||
|
class MentionTile extends StatelessWidget {
|
||||||
|
/// Member to display in the tile
|
||||||
|
final Member member;
|
||||||
|
|
||||||
|
/// Widget to display as title
|
||||||
|
final Widget title;
|
||||||
|
|
||||||
|
/// Widget to display below [title]
|
||||||
|
final Widget subtitle;
|
||||||
|
|
||||||
|
/// Widget at the start of the tile
|
||||||
|
final Widget leading;
|
||||||
|
|
||||||
|
/// Widget at the end of tile
|
||||||
|
final Widget trailing;
|
||||||
|
|
||||||
|
MentionTile(
|
||||||
|
this.member, {
|
||||||
|
this.title,
|
||||||
|
this.subtitle,
|
||||||
|
this.leading,
|
||||||
|
this.trailing,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: 56.0,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 16.0,
|
||||||
|
),
|
||||||
|
leading ??
|
||||||
|
UserAvatar(
|
||||||
|
constraints: BoxConstraints.tight(
|
||||||
|
Size(
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
user: member.user,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 8.0,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
title ??
|
||||||
|
Text(
|
||||||
|
'${member.user.name}',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: StreamChatTheme.of(context).textTheme.bodyBold,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 2.0,
|
||||||
|
),
|
||||||
|
subtitle ??
|
||||||
|
Text(
|
||||||
|
'@${member.userId}',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: StreamChatTheme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.footnoteBold
|
||||||
|
.copyWith(
|
||||||
|
color:
|
||||||
|
StreamChatTheme.of(context).colorTheme.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing ??
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 18.0, left: 8.0),
|
||||||
|
child: StreamSvgIcon.mentions(
|
||||||
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,6 @@ import 'package:stream_chat_flutter/src/media_list_view.dart';
|
|||||||
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
||||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
|
||||||
import 'package:stream_chat_flutter/src/video_service.dart';
|
import 'package:stream_chat_flutter/src/video_service.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
import 'package:substring_highlight/substring_highlight.dart';
|
import 'package:substring_highlight/substring_highlight.dart';
|
||||||
@@ -32,6 +31,13 @@ typedef AttachmentThumbnailBuilder = Widget Function(
|
|||||||
Attachment,
|
Attachment,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Builder function for building a mention tile
|
||||||
|
/// Use [MentionTile] for the default implementation
|
||||||
|
typedef MentionTileBuilder = Widget Function(
|
||||||
|
BuildContext context,
|
||||||
|
Member member,
|
||||||
|
);
|
||||||
|
|
||||||
enum ActionsLocation {
|
enum ActionsLocation {
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
@@ -125,6 +131,7 @@ class MessageInput extends StatefulWidget {
|
|||||||
this.idleSendButton,
|
this.idleSendButton,
|
||||||
this.activeSendButton,
|
this.activeSendButton,
|
||||||
this.showCommandsButton = true,
|
this.showCommandsButton = true,
|
||||||
|
this.mentionsTileBuilder,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// Message to edit
|
/// Message to edit
|
||||||
@@ -191,6 +198,9 @@ class MessageInput extends StatefulWidget {
|
|||||||
/// Send button widget in an active state
|
/// Send button widget in an active state
|
||||||
final Widget activeSendButton;
|
final Widget activeSendButton;
|
||||||
|
|
||||||
|
/// Customize the tile for the mentions overlay
|
||||||
|
final MentionTileBuilder mentionsTileBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MessageInputState createState() => MessageInputState();
|
MessageInputState createState() => MessageInputState();
|
||||||
|
|
||||||
@@ -458,7 +468,9 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
? pi
|
? pi
|
||||||
: 0,
|
: 0,
|
||||||
child: StreamSvgIcon.emptyCircleLeft(
|
child: StreamSvgIcon.emptyCircleLeft(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
color: StreamChatTheme.of(context)
|
||||||
|
.messageInputTheme
|
||||||
|
.expandButtonColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
@@ -1314,80 +1326,9 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
_mentionsOverlay?.remove();
|
_mentionsOverlay?.remove();
|
||||||
_mentionsOverlay = null;
|
_mentionsOverlay = null;
|
||||||
},
|
},
|
||||||
child: Container(
|
child: widget.mentionsTileBuilder != null
|
||||||
height: 56.0,
|
? widget.mentionsTileBuilder(context, m)
|
||||||
child: Row(
|
: MentionTile(m),
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 16.0,
|
|
||||||
),
|
|
||||||
UserAvatar(
|
|
||||||
constraints: BoxConstraints.tight(
|
|
||||||
Size(
|
|
||||||
40,
|
|
||||||
40,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
user: m.user,
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 8.0,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'${m.user.name}',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow:
|
|
||||||
TextOverflow.ellipsis,
|
|
||||||
style: StreamChatTheme.of(
|
|
||||||
context)
|
|
||||||
.textTheme
|
|
||||||
.bodyBold,
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 2.0,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'@${m.userId}',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow:
|
|
||||||
TextOverflow.ellipsis,
|
|
||||||
style: StreamChatTheme.of(
|
|
||||||
context)
|
|
||||||
.textTheme
|
|
||||||
.footnoteBold
|
|
||||||
.copyWith(
|
|
||||||
color: StreamChatTheme
|
|
||||||
.of(context)
|
|
||||||
.colorTheme
|
|
||||||
.grey),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
right: 18.0, left: 8.0),
|
|
||||||
child: StreamSvgIcon.mentions(
|
|
||||||
color: StreamChatTheme.of(context)
|
|
||||||
.colorTheme
|
|
||||||
.accentBlue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -231,10 +231,10 @@ class MessageListView extends StatefulWidget {
|
|||||||
/// Called when system message is tapped
|
/// Called when system message is tapped
|
||||||
final OnMessageTap onSystemMessageTap;
|
final OnMessageTap onSystemMessageTap;
|
||||||
|
|
||||||
// Customize onTap on attachment
|
/// Customize onTap on attachment
|
||||||
final void Function(Message message, Attachment attachment) onAttachmentTap;
|
final void Function(Message message, Attachment attachment) onAttachmentTap;
|
||||||
|
|
||||||
// Customize the MessageWidget textBuilder
|
/// Customize the MessageWidget textBuilder
|
||||||
final void Function(BuildContext context, Message message) textBuilder;
|
final void Function(BuildContext context, Message message) textBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ class StreamChatThemeData {
|
|||||||
sendAnimationDuration: Duration(milliseconds: 300),
|
sendAnimationDuration: Duration(milliseconds: 300),
|
||||||
actionButtonColor: colorTheme.accentBlue,
|
actionButtonColor: colorTheme.accentBlue,
|
||||||
actionButtonIdleColor: colorTheme.grey,
|
actionButtonIdleColor: colorTheme.grey,
|
||||||
|
expandButtonColor: colorTheme.accentBlue,
|
||||||
sendButtonColor: colorTheme.accentBlue,
|
sendButtonColor: colorTheme.accentBlue,
|
||||||
sendButtonIdleColor: colorTheme.greyGainsboro,
|
sendButtonIdleColor: colorTheme.greyGainsboro,
|
||||||
inputBackground: colorTheme.white,
|
inputBackground: colorTheme.white,
|
||||||
@@ -935,6 +936,9 @@ class MessageInputTheme {
|
|||||||
/// Background color of [MessageInput] action buttons
|
/// Background color of [MessageInput] action buttons
|
||||||
final Color actionButtonIdleColor;
|
final Color actionButtonIdleColor;
|
||||||
|
|
||||||
|
/// Background color of [MessageInput] expand button
|
||||||
|
final Color expandButtonColor;
|
||||||
|
|
||||||
/// Background color of [MessageInput]
|
/// Background color of [MessageInput]
|
||||||
final Color inputBackground;
|
final Color inputBackground;
|
||||||
|
|
||||||
@@ -966,6 +970,7 @@ class MessageInputTheme {
|
|||||||
this.activeBorderGradient,
|
this.activeBorderGradient,
|
||||||
this.idleBorderGradient,
|
this.idleBorderGradient,
|
||||||
this.borderRadius,
|
this.borderRadius,
|
||||||
|
this.expandButtonColor,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Returns a new [MessageInputTheme] replacing some of its properties
|
/// Returns a new [MessageInputTheme] replacing some of its properties
|
||||||
@@ -976,6 +981,7 @@ class MessageInputTheme {
|
|||||||
Color sendButtonColor,
|
Color sendButtonColor,
|
||||||
Color actionButtonIdleColor,
|
Color actionButtonIdleColor,
|
||||||
Color sendButtonIdleColor,
|
Color sendButtonIdleColor,
|
||||||
|
Color expandButtonColor,
|
||||||
TextStyle inputTextStyle,
|
TextStyle inputTextStyle,
|
||||||
InputDecoration inputDecoration,
|
InputDecoration inputDecoration,
|
||||||
Gradient activeBorderGradient,
|
Gradient activeBorderGradient,
|
||||||
@@ -990,6 +996,7 @@ class MessageInputTheme {
|
|||||||
sendButtonColor: sendButtonColor ?? this.sendButtonColor,
|
sendButtonColor: sendButtonColor ?? this.sendButtonColor,
|
||||||
actionButtonIdleColor:
|
actionButtonIdleColor:
|
||||||
actionButtonIdleColor ?? this.actionButtonIdleColor,
|
actionButtonIdleColor ?? this.actionButtonIdleColor,
|
||||||
|
expandButtonColor: expandButtonColor ?? this.expandButtonColor,
|
||||||
inputTextStyle: inputTextStyle ?? this.inputTextStyle,
|
inputTextStyle: inputTextStyle ?? this.inputTextStyle,
|
||||||
sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor,
|
sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor,
|
||||||
inputDecoration: inputDecoration ?? this.inputDecoration,
|
inputDecoration: inputDecoration ?? this.inputDecoration,
|
||||||
@@ -1014,6 +1021,7 @@ class MessageInputTheme {
|
|||||||
activeBorderGradient: other.activeBorderGradient,
|
activeBorderGradient: other.activeBorderGradient,
|
||||||
idleBorderGradient: other.idleBorderGradient,
|
idleBorderGradient: other.idleBorderGradient,
|
||||||
borderRadius: other.borderRadius,
|
borderRadius: other.borderRadius,
|
||||||
|
expandButtonColor: other.expandButtonColor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,4 +39,5 @@ export 'src/channel_media_display_screen.dart';
|
|||||||
export 'src/info_tile.dart';
|
export 'src/info_tile.dart';
|
||||||
export 'src/stream_chat.dart';
|
export 'src/stream_chat.dart';
|
||||||
export 'src/connection_status_builder.dart';
|
export 'src/connection_status_builder.dart';
|
||||||
|
export 'src/mention_tile.dart';
|
||||||
export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user