diff --git a/lib/helpers/posts_helper.dart b/lib/helpers/posts_helper.dart index dbb9293..76543c4 100644 --- a/lib/helpers/posts_helper.dart +++ b/lib/helpers/posts_helper.dart @@ -56,6 +56,16 @@ class PostsHelper { } } + /// Delete a post + Future delete(int id) async { + return (await APIRequest( + uri: "posts/delete", + needLogin: true, + args: {"postID": id.toString()}, + ).exec()) + .isOK; + } + /// Turn an API entry into a [Post] object Post _apiToPost(Map map) { // Parse comments diff --git a/lib/models/post.dart b/lib/models/post.dart index 08bb6ac..96e8d21 100644 --- a/lib/models/post.dart +++ b/lib/models/post.dart @@ -32,29 +32,29 @@ class Post implements LikeElement { final UserAccessLevels access; final CommentsList comments; - Post({ - @required this.id, - @required this.userID, - @required this.userPageID, - @required this.groupID, - @required this.timeSent, - @required this.content, - @required this.visibilityLevel, - @required this.kind, - @required this.fileSize, - @required this.fileType, - @required this.filePath, - @required this.fileURL, - @required this.timeEnd, - @required this.linkURL, - @required this.linkTitle, - @required this.linkDescription, - @required this.linkImage, - @required this.likes, - @required this.userLike, - @required this.access, - @required this.comments - }) : assert(id != null), + Post( + {@required this.id, + @required this.userID, + @required this.userPageID, + @required this.groupID, + @required this.timeSent, + @required this.content, + @required this.visibilityLevel, + @required this.kind, + @required this.fileSize, + @required this.fileType, + @required this.filePath, + @required this.fileURL, + @required this.timeEnd, + @required this.linkURL, + @required this.linkTitle, + @required this.linkDescription, + @required this.linkImage, + @required this.likes, + @required this.userLike, + @required this.access, + @required this.comments}) + : assert(id != null), assert(userID != null), assert(userPageID != 0 || groupID != 0), assert(timeSent != null), @@ -69,4 +69,8 @@ class Post implements LikeElement { bool get hasContent => content != null; bool get hasComments => comments != null; + + bool get canDelete => + access == UserAccessLevels.FULL || + access == UserAccessLevels.INTERMEDIATE; } diff --git a/lib/ui/tiles/post_tile.dart b/lib/ui/tiles/post_tile.dart index 719fc76..9f157cc 100644 --- a/lib/ui/tiles/post_tile.dart +++ b/lib/ui/tiles/post_tile.dart @@ -4,6 +4,7 @@ import 'package:comunic/enums/likes_type.dart'; import 'package:comunic/enums/post_kind.dart'; import 'package:comunic/helpers/comments_helper.dart'; import 'package:comunic/helpers/likes_helper.dart'; +import 'package:comunic/helpers/posts_helper.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/comment.dart'; import 'package:comunic/models/like_element.dart'; @@ -29,16 +30,22 @@ const TextStyle _userNameStyle = TextStyle( fontWeight: FontWeight.w600, fontSize: 16.0); +/// Post actions +enum _PostActions { DELETE } + class PostTile extends StatefulWidget { final Post post; final UsersList usersInfo; + final void Function(Post) onDeletedPost; const PostTile({ Key key, @required this.post, @required this.usersInfo, + @required this.onDeletedPost, }) : assert(post != null), assert(usersInfo != null), + assert(onDeletedPost != null), super(key: key); @override @@ -47,6 +54,7 @@ class PostTile extends StatefulWidget { class _PostTileState extends State { // Helpers + final _postsHelper = PostsHelper(); final _likesHelper = LikesHelper(); final _commentsHelper = CommentsHelper(); @@ -89,8 +97,16 @@ class _PostTileState extends State { ), ), - PopupMenuButton( - itemBuilder: (c) => [], + PopupMenuButton<_PostActions>( + itemBuilder: (c) => [ + // Delete post + PopupMenuItem( + child: Text(tr("Delete")), + value: _PostActions.DELETE, + enabled: widget.post.canDelete, + ), + ], + onSelected: _selectedPostMenuAction, ) ], ); @@ -402,4 +418,30 @@ class _PostTileState extends State { widget.post.comments.remove(comment); }); } + + /// Method called each time the user has selected an option + void _selectedPostMenuAction(_PostActions value) { + switch (value) { + case _PostActions.DELETE: + confirmDelete(); + break; + } + } + + /// Perform the deletion of the post + Future confirmDelete() async { + // Ask user confirmation + if (!await showConfirmDialog( + context: context, + message: tr( + "Do you really want to delete this post ? The operation can not be reverted !"), + )) return; + + if (!await _postsHelper.delete(widget.post.id)) { + showSimpleSnack(context, tr("Could not delete the post!")); + return; + } + + widget.onDeletedPost(widget.post); + } } diff --git a/lib/ui/widgets/posts_list_widget.dart b/lib/ui/widgets/posts_list_widget.dart index b5bd2af..866db68 100644 --- a/lib/ui/widgets/posts_list_widget.dart +++ b/lib/ui/widgets/posts_list_widget.dart @@ -1,6 +1,7 @@ import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/posts_list.dart'; import 'package:comunic/lists/users_list.dart'; +import 'package:comunic/models/post.dart'; import 'package:comunic/ui/screens/conversation_screen.dart'; import 'package:comunic/ui/tiles/post_tile.dart'; import 'package:comunic/utils/intl_utils.dart'; @@ -73,6 +74,7 @@ class _PostsListWidgetState extends State { itemBuilder: (c, i) => PostTile( post: _list[i], usersInfo: _users, + onDeletedPost: _removePost, ), ); } @@ -83,4 +85,6 @@ class _PostsListWidgetState extends State { if (_list == null) return buildCenteredProgressBar(); return _buildListView(); } + + void _removePost(Post post) => setState(() => _list.remove(post)); }