diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index c7d6246..f68d587 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -51,7 +51,7 @@ class ConversationsHelper { }); // Update all conversation settings, if possible - if(settings.isOwner) { + if (settings.isOwner) { request.addString("name", settings.hasName ? settings.name : "false"); request.addString("members", settings.members.join(",")); } @@ -61,6 +61,19 @@ class ConversationsHelper { return response.code == 200; } + /// Delete a conversation specified by its [id] + Future deleteConversation(int id) async { + final response = await APIRequest( + uri: "conversations/delete", + needLogin: true, + args: { + "conversationID": id.toString(), + }, + ).exec(); + + return response.code == 200; + } + /// Download the list of conversations from the server Future downloadList() async { final response = diff --git a/lib/ui/screens/conversations_list_screen.dart b/lib/ui/screens/conversations_list_screen.dart index 8df68db..865e006 100644 --- a/lib/ui/screens/conversations_list_screen.dart +++ b/lib/ui/screens/conversations_list_screen.dart @@ -2,6 +2,7 @@ import 'package:comunic/enums/load_error_level.dart'; import 'package:comunic/helpers/conversations_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/conversations_list.dart'; +import 'package:comunic/models/conversation.dart'; import 'package:comunic/ui/routes/conversation_route.dart'; import 'package:comunic/ui/routes/create_conversation_route.dart'; import 'package:comunic/ui/tiles/conversation_tile.dart'; @@ -105,6 +106,43 @@ class _ConversationScreenState extends State { .push(MaterialPageRoute(builder: (c) => CreateConversationRoute())); } + /// Handles conversation deletion request + Future _requestDeleteConversation(Conversation conversation) async { + final result = await showDialog( + context: context, + builder: (c) { + return AlertDialog( + title: Text(tr("Delete conversation")), + content: Text(tr( + "Do you really want to remove this conversation from your list of conversations ? If you are the owner of this conversation, it will be completely deleted!")), + actions: [ + FlatButton( + onPressed: () => Navigator.pop(context, false), + child: Text(tr("cancel").toUpperCase()), + ), + FlatButton( + onPressed: () => Navigator.pop(context, true), + child: Text( + tr("delete").toUpperCase(), + style: TextStyle(color: Colors.red), + ), + ) + ], + ); + }, + ); + + if (result == null || !result) return; + + // Request the conversation to be deleted now + if (!await _conversationsHelper.deleteConversation(conversation.id)) + Scaffold.of(context).showSnackBar( + SnackBar(content: Text(tr("Could not delete the conversation!")))); + + // Reload the list of conversations + _loadConversationsList(false); + } + @override Widget build(BuildContext context) { if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard(); @@ -128,6 +166,7 @@ class _ConversationScreenState extends State { onOpen: (c) { _openConversation(context, c.id); }, + onRequestDelete: _requestDeleteConversation, ); }, itemCount: _list.length, diff --git a/lib/ui/tiles/conversation_tile.dart b/lib/ui/tiles/conversation_tile.dart index 7471208..fb65c1a 100644 --- a/lib/ui/tiles/conversation_tile.dart +++ b/lib/ui/tiles/conversation_tile.dart @@ -10,20 +10,26 @@ import 'package:flutter/material.dart'; /// @author Pierre HUBERT typedef OpenConversationCallback = void Function(Conversation); +typedef RequestDeleteConversationCallback = void Function(Conversation); + +enum _PopupMenuChoices { DELETE } class ConversationTile extends StatelessWidget { final Conversation conversation; final UsersList usersList; final OpenConversationCallback onOpen; + final RequestDeleteConversationCallback onRequestDelete; const ConversationTile( {Key key, @required this.conversation, @required this.usersList, - @required this.onOpen}) + @required this.onOpen, + @required this.onRequestDelete}) : assert(conversation != null), assert(usersList != null), assert(onOpen != null), + assert(onRequestDelete != null), super(key: key); _buildSubInformation(IconData icon, String content) { @@ -80,6 +86,26 @@ class ConversationTile extends StatelessWidget { ), ], ), + + // Trailing information + trailing: PopupMenuButton<_PopupMenuChoices>( + itemBuilder: (b) => >[ + PopupMenuItem( + child: Text(tr("Delete")), + value: _PopupMenuChoices.DELETE, + ) + ], + onSelected: _conversationMenuCallback, + ), ); } + + /// Method called each time an option of the menu is selected + void _conversationMenuCallback(_PopupMenuChoices c) { + switch (c) { + case _PopupMenuChoices.DELETE: + onRequestDelete(conversation); + break; + } + } }