From 3f75c565cad6cf84ff8a99f4660004ba333bf88d Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 25 Apr 2019 09:48:52 +0200 Subject: [PATCH] Send message --- lib/helpers/conversations_helper.dart | 22 ++++ lib/models/new_conversation_message.dart | 17 +++ lib/ui/screens/conversation_screen.dart | 126 +++++++++++++++++++++-- 3 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 lib/models/new_conversation_message.dart diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index d9a2bc6..4e57837 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -6,12 +6,15 @@ import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/conversation_message.dart'; +import 'package:comunic/models/new_conversation_message.dart'; import 'package:comunic/utils/account_utils.dart'; /// Conversation helper /// /// @author Pierre HUBERT +enum SendMessageResult { SUCCESS, MESSAGE_REJECTED, FAILED } + class ConversationsHelper { final ConversationsDatabaseHelper _conversationsDatabaseHelper = ConversationsDatabaseHelper(); @@ -156,4 +159,23 @@ class ConversationsHelper { return list; } + + /// Send a new message to the server + Future sendMessage(NewConversationMessage message) async { + final response = await APIRequest( + uri: "conversations/sendMessage", + needLogin: true, + args: { + "conversationID": message.conversationID.toString(), + "message": message.message + }, + ).exec(); + + if(response.code == 401) + return SendMessageResult.MESSAGE_REJECTED; + else if(response.code != 200) + return SendMessageResult.FAILED; + + return SendMessageResult.SUCCESS; + } } diff --git a/lib/models/new_conversation_message.dart b/lib/models/new_conversation_message.dart new file mode 100644 index 0000000..8b3f04a --- /dev/null +++ b/lib/models/new_conversation_message.dart @@ -0,0 +1,17 @@ +import 'package:meta/meta.dart'; + +/// New conversation message model +/// +/// This model is used to transfer a conversation message to send in the application +/// +/// @author Pierre HUBERT + +class NewConversationMessage { + final int conversationID; + final String message; + + NewConversationMessage({ + @required this.conversationID, + @required this.message, + }) : assert(conversationID != null); +} diff --git a/lib/ui/screens/conversation_screen.dart b/lib/ui/screens/conversation_screen.dart index e97a1e8..de90f12 100644 --- a/lib/ui/screens/conversation_screen.dart +++ b/lib/ui/screens/conversation_screen.dart @@ -2,6 +2,7 @@ import 'package:comunic/helpers/conversations_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/conversation_messages_list.dart'; import 'package:comunic/lists/users_list.dart'; +import 'package:comunic/models/new_conversation_message.dart'; import 'package:comunic/ui/tiles/conversation_message_tile.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/list_utils.dart'; @@ -26,11 +27,17 @@ class ConversationScreen extends StatefulWidget { } class _ConversationScreenState extends State { + //Helpers final ConversationsHelper _conversationsHelper = ConversationsHelper(); final UsersHelper _usersHelper = UsersHelper(); + + // Class members ConversationMessagesList _messages; UsersList _usersInfo = UsersList(); ErrorLevel _error = ErrorLevel.NONE; + bool _isMessageValid = false; + bool _isSendingMessage = false; + TextEditingController _textEditingController = TextEditingController(); @override void didChangeDependencies() { @@ -40,6 +47,8 @@ class _ConversationScreenState extends State { void _setError(ErrorLevel err) => setState(() => _error = err); + void _setSending(bool sending) => setState(() => _isSendingMessage = sending); + /// Method called when an error occurred while loading messages void _errorLoading() { _setError(_messages == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR); @@ -68,6 +77,41 @@ class _ConversationScreenState extends State { _messages = messages; else _messages.addAll(messages); + + _messages.sort(); + }); + } + + /// Send a new message + Future _submitMessage(BuildContext context, String content) async { + //Send the message + _setSending(true); + final result = await _conversationsHelper.sendMessage( + NewConversationMessage( + conversationID: widget.conversationID, message: content)); + _setSending(false); + + //Check the result of the operation + if (result == SendMessageResult.SUCCESS) + _clearSendMessageForm(); + else + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + result == SendMessageResult.MESSAGE_REJECTED + ? tr("Message rejected by the server!") + : tr("Could not send message!"), + ), + duration: Duration(milliseconds: 500), + ), + ); + } + + /// Clear send message form + void _clearSendMessageForm() { + setState(() { + _textEditingController = TextEditingController(); + _isMessageValid = false; }); } @@ -76,19 +120,85 @@ class _ConversationScreenState extends State { return buildErrorCard(tr("Could not load the list of messages!")); } + /// Messages list + Widget _buildMessagesList() { + return Expanded( + child: ListView.builder( + itemCount: _messages.length, + itemBuilder: (c, i) { + return ConversationMessageTile( + message: _messages.elementAt(i), + userInfo: _usersInfo.getUser(_messages[i].userID), + ); + }), + ); + } + + /// Send message from + Widget _buildSendMessageForm() { + return new Container( + margin: const EdgeInsets.symmetric(horizontal: 8.0), + child: new Row( + children: [ + // Image area + /*new Container( + margin: new EdgeInsets.symmetric(horizontal: 4.0), + child: new IconButton( + icon: new Icon( + Icons.photo_camera, + color: Theme.of(context).accentColor, + ), + onPressed: () async {}), + ),*/ + + // Message area + new Flexible( + child: new TextField( + controller: _textEditingController, + onChanged: (String messageText) { + setState(() { + _isMessageValid = messageText.length > 4; + }); + }, + onSubmitted: + _isMessageValid ? (s) => _submitMessage(context, s) : null, + decoration: + new InputDecoration.collapsed(hintText: tr("Send a message")), + ), + ), + + // Send button + new Container( + margin: const EdgeInsets.symmetric(horizontal: 4.0), + child: new IconButton( + icon: new Icon( + Icons.send, + color: !_isSendingMessage && _isMessageValid + ? Theme.of(context).accentColor + : Theme.of(context).disabledColor, + ), + onPressed: !_isSendingMessage && _isMessageValid + ? () => _submitMessage(context, _textEditingController.text) + : null, + ), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { if (_error == ErrorLevel.MAJOR) return _buildError(); if (_messages == null) return buildCenteredProgressBar(); - return ListView.builder( - itemCount: _messages.length, - itemBuilder: (c, i) { - return ConversationMessageTile( - message: _messages.elementAt(i), - userInfo: _usersInfo.getUser(_messages[i].userID), - ); - }); + return Column( + children: [ + _buildMessagesList(), + Divider(), + _buildSendMessageForm() + ], + ); } }