From 5f70669a843e2d9774aa0fdaad6c19ebd46a9853 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 Apr 2020 18:58:45 +0200 Subject: [PATCH] Create like widget --- lib/ui/tiles/comment_tile.dart | 87 ++++++++++------------------- lib/ui/tiles/post_tile.dart | 6 -- lib/ui/widgets/like_widget.dart | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 63 deletions(-) create mode 100644 lib/ui/widgets/like_widget.dart diff --git a/lib/ui/tiles/comment_tile.dart b/lib/ui/tiles/comment_tile.dart index b90481d..3546581 100644 --- a/lib/ui/tiles/comment_tile.dart +++ b/lib/ui/tiles/comment_tile.dart @@ -1,6 +1,8 @@ +import 'package:comunic/enums/likes_type.dart'; import 'package:comunic/models/comment.dart'; import 'package:comunic/models/user.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart'; +import 'package:comunic/ui/widgets/like_widget.dart'; import 'package:comunic/ui/widgets/network_image_widget.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; @@ -16,7 +18,6 @@ enum _CommentAction { DELETE, UPDATE } class CommentTile extends StatelessWidget { final Comment comment; final User user; - final void Function(Comment) onUpdateLike; final void Function(Comment) onUpdateComment; final void Function(Comment) onDeleteComment; @@ -24,12 +25,10 @@ class CommentTile extends StatelessWidget { Key key, @required this.comment, @required this.user, - @required this.onUpdateLike, @required this.onUpdateComment, @required this.onDeleteComment, }) : assert(comment != null), assert(user != null), - assert(onUpdateLike != null), assert(onUpdateComment != null), assert(onDeleteComment != null), super(key: key); @@ -42,7 +41,10 @@ class CommentTile extends StatelessWidget { user.displayName, ), subtitle: _buildCommentContent(), - trailing: Text(diffTimeFromNowToStr(comment.timeSent), style: TextStyle(fontSize: 10.0),), + trailing: Text( + diffTimeFromNowToStr(comment.timeSent), + style: TextStyle(fontSize: 10.0), + ), ); } @@ -53,20 +55,20 @@ class CommentTile extends StatelessWidget { ), onSelected: _selectedMenuOption, itemBuilder: (c) => [ - // Update comment content - PopupMenuItem( - enabled: comment.isOwner, - child: Text(tr("Update")), - value: _CommentAction.UPDATE, - ), + // Update comment content + PopupMenuItem( + enabled: comment.isOwner, + child: Text(tr("Update")), + value: _CommentAction.UPDATE, + ), - // Delete comment - PopupMenuItem( - enabled: comment.isOwner, - child: Text(tr("Delete")), - value: _CommentAction.DELETE, - ), - ], + // Delete comment + PopupMenuItem( + enabled: comment.isOwner, + child: Text(tr("Delete")), + value: _CommentAction.DELETE, + ), + ], ); } @@ -91,55 +93,26 @@ class CommentTile extends StatelessWidget { child: comment.hasContent ? Text( comment.content, - style: TextStyle(color: darkTheme() ? darkAccentColor : Colors.black), + style: TextStyle( + color: darkTheme() ? darkAccentColor : Colors.black), ) : null, ), // Comment likes - _buildLikeButton(), + LikeWidget( + likeType: LikesType.COMMENT, + likeID: comment.id, + likesCount: comment.likes, + isLiking: comment.userLike, + onUpdatedLikings: (count, isLiking) { + comment.likes = count; + comment.userLike = isLiking; + }), ], ); } - String get _likeString { - if (comment.likes == 0) return tr("Like"); - if (comment.likes == 1) - return tr("1 Like"); - else - return tr("%num% likes", args: {"num": comment.likes.toString()}); - } - - /// Build like button associated to this post - Widget _buildLikeButton() { - return Padding( - padding: const EdgeInsets.only(top: 4.0, bottom: 4.0), - child: Align( - alignment: AlignmentDirectional.topStart, - child: Column( - children: [ - InkWell( - onTap: () => onUpdateLike(comment), - child: Row( - children: [ - Icon( - Icons.thumb_up, - color: comment.userLike ? Colors.blue : null, - size: 15.0, - ), - SizedBox( - width: 8.0, - ), - Text(_likeString), - ], - ), - ), - ], - ), - ), - ); - } - /// A menu option has been selected void _selectedMenuOption(_CommentAction value) { switch (value) { diff --git a/lib/ui/tiles/post_tile.dart b/lib/ui/tiles/post_tile.dart index c1883df..1b114e3 100644 --- a/lib/ui/tiles/post_tile.dart +++ b/lib/ui/tiles/post_tile.dart @@ -362,7 +362,6 @@ class _PostTileState extends State { (num) => CommentTile( comment: widget.post.comments[num], user: widget.usersInfo.getUser(widget.post.comments[num].userID), - onUpdateLike: _updateCommentLike, onUpdateComment: _updateCommentContent, onDeleteComment: _deleteComment, ), @@ -525,11 +524,6 @@ class _PostTileState extends State { _updateElementLike(LikesType.POST, widget.post); } - /// Invert comment like status - Future _updateCommentLike(Comment comment) async { - _updateElementLike(LikesType.COMMENT, comment); - } - /// Invert element like status Future _updateElementLike(LikesType type, LikeElement element) async { // Update liking status diff --git a/lib/ui/widgets/like_widget.dart b/lib/ui/widgets/like_widget.dart new file mode 100644 index 0000000..59b875c --- /dev/null +++ b/lib/ui/widgets/like_widget.dart @@ -0,0 +1,98 @@ +import 'package:comunic/enums/likes_type.dart'; +import 'package:comunic/helpers/likes_helper.dart'; +import 'package:comunic/ui/widgets/safe_state.dart'; +import 'package:comunic/utils/intl_utils.dart'; +import 'package:flutter/material.dart'; + +/// Like widget +/// +/// @author Pierre Hubert + +/// Updated linking callback +/// int : new number of likes +/// bool : new user liking status +typedef UpdatedLikingCallBack = Function(int, bool); + +class LikeWidget extends StatefulWidget { + final LikesType likeType; + final int likeID; + int likesCount; + bool isLiking; + final UpdatedLikingCallBack onUpdatedLikings; + + LikeWidget({ + Key key, + @required this.likeType, + @required this.likeID, + @required this.likesCount, + @required this.isLiking, + @required this.onUpdatedLikings, + }) : assert(likeType != null), + assert(likeID != null), + assert(likesCount != null), + assert(isLiking != null), + assert(onUpdatedLikings != null), + super(key: key); + + @override + _LikeWidgetState createState() => _LikeWidgetState(); +} + +class _LikeWidgetState extends SafeState { + String get _likeString { + switch (widget.likesCount) { + case 0: + return tr("Like"); + + case 1: + return tr("1 Like"); + + default: + return tr("%num% likes", args: {"num": widget.likesCount.toString()}); + } + } + + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 4.0, bottom: 4.0), + child: Align( + alignment: AlignmentDirectional.topStart, + child: Column( + children: [ + InkWell( + onTap: () => _toggleLike(), + child: Row( + children: [ + Icon( + Icons.thumb_up, + color: widget.isLiking ? Colors.blue : null, + size: 15.0, + ), + SizedBox( + width: 8.0, + ), + Text(_likeString), + ], + ), + ), + ], + ), + ), + ); + } + + /// Toggle like status + void _toggleLike() async { + // As like are not really important, we ignore failures + if (await LikesHelper().setLiking( + type: widget.likeType, like: !widget.isLiking, id: widget.likeID)) { + setState(() { + widget.isLiking = !widget.isLiking; + + widget.likesCount += widget.isLiking ? 1 : -1; + + widget.onUpdatedLikings(widget.likesCount, widget.isLiking); + }); + } + } +}