From 263849266f42c43e7202741eb3bb410c7b07460e Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 6 May 2020 13:38:11 +0200 Subject: [PATCH] Can respond to friendship requests from memberships bar --- lib/lists/memberships_list.dart | 4 + lib/models/friend.dart | 6 +- .../tablet_mode/memberships_panel.dart | 88 ++++++++++++++++++- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/lib/lists/memberships_list.dart b/lib/lists/memberships_list.dart index 3722f15..03e90bb 100644 --- a/lib/lists/memberships_list.dart +++ b/lib/lists/memberships_list.dart @@ -30,4 +30,8 @@ class MembershipList extends AbstractList { Set get groupsId => where((f) => f.type == MembershipType.GROUP) .map((f) => f.groupID) .toSet(); + + /// Remove a friend membership from the list + void removeFriend(int friendID) => remove(firstWhere( + (f) => f.type == MembershipType.FRIEND && f.friend.id == friendID)); } diff --git a/lib/models/friend.dart b/lib/models/friend.dart index 689350f..c6630e3 100644 --- a/lib/models/friend.dart +++ b/lib/models/friend.dart @@ -8,12 +8,12 @@ import 'package:meta/meta.dart'; /// @author Pierre HUBERT class Friend extends CacheModel implements Comparable { - final bool accepted; + bool accepted; final int lastActive; final bool following; final bool canPostTexts; - const Friend({ + Friend({ @required int id, @required this.accepted, @required this.lastActive, @@ -22,6 +22,8 @@ class Friend extends CacheModel implements Comparable { }) : assert(id != null), assert(accepted != null), assert(lastActive != null), + assert(following != null), + assert(canPostTexts != null), super(id: id); /// Check out whether friend is connected or not diff --git a/lib/ui/widgets/tablet_mode/memberships_panel.dart b/lib/ui/widgets/tablet_mode/memberships_panel.dart index 086f16d..e0f81f9 100644 --- a/lib/ui/widgets/tablet_mode/memberships_panel.dart +++ b/lib/ui/widgets/tablet_mode/memberships_panel.dart @@ -1,10 +1,12 @@ import 'package:comunic/helpers/conversations_helper.dart'; +import 'package:comunic/helpers/friends_helper.dart'; import 'package:comunic/helpers/groups_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/helpers/webapp_helper.dart'; import 'package:comunic/lists/groups_list.dart'; import 'package:comunic/lists/memberships_list.dart'; import 'package:comunic/lists/users_list.dart'; +import 'package:comunic/models/friend.dart'; import 'package:comunic/models/membership.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart'; import 'package:comunic/ui/widgets/group_icon_widget.dart'; @@ -92,13 +94,40 @@ class _MembershipsPanelState extends SafeState { Widget _buildFriendMembership(Membership membership) { final user = _usersList.getUser(membership.friend.id); final connected = membership.friend.isConnected; + + Widget subtitle; + + if (!membership.friend.accepted) { + subtitle = RichText( + text: TextSpan(children: [ + WidgetSpan( + child: _RespondFriendshipRequestButton( + friend: membership.friend, + accept: true, + text: tr("Accept"), + color: Colors.green, + onTap: _respondFriendshipRequest, + )), + TextSpan(text: " "), + WidgetSpan( + child: _RespondFriendshipRequestButton( + friend: membership.friend, + accept: false, + text: tr("Reject"), + color: Colors.red, + onTap: _respondFriendshipRequest, + )), + ])); + } else + subtitle = Text( + connected ? tr("Online") : diffTimeFromNowToStr(membership.lastActive), + style: TextStyle(color: connected ? Colors.green : null), + ); + return ListTile( leading: AccountImageWidget(user: user, width: _MembershipIconsWidth), title: Text(user.displayName), - subtitle: Text( - connected ? tr("Online") : diffTimeFromNowToStr(membership.lastActive), - style: TextStyle(color: connected ? Colors.green : null), - ), + subtitle: subtitle, ); } @@ -124,4 +153,55 @@ class _MembershipsPanelState extends SafeState { subtitle: Text(diffTimeFromNowToStr(membership.lastActive)), ); } + + /// Respond to a friendship request + Future _respondFriendshipRequest(Friend f, bool accept) async { + try { + if (!accept && + !await showConfirmDialog( + context: Scaffold.of(context) + .context, // Without this the text appears in white + message: + tr("Do you really want to reject this friendship request?"))) + return; + + await FriendsHelper().respondRequest(f.id, accept); + + setState(() { + if (accept) + f.accepted = true; + else + _membershipList.removeFriend(f.id); + }); + _refreshKey.currentState.show(); + } catch (e, s) { + print("Could not respond to friendship request! $e\n$s"); + showSimpleSnack(context, tr("Could not respond to friendship request!")); + } + } +} + +class _RespondFriendshipRequestButton extends StatelessWidget { + final Friend friend; + final bool accept; + final String text; + final Color color; + final void Function(Friend, bool) onTap; + + const _RespondFriendshipRequestButton({ + Key key, + @required this.friend, + @required this.accept, + @required this.text, + @required this.color, + @required this.onTap, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () => onTap(friend, accept), + child: Text(text, style: TextStyle(color: color)), + ); + } }