diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index ab771b6..d95b692 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -58,8 +58,7 @@ class ConversationsHelper { final response = await request.exec(); - if(response.code != 200) - return false; + if (response.code != 200) return false; //Delete old conversation entry from the database await _conversationsDatabaseHelper.delete(settings.id); @@ -160,6 +159,30 @@ class ConversationsHelper { return name; } + /// Search and return a private conversation with a given [userID]. If such + /// conversation does not exists, it is created if [allowCreate] is set to + /// true + Future getPrivate(int userID, {bool allowCreate = true}) async { + final response = await APIRequest( + uri: "conversations/getPrivate", + needLogin: true, + args: { + "otherUser": userID.toString(), + "allowCreate": allowCreate.toString() + }, + ).exec(); + + if (response.code != 200) return null; + + // Get and return conversation ID + try { + return int.parse(response.getObject()["conversationsID"][0]); + } catch (e) { + e.toString(); + return null; + } + } + /// Asynchronously get the name fo the conversation /// /// Unlike the synchronous method, this method does not need information diff --git a/lib/ui/screens/friends_list_screen.dart b/lib/ui/screens/friends_list_screen.dart index 61f3632..239e927 100644 --- a/lib/ui/screens/friends_list_screen.dart +++ b/lib/ui/screens/friends_list_screen.dart @@ -6,6 +6,7 @@ import 'package:comunic/models/friend.dart'; import 'package:comunic/ui/tiles/accepted_friend_tile.dart'; import 'package:comunic/ui/tiles/pending_friend_tile.dart'; import 'package:comunic/ui/widgets/safe_state.dart'; +import 'package:comunic/utils/conversations_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; @@ -111,6 +112,7 @@ class _FriendsListScreenState extends SafeState { ? AcceptedFriendTile( friend: _friendsList[i], user: _usersInfo.getUser(_friendsList[i].id), + onOpenPrivateConversation: _openPrivateConversation, onSetFollowing: _setFollowingFriend, onRequestDelete: _deleteFriend, ) @@ -135,16 +137,14 @@ class _FriendsListScreenState extends SafeState { _loadList(); } - /// Update following status of a friend Future _setFollowingFriend(Friend friend, bool follow) async { loading = true; - if(!await _friendsHelper.setFollowing(friend.id, follow)) + if (!await _friendsHelper.setFollowing(friend.id, follow)) showSimpleSnack(context, tr("Could not update following status!")); _loadList(); - } /// Handles deletion request of a friend @@ -182,4 +182,11 @@ class _FriendsListScreenState extends SafeState { // Refresh list _loadList(); } + + /// Open a private conversation for a given [friend] + Future _openPrivateConversation(Friend friend) async { + loading = true; + await openPrivateConversation(context, friend.id); + loading = false; + } } diff --git a/lib/ui/tiles/accepted_friend_tile.dart b/lib/ui/tiles/accepted_friend_tile.dart index 4b84300..de5863c 100644 --- a/lib/ui/tiles/accepted_friend_tile.dart +++ b/lib/ui/tiles/accepted_friend_tile.dart @@ -9,16 +9,18 @@ import 'package:flutter/material.dart'; /// /// @author Pierre HUBERT -enum _FriendMenuChoices { REMOVE, TOGGLE_FOLLOWING } +enum _FriendMenuChoices { REMOVE, TOGGLE_FOLLOWING, PRIVATE_CONVERSATION } typedef OnRequestDeleteFriend = void Function(Friend); typedef OnSetFollowing = void Function(Friend, bool); +typedef OnOpenPrivateConversation = void Function(Friend); class AcceptedFriendTile extends StatelessWidget { final Friend friend; final User user; final OnRequestDeleteFriend onRequestDelete; final OnSetFollowing onSetFollowing; + final OnOpenPrivateConversation onOpenPrivateConversation; const AcceptedFriendTile({ Key key, @@ -26,10 +28,12 @@ class AcceptedFriendTile extends StatelessWidget { @required this.user, @required this.onRequestDelete, @required this.onSetFollowing, + @required this.onOpenPrivateConversation, }) : assert(friend != null), assert(user != null), assert(onRequestDelete != null), assert(onSetFollowing != null), + assert(onOpenPrivateConversation != null), super(key: key); @override @@ -49,6 +53,13 @@ class AcceptedFriendTile extends StatelessWidget { ), trailing: PopupMenuButton<_FriendMenuChoices>( itemBuilder: (c) => [ + //Open a private conversation + PopupMenuItem( + child: Text(tr("Private conversation")), + value: _FriendMenuChoices.PRIVATE_CONVERSATION, + ), + + // Update following status PopupMenuItem( child: Row( children: [ @@ -61,6 +72,8 @@ class AcceptedFriendTile extends StatelessWidget { ), value: _FriendMenuChoices.TOGGLE_FOLLOWING, ), + + // Remove the friend from the list PopupMenuItem( child: Text(tr("Remove")), value: _FriendMenuChoices.REMOVE, @@ -75,6 +88,11 @@ class AcceptedFriendTile extends StatelessWidget { if (value == null) return; switch (value) { + // Open private conversation + case _FriendMenuChoices.PRIVATE_CONVERSATION: + onOpenPrivateConversation(friend); + break; + //Toggle following status case _FriendMenuChoices.TOGGLE_FOLLOWING: onSetFollowing(friend, !friend.following); diff --git a/lib/utils/conversations_utils.dart b/lib/utils/conversations_utils.dart new file mode 100644 index 0000000..f577a09 --- /dev/null +++ b/lib/utils/conversations_utils.dart @@ -0,0 +1,31 @@ +import 'package:comunic/helpers/conversations_helper.dart'; +import 'package:comunic/ui/routes/conversation_route.dart'; +import 'package:comunic/utils/intl_utils.dart'; +import 'package:comunic/utils/ui_utils.dart'; +import 'package:flutter/material.dart'; + +/// Conversations utilities +/// +/// @author Pierre HUBERT + +/// Open a private conversation with a given [userID] +Future openPrivateConversation(BuildContext context, int userID) async { + final convID = await ConversationsHelper().getPrivate(userID); + + if (convID == null) { + showSimpleSnack(context, tr("Could not find a private conversation!")); + return false; + } + + // Open the conversation + Navigator.of(context).push( + MaterialPageRoute( + builder: (c) => ConversationRoute( + conversationID: convID, + ), + ), + ); + + // Success + return true; +}