From 91600f72a79002dee87ca82f1ce22b21f26895f8 Mon Sep 17 00:00:00 2001 From: Alex Demchenko Date: Tue, 15 Jun 2021 01:15:30 +0200 Subject: [PATCH] Add shortcuts --- CHANGELOG.md | 4 ++ lib/src/widgets/input.dart | 130 ++++++++++++++++++++++++------------- pubspec.yaml | 2 +- 3 files changed, 91 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8ad5c..6339c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.3 + +- [WEB] Add shortcuts to send messages on `enter` press + ## 1.1.2 - The text inside text messages is now selectable. Thanks @AndreHaueisen for the PR! diff --git a/lib/src/widgets/input.dart b/lib/src/widgets/input.dart index 85b7989..02a875a 100644 --- a/lib/src/widgets/input.dart +++ b/lib/src/widgets/input.dart @@ -1,10 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_chat_types/flutter_chat_types.dart' as types; import 'attachment_button.dart'; import 'inherited_chat_theme.dart'; import 'inherited_l10n.dart'; import 'send_button.dart'; +class NewLineIntent extends Intent { + const NewLineIntent(); +} + +class SendMessageIntent extends Intent { + const SendMessageIntent(); +} + /// A class that represents bottom bar widget with a text field, attachment and /// send buttons inside. Hides send button when text field is empty. class Input extends StatefulWidget { @@ -88,55 +97,88 @@ class _InputState extends State { return GestureDetector( onTap: () => _inputFocusNode.requestFocus(), - child: Material( - borderRadius: InheritedChatTheme.of(context).theme.inputBorderRadius, - color: InheritedChatTheme.of(context).theme.inputBackgroundColor, - child: Container( - padding: EdgeInsets.fromLTRB( - 24 + _query.padding.left, - 20, - 24 + _query.padding.right, - 20 + _query.viewInsets.bottom + _query.padding.bottom, - ), - child: Row( - children: [ - if (widget.onAttachmentPressed != null) _leftWidget(), - Expanded( - child: TextField( - controller: _textController, - decoration: InputDecoration.collapsed( - hintStyle: InheritedChatTheme.of(context) - .theme - .inputTextStyle - .copyWith( - color: InheritedChatTheme.of(context) + child: Shortcuts( + shortcuts: { + LogicalKeySet(LogicalKeyboardKey.enter): const SendMessageIntent(), + LogicalKeySet(LogicalKeyboardKey.enter, LogicalKeyboardKey.alt): + const NewLineIntent(), + LogicalKeySet(LogicalKeyboardKey.enter, LogicalKeyboardKey.shift): + const NewLineIntent(), + }, + child: Actions( + actions: { + SendMessageIntent: CallbackAction( + onInvoke: (SendMessageIntent intent) => _handleSendPressed(), + ), + NewLineIntent: CallbackAction( + onInvoke: (NewLineIntent intent) { + final _newValue = '${_textController.text}\r\n'; + _textController.value = TextEditingValue( + text: _newValue, + selection: TextSelection.fromPosition( + TextPosition(offset: _newValue.length), + ), + ); + }, + ), + }, + child: Focus( + autofocus: true, + child: Material( + borderRadius: + InheritedChatTheme.of(context).theme.inputBorderRadius, + color: InheritedChatTheme.of(context).theme.inputBackgroundColor, + child: Container( + padding: EdgeInsets.fromLTRB( + 24 + _query.padding.left, + 20, + 24 + _query.padding.right, + 20 + _query.viewInsets.bottom + _query.padding.bottom, + ), + child: Row( + children: [ + if (widget.onAttachmentPressed != null) _leftWidget(), + Expanded( + child: TextField( + controller: _textController, + decoration: InputDecoration.collapsed( + hintStyle: InheritedChatTheme.of(context) .theme - .inputTextColor - .withOpacity(0.5), + .inputTextStyle + .copyWith( + color: InheritedChatTheme.of(context) + .theme + .inputTextColor + .withOpacity(0.5), + ), + hintText: + InheritedL10n.of(context).l10n.inputPlaceholder, ), - hintText: InheritedL10n.of(context).l10n.inputPlaceholder, - ), - focusNode: _inputFocusNode, - keyboardType: TextInputType.multiline, - maxLines: 5, - minLines: 1, - style: InheritedChatTheme.of(context) - .theme - .inputTextStyle - .copyWith( - color: - InheritedChatTheme.of(context).theme.inputTextColor, + focusNode: _inputFocusNode, + keyboardType: TextInputType.multiline, + maxLines: 5, + minLines: 1, + style: InheritedChatTheme.of(context) + .theme + .inputTextStyle + .copyWith( + color: InheritedChatTheme.of(context) + .theme + .inputTextColor, + ), + textCapitalization: TextCapitalization.sentences, ), - textCapitalization: TextCapitalization.sentences, - ), - ), - Visibility( - visible: _sendButtonVisible, - child: SendButton( - onPressed: _handleSendPressed, + ), + Visibility( + visible: _sendButtonVisible, + child: SendButton( + onPressed: _handleSendPressed, + ), + ), + ], ), ), - ], + ), ), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index c83406c..566f221 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_chat_ui description: > Actively maintained, community-driven chat UI implementation with an optional Firebase BaaS. -version: 1.1.2 +version: 1.1.3 homepage: https://flyer.chat repository: https://github.com/flyerhq/flutter_chat_ui