import 'package:comunic/helpers/groups_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/group_members_list.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/group.dart'; import 'package:comunic/models/group_membership.dart'; import 'package:comunic/models/user.dart'; import 'package:comunic/ui/dialogs/multi_choices_dialog.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart'; import 'package:comunic/ui/widgets/async_screen_widget.dart'; import 'package:comunic/ui/widgets/comunic_back_button_widget.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; /// Group members screen /// /// @author Pierre HUBERT class GroupMembersScreen extends StatefulWidget { final int groupID; const GroupMembersScreen({Key key, this.groupID}) : assert(groupID != null), super(key: key); @override _GroupMembersScreenState createState() => _GroupMembersScreenState(); } class _GroupMembersScreenState extends State { final _key = GlobalKey(); GroupMembersList _members; UsersList _users; Future _refresh() async { final members = await GroupsHelper.getMembersList(widget.groupID); final users = await UsersHelper().getListWithThrow(members.usersID); _members = members; _users = users; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: ComunicBackButton(), title: Text(tr("Group members")), ), body: _buildBody(), ); } Widget _buildBody() => AsyncScreenWidget( key: _key, onReload: _refresh, onBuild: _buildBodyContent, errorMessage: tr("Could not load the list of members of this group!"), showOldDataWhileUpdating: true, ); Widget _buildBodyContent() { return ListView( children: _members.map(_buildGroupMemberTile).toList(), ); } Widget _buildGroupMemberTile(GroupMembership membership) { final user = _users.getUser(membership.userID); return _GroupMembershipTile( membership: membership, user: user, onUpdated: () => _key.currentState.refresh(), ); } } List> get _membershipLevels => [ MultiChoiceEntry( id: GroupMembershipLevel.ADMINISTRATOR, title: tr("Administrator"), subtitle: tr("Can change members privileges and change group settings")), MultiChoiceEntry( id: GroupMembershipLevel.MODERATOR, title: tr("Moderator"), subtitle: tr( "Can always create posts, invite users and respond to membership request")), MultiChoiceEntry( id: GroupMembershipLevel.MEMBER, title: tr("Member"), subtitle: tr("Can access to all group posts")), MultiChoiceEntry( id: GroupMembershipLevel.PENDING, title: tr("Requested")), MultiChoiceEntry(id: GroupMembershipLevel.INVITED, title: tr("Invited")), MultiChoiceEntry(id: GroupMembershipLevel.VISITOR, title: tr("Visitor")), ]; class _GroupMembershipTile extends StatefulWidget { final GroupMembership membership; final User user; final void Function() onUpdated; const _GroupMembershipTile({ Key key, @required this.membership, @required this.user, @required this.onUpdated, }) : assert(membership != null), assert(user != null), assert(onUpdated != null), super(key: key); @override __GroupMembershipTileState createState() => __GroupMembershipTileState(); } class __GroupMembershipTileState extends State<_GroupMembershipTile> { int get groupID => widget.membership.groupID; int get userID => widget.membership.userID; @override Widget build(BuildContext context) { return ListTile( leading: AccountImageWidget( user: widget.user, ), title: Text(widget.user.displayName), subtitle: Text(_membershipLevels .firstWhere((f) => f.id == widget.membership.level) .title), trailing: _buildTrailing(), ); } Widget _buildTrailing() { switch (widget.membership.level) { case GroupMembershipLevel.ADMINISTRATOR: // TODO: Handle this case. break; case GroupMembershipLevel.MODERATOR: // TODO: Handle this case. break; case GroupMembershipLevel.MEMBER: // TODO: Handle this case. break; case GroupMembershipLevel.INVITED: return _buildInvitedCase(); break; case GroupMembershipLevel.PENDING: // TODO: Handle this case. break; case GroupMembershipLevel.VISITOR: // This case should never happen break; } return null; } Widget _buildInvitedCase() { return MaterialButton( onPressed: _cancelMembership, child: Text(tr("Cancel").toUpperCase()), textColor: Colors.red, ); } void _cancelMembership() async { try { await GroupsHelper.cancelInvitation(groupID, userID); } catch (e, s) { print("Could not cancel invitation! $e\n$s"); showSimpleSnack(context, tr("Could not cancel invitation!")); } widget.onUpdated(); } }