import 'package:comunic/helpers/groups_helper.dart'; import 'package:comunic/models/group.dart'; import 'package:comunic/ui/widgets/safe_state.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; /// Group membership information widget /// /// @author Pierre Hubert class GroupMembershipWidget extends StatefulWidget { final Group group; final Function() onUpdated; final Function() onError; const GroupMembershipWidget( {@required this.group, this.onUpdated, this.onError}) : assert(group != null); @override _GroupMembershipWidgetState createState() => _GroupMembershipWidgetState(); } class _GroupMembershipWidgetState extends SafeState { Group get group => widget.group; int get _id => group.id; GroupMembershipLevel get _level => group.membershipLevel; @override Widget build(BuildContext context) { switch (_level) { case GroupMembershipLevel.ADMINISTRATOR: return Text(tr("Administrator")); case GroupMembershipLevel.MODERATOR: return Text(tr("Moderator")); case GroupMembershipLevel.MEMBER: return Text(tr("Member")); case GroupMembershipLevel.INVITED: return _buildInvitedState(); case GroupMembershipLevel.PENDING: return _buildPendingState(); case GroupMembershipLevel.VISITOR: return _buildVisitorState(); default: throw Exception("Unknown group membership level state: $_level"); } } /// Build invited state Widget _buildInvitedState() { return RichText( text: TextSpan(children: [ WidgetSpan( child: Icon(Icons.info_outline, size: 12), alignment: PlaceholderAlignment.middle), TextSpan(text: " " + tr("Invited") + " ", style: blackForWhiteTheme()), TextSpan( text: tr("Accept"), style: TextStyle(color: Colors.green), recognizer: TapGestureRecognizer() ..onTap = () => _respondInvitation(true)), TextSpan(text: " "), TextSpan( text: tr("Reject"), style: TextStyle(color: Colors.red), recognizer: TapGestureRecognizer() ..onTap = () => _respondInvitation(false)), ]), ); } /// Respond to an invitation void _respondInvitation(bool accept) async { if (!accept && !await showConfirmDialog( context: context, message: tr("Do you really want to reject this invitation?"))) return; if (!await GroupsHelper().respondInvitation(_id, accept)) { showSimpleSnack(context, tr("Could not respond to your invitation!")); if (this.widget.onError != null) this.widget.onError(); } else { // Refresh state group.membershipLevel = accept ? GroupMembershipLevel.MEMBER : GroupMembershipLevel.VISITOR; this.setState(() {}); if (this.widget.onUpdated != null) this.widget.onUpdated(); } } /// Build pending state Widget _buildPendingState() { return RichText( text: TextSpan(children: [ WidgetSpan( child: Icon(Icons.access_time, size: 12), alignment: PlaceholderAlignment.middle), TextSpan( text: " " + tr("Requested") + " ", style: blackForWhiteTheme()), TextSpan( text: tr("Cancel"), style: TextStyle(color: Colors.blue), recognizer: TapGestureRecognizer()..onTap = () => _cancelRequest()), ]), ); } /// Cancel group membership request void _cancelRequest() async { if (!await GroupsHelper().cancelRequest(_id)) { showSimpleSnack(context, tr("Could not cancel your membership request!")); if (this.widget.onError != null) this.widget.onError(); } else { // Refresh state group.membershipLevel = GroupMembershipLevel.VISITOR; this.setState(() {}); if (this.widget.onUpdated != null) this.widget.onUpdated(); } } /// Build visitor state Widget _buildVisitorState() { // Check if the user can request membership if (group.registrationLevel == GroupRegistrationLevel.CLOSED) return Text(tr("Closed registration")); return RichText( text: TextSpan( text: tr("Request membership"), recognizer: TapGestureRecognizer() ..onTap = () => _requestMembership()), ); } /// Create new membership request void _requestMembership() async { if (!await GroupsHelper().sendRequest(_id)) { showSimpleSnack(context, tr("Could not send your membership request!")); if (this.widget.onError != null) this.widget.onError(); } else { // Refresh state group.membershipLevel = GroupMembershipLevel.PENDING; this.setState(() {}); if (this.widget.onUpdated != null) this.widget.onUpdated(); } } }