diff --git a/lib/helpers/posts_helper.dart b/lib/helpers/posts_helper.dart index 384cd95..8451486 100644 --- a/lib/helpers/posts_helper.dart +++ b/lib/helpers/posts_helper.dart @@ -69,6 +69,19 @@ class PostsHelper { .isOK; } + /// Update a post visibility + Future setVisibility(int id, PostVisibilityLevel level) async { + return (await APIRequest( + uri: "posts/set_visibility_level", + needLogin: true, + args: { + "postID": id.toString(), + "new_level": _APIPostsVisibilityLevelMap.map((k, v) => MapEntry(v, k))[level] + }, + ).exec()) + .isOK; + } + /// Delete a post Future delete(int id) async { return (await APIRequest( diff --git a/lib/models/post.dart b/lib/models/post.dart index 81ecdc6..9f23ca8 100644 --- a/lib/models/post.dart +++ b/lib/models/post.dart @@ -16,7 +16,7 @@ class Post implements LikeElement { final int groupID; final int timeSent; String content; - final PostVisibilityLevel visibilityLevel; + PostVisibilityLevel visibilityLevel; final PostKind kind; final int fileSize; final String fileType; @@ -66,6 +66,8 @@ class Post implements LikeElement { assert(userLike != null), assert(access != null); + bool get isGroupPost => groupID != null && groupID > 0; + bool get hasContent => content != null; bool get hasComments => comments != null; diff --git a/lib/ui/tiles/post_tile.dart b/lib/ui/tiles/post_tile.dart index 80790ae..f64e4f0 100644 --- a/lib/ui/tiles/post_tile.dart +++ b/lib/ui/tiles/post_tile.dart @@ -18,6 +18,7 @@ import 'package:comunic/ui/widgets/network_image_widget.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/files_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; +import 'package:comunic/utils/post_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; @@ -98,12 +99,12 @@ class _PostTileState extends State { ), ), - PopupMenuButton( + InkWell( child: Icon( PostVisibilityLevelsMapIcons[widget.post.visibilityLevel], color: Colors.grey, ), - itemBuilder: (c) => [], + onTap: widget.post.canUpdate ? updatePostVisibilityLevel : null, ), PopupMenuButton<_PostActions>( @@ -457,6 +458,25 @@ class _PostTileState extends State { } } + /// Update post visibility level + Future updatePostVisibilityLevel() async { + final newLevel = await showPostVisibilityPicker( + context: context, + initialLevel: widget.post.visibilityLevel, + isGroup: widget.post.isGroupPost, + ); + + if (newLevel == null || newLevel == widget.post.visibilityLevel) return; + + // Update post visibility + if (!await _postsHelper.setVisibility(widget.post.id, newLevel)) { + showSimpleSnack(context, tr("Could not update post visibility!")); + return; + } + + setState(() => widget.post.visibilityLevel = newLevel); + } + /// Update post content Future updateContent() async { final newContent = await askUserString( diff --git a/lib/ui/tiles/post_visibility_level_tile.dart b/lib/ui/tiles/post_visibility_level_tile.dart new file mode 100644 index 0000000..95d195b --- /dev/null +++ b/lib/ui/tiles/post_visibility_level_tile.dart @@ -0,0 +1,38 @@ +import 'package:comunic/enums/post_visibility_level.dart'; +import 'package:flutter/material.dart'; + +/// Post visibility level tile +/// +/// @author Pierre HUBERT + +class PostVisibilityLevelTile extends StatelessWidget { + final PostVisibilityLevel level; + final String title; + final void Function(PostVisibilityLevel) onSelect; + final bool visible; + + const PostVisibilityLevelTile({ + Key key, + @required this.level, + @required this.title, + @required this.onSelect, + this.visible = true, + }) : assert(level != null), + assert(title != null), + assert(onSelect != null), + assert(visible != null), + super(key: key); + + @override + Widget build(BuildContext context) { + + if(!visible) + return Container(); + + return ListTile( + leading: Icon(PostVisibilityLevelsMapIcons[level]), + title: Text(title), + onTap: () => onSelect(level), + ); + } +} diff --git a/lib/utils/post_utils.dart b/lib/utils/post_utils.dart new file mode 100644 index 0000000..1fd703d --- /dev/null +++ b/lib/utils/post_utils.dart @@ -0,0 +1,74 @@ +import 'package:comunic/enums/post_visibility_level.dart'; +import 'package:comunic/ui/tiles/post_visibility_level_tile.dart'; +import 'package:comunic/utils/intl_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; + +/// Post utilities +/// +/// @author Pierre HUBERT + +/// Show post visibility level picker and return selected visibility level +Future showPostVisibilityPicker({ + @required BuildContext context, + @required PostVisibilityLevel initialLevel, + @required bool isGroup, +}) async { + assert(context != null); + assert(initialLevel != null); + assert(isGroup != null); + + final newLevel = await showDialog( + context: context, + builder: (c) => AlertDialog( + title: Text(tr("Select new post visibility level")), + + // Show all options + content: Column( + children: [ + // Public + PostVisibilityLevelTile( + level: PostVisibilityLevel.PUBLIC, + title: tr("Public"), + onSelect: (o) => Navigator.pop(c, o), + ), + + // Friends only (User page only) + PostVisibilityLevelTile( + level: PostVisibilityLevel.FRIENDS, + title: tr("Friends only"), + onSelect: (o) => Navigator.pop(c, o), + visible: !isGroup, + ), + + // User only (User page only) + PostVisibilityLevelTile( + level: PostVisibilityLevel.USER, + title: tr("Me only"), + onSelect: (o) => Navigator.pop(c, o), + visible: !isGroup, + ), + + // Group members only (Group page only) + PostVisibilityLevelTile( + level: PostVisibilityLevel.GROUP_MEMBERS, + title: tr("Group members only"), + onSelect: (o) => Navigator.pop(c, o), + visible: isGroup, + ), + ], + ), + + // Dialog actions + actions: [ + // Cancel + FlatButton( + child: Text(tr("Cancel").toUpperCase()), + onPressed: () => Navigator.pop(c, null), + ), + ], + ), + ); + + return newLevel == null ? initialLevel : newLevel; +}