feat: wip message input
This commit is contained in:
+80
-124
@@ -202,7 +202,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
Flex _buildTextField(BuildContext context) {
|
Flex _buildTextField(BuildContext context) {
|
||||||
return Flex(
|
return Flex(
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (!widget.disableAttachments) _buildAttachmentButton(),
|
if (!widget.disableAttachments) _buildAttachmentButton(),
|
||||||
if (widget.actionsLocation == ActionsLocation.left)
|
if (widget.actionsLocation == ActionsLocation.left)
|
||||||
@@ -222,7 +222,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
? CrossFadeState.showFirst
|
? CrossFadeState.showFirst
|
||||||
: CrossFadeState.showSecond,
|
: CrossFadeState.showSecond,
|
||||||
firstChild: _buildSendButton(context),
|
firstChild: _buildSendButton(context),
|
||||||
secondChild: _buildIdleSendButton(context),
|
secondChild: SizedBox(),
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
);
|
);
|
||||||
@@ -230,64 +230,60 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Expanded _buildTextInput(BuildContext context) {
|
Expanded _buildTextInput(BuildContext context) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Center(
|
child: LimitedBox(
|
||||||
child: LimitedBox(
|
maxHeight: widget.maxHeight,
|
||||||
maxHeight: widget.maxHeight,
|
child: TextField(
|
||||||
child: TextField(
|
key: Key('messageInputText'),
|
||||||
key: Key('messageInputText'),
|
enabled: _inputEnabled,
|
||||||
enabled: _inputEnabled,
|
minLines: null,
|
||||||
minLines: null,
|
maxLines: null,
|
||||||
maxLines: null,
|
onSubmitted: (_) {
|
||||||
onSubmitted: (_) {
|
sendMessage();
|
||||||
sendMessage();
|
},
|
||||||
},
|
keyboardType: widget.keyboardType,
|
||||||
keyboardType: widget.keyboardType,
|
controller: textEditingController,
|
||||||
controller: textEditingController,
|
focusNode: _focusNode,
|
||||||
focusNode: _focusNode,
|
onChanged: (s) {
|
||||||
onChanged: (s) {
|
StreamChannel.of(context).channel.keyStroke();
|
||||||
StreamChannel.of(context).channel.keyStroke();
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_messageIsPresent = s.trim().isNotEmpty;
|
_messageIsPresent = s.trim().isNotEmpty;
|
||||||
});
|
});
|
||||||
|
|
||||||
_commandsOverlay?.remove();
|
_commandsOverlay?.remove();
|
||||||
_commandsOverlay = null;
|
_commandsOverlay = null;
|
||||||
_mentionsOverlay?.remove();
|
_mentionsOverlay?.remove();
|
||||||
_mentionsOverlay = null;
|
_mentionsOverlay = null;
|
||||||
|
|
||||||
if (s.startsWith('/')) {
|
if (s.startsWith('/')) {
|
||||||
_commandsOverlay = _buildCommandsOverlayEntry();
|
_commandsOverlay = _buildCommandsOverlayEntry();
|
||||||
Overlay.of(context).insert(_commandsOverlay);
|
Overlay.of(context).insert(_commandsOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textEditingController.selection.isCollapsed &&
|
if (textEditingController.selection.isCollapsed &&
|
||||||
(s[textEditingController.selection.start - 1] == '@' ||
|
(s[textEditingController.selection.start - 1] == '@' ||
|
||||||
textEditingController.text
|
textEditingController.text
|
||||||
.substring(0, textEditingController.selection.start)
|
.substring(0, textEditingController.selection.start)
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.last
|
.last
|
||||||
.contains('@'))) {
|
.contains('@'))) {
|
||||||
_mentionsOverlay = _buildMentionsOverlayEntry();
|
_mentionsOverlay = _buildMentionsOverlayEntry();
|
||||||
Overlay.of(context).insert(_mentionsOverlay);
|
Overlay.of(context).insert(_mentionsOverlay);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_typingStarted = true;
|
_typingStarted = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
style: Theme.of(context).textTheme.bodyText2,
|
style: Theme.of(context).textTheme.bodyText2,
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Write a message',
|
hintText: 'Write a message',
|
||||||
prefixText: ' ',
|
prefixText: ' ',
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(),
|
||||||
borderRadius: BorderRadius.circular(32),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
textCapitalization: TextCapitalization.sentences,
|
|
||||||
),
|
),
|
||||||
|
textCapitalization: TextCapitalization.sentences,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -447,9 +443,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
leading: UserAvatar(
|
leading: UserAvatar(
|
||||||
user: m.user,
|
user: m.user,
|
||||||
),
|
),
|
||||||
title: Text('${m.user.name}', style: TextStyle(fontWeight: FontWeight.bold),),
|
title: Text('${m.user.name}'),
|
||||||
subtitle: Text('${m.userId}'),
|
|
||||||
trailing: Icon(Icons.alternate_email, color: StreamChatTheme.of(context).accentColor,),
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_mentionedUsers.add(m.user);
|
_mentionedUsers.add(m.user);
|
||||||
|
|
||||||
@@ -608,24 +602,22 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentButton() {
|
Material _buildAttachmentButton() {
|
||||||
return Center(
|
return Material(
|
||||||
child: Material(
|
clipBehavior: Clip.hardEdge,
|
||||||
clipBehavior: Clip.hardEdge,
|
shape: RoundedRectangleBorder(
|
||||||
shape: RoundedRectangleBorder(
|
borderRadius: BorderRadius.circular(32),
|
||||||
borderRadius: BorderRadius.circular(32),
|
),
|
||||||
),
|
color: Colors.transparent,
|
||||||
color: Colors.transparent,
|
child: IconButton(
|
||||||
child: IconButton(
|
onPressed: () {
|
||||||
onPressed: () {
|
showAttachmentModal();
|
||||||
showAttachmentModal();
|
},
|
||||||
},
|
icon: Transform.rotate(
|
||||||
icon: Transform.rotate(
|
child: Icon(
|
||||||
child: Icon(
|
Icons.attach_file_sharp,
|
||||||
Icons.attach_file_sharp,
|
|
||||||
),
|
|
||||||
angle: 0.4,
|
|
||||||
),
|
),
|
||||||
|
angle: - 0.3,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -843,60 +835,24 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
return res.file;
|
return res.file;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIdleSendButton(BuildContext context) {
|
|
||||||
return IconTheme(
|
|
||||||
data:
|
|
||||||
StreamChatTheme.of(context).channelTheme.messageInputButtonIconTheme,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Center(
|
|
||||||
child: Material(
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(32),
|
|
||||||
),
|
|
||||||
color: Colors.grey,
|
|
||||||
child: IconButton(
|
|
||||||
key: Key('sendButton'),
|
|
||||||
onPressed: () {
|
|
||||||
sendMessage();
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.arrow_forward,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 16.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildSendButton(BuildContext context) {
|
Widget _buildSendButton(BuildContext context) {
|
||||||
return IconTheme(
|
return IconTheme(
|
||||||
data:
|
data:
|
||||||
StreamChatTheme.of(context).channelTheme.messageInputButtonIconTheme,
|
StreamChatTheme.of(context).channelTheme.messageInputButtonIconTheme,
|
||||||
child: Center(
|
child: Material(
|
||||||
child: Padding(
|
clipBehavior: Clip.hardEdge,
|
||||||
padding: const EdgeInsets.all(8.0),
|
shape: RoundedRectangleBorder(
|
||||||
child: Material(
|
borderRadius: BorderRadius.circular(32),
|
||||||
clipBehavior: Clip.hardEdge,
|
),
|
||||||
shape: RoundedRectangleBorder(
|
color: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(32),
|
child: IconButton(
|
||||||
),
|
key: Key('sendButton'),
|
||||||
|
onPressed: () {
|
||||||
|
sendMessage();
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.send,
|
||||||
color: StreamChatTheme.of(context).accentColor,
|
color: StreamChatTheme.of(context).accentColor,
|
||||||
child: IconButton(
|
|
||||||
key: Key('sendButton'),
|
|
||||||
onPressed: () {
|
|
||||||
sendMessage();
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.arrow_upward,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 16.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user