mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Can request to join a Forez group
This commit is contained in:
		
							
								
								
									
										19
									
								
								lib/forez/helpers/forez_group_helper.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/forez/helpers/forez_group_helper.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/preferences_helper.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Forez group helper
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Contains the ID of the currently selected Forez group
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ForezGroupHelper {
 | 
				
			||||||
 | 
					  static Future<void> setId(int groupID) async {
 | 
				
			||||||
 | 
					    (await PreferencesHelper.getInstance())
 | 
				
			||||||
 | 
					        .setInt(PreferencesKeyList.FOREZ_GROUP, groupID);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static Future<int> getId() async {
 | 
				
			||||||
 | 
					    return (await PreferencesHelper.getInstance())
 | 
				
			||||||
 | 
					        .getInt(PreferencesKeyList.FOREZ_GROUP);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -15,7 +15,7 @@ const _JOIN_GROUP_KEY_ID = 1;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
List<Widget> buildTour(TourRouteState state) {
 | 
					List<Widget> buildTour(TourRouteState state) {
 | 
				
			||||||
  if (!state.pubKeys.containsKey(_JOIN_GROUP_KEY_ID))
 | 
					  if (!state.pubKeys.containsKey(_JOIN_GROUP_KEY_ID))
 | 
				
			||||||
    state.pubKeys[_JOIN_GROUP_KEY_ID] = GlobalKey();
 | 
					    state.pubKeys[_JOIN_GROUP_KEY_ID] = GlobalKey<JoinGroupPaneBodyState>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return [
 | 
					  return [
 | 
				
			||||||
    FirstTourPane(
 | 
					    FirstTourPane(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,13 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/forez/helpers/forez_group_helper.dart';
 | 
				
			||||||
import 'package:comunic/helpers/forez_groups_helper.dart';
 | 
					import 'package:comunic/helpers/forez_groups_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/helpers/groups_helper.dart';
 | 
				
			||||||
import 'package:comunic/models/group.dart';
 | 
					import 'package:comunic/models/group.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/dialogs/alert_dialog.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
					import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/tour/presentation_pane.dart';
 | 
					import 'package:comunic/ui/widgets/tour/presentation_pane.dart';
 | 
				
			||||||
import 'package:comunic/utils/intl_utils.dart';
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/log_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/ui_utils.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Ask the user to join a Forez group
 | 
					/// Ask the user to join a Forez group
 | 
				
			||||||
@@ -12,14 +17,16 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
class JoinGroupPane extends PresentationPane {
 | 
					class JoinGroupPane extends PresentationPane {
 | 
				
			||||||
  JoinGroupPane({
 | 
					  JoinGroupPane({
 | 
				
			||||||
    @required Function() onUpdated,
 | 
					    @required Function() onUpdated,
 | 
				
			||||||
    @required GlobalKey key,
 | 
					    @required GlobalKey<JoinGroupPaneBodyState> key,
 | 
				
			||||||
  }) : super(
 | 
					  }) : super(
 | 
				
			||||||
          icon: Icons.login,
 | 
					          icon: Icons.login,
 | 
				
			||||||
          title: tr("Join a group"),
 | 
					          title: tr("Join a Forez group"),
 | 
				
			||||||
          child: (c) => _JoinGroupPaneBody(
 | 
					          child: (c) => _JoinGroupPaneBody(
 | 
				
			||||||
            key: key,
 | 
					            key: key,
 | 
				
			||||||
            onUpdated: onUpdated,
 | 
					            onUpdated: onUpdated,
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
 | 
					          canGoNext: key?.currentState?.canGoNext ?? false,
 | 
				
			||||||
 | 
					          onTapNext: (c) => key.currentState.validateChoice(),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,14 +40,20 @@ class _JoinGroupPaneBody extends StatefulWidget {
 | 
				
			|||||||
        super(key: key);
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  __JoinGroupPaneBodyState createState() => __JoinGroupPaneBodyState();
 | 
					  JoinGroupPaneBodyState createState() => JoinGroupPaneBodyState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class __JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
 | 
					class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
 | 
				
			||||||
  List<Group> _groups;
 | 
					  List<Group> _groups;
 | 
				
			||||||
 | 
					  int _currChoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get canGoNext => _currChoice != null && _currChoice > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Group get _currGroup => _groups.firstWhere((e) => e.id == _currChoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _load() async {
 | 
					  Future<void> _load() async {
 | 
				
			||||||
    _groups = await ForezGroupsHelper.getForezGroups();
 | 
					    _groups = await ForezGroupsHelper.getForezGroups();
 | 
				
			||||||
 | 
					    _currChoice = _groups[0].id;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
@@ -49,18 +62,60 @@ class __JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
 | 
				
			|||||||
      onBuild: onBuild,
 | 
					      onBuild: onBuild,
 | 
				
			||||||
      errorMessage: tr("Failed to load the list of Forez groups!"));
 | 
					      errorMessage: tr("Failed to load the list of Forez groups!"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  List<Widget> get _initialWidgets => [
 | 
					  Widget onBuild() => ConstrainedBox(
 | 
				
			||||||
        Text(tr("Please choose now the Forez group you want to join...")),
 | 
					        constraints: BoxConstraints(maxWidth: 300),
 | 
				
			||||||
      ];
 | 
					        child: Column(
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					            Text(tr("Please choose now the Forez group you want to join...")),
 | 
				
			||||||
 | 
					          ]..addAll(_groups.map((e) => RadioListTile(
 | 
				
			||||||
 | 
					                value: e.id,
 | 
				
			||||||
 | 
					                groupValue: _currChoice,
 | 
				
			||||||
 | 
					                onChanged: (v) => setState(() => _currChoice = _currChoice),
 | 
				
			||||||
 | 
					                title: Text(e.name),
 | 
				
			||||||
 | 
					                subtitle: Text(e.membershipText),
 | 
				
			||||||
 | 
					              ))),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget onBuild() => Flexible(
 | 
					  Future<bool> validateChoice() async {
 | 
				
			||||||
          child: ListView.builder(
 | 
					    try {
 | 
				
			||||||
        itemCount: _initialWidgets.length + _groups.length,
 | 
					      switch (_currGroup.membershipLevel) {
 | 
				
			||||||
        itemBuilder: (c, i) {
 | 
					        case GroupMembershipLevel.VISITOR:
 | 
				
			||||||
          if (i < _initialWidgets.length) return _initialWidgets[i];
 | 
					          if (!await GroupsHelper.sendRequest(_currGroup.id))
 | 
				
			||||||
 | 
					            throw Exception("Failed to send group membership request!");
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          final group = _groups[i - _initialWidgets.length];
 | 
					        case GroupMembershipLevel.INVITED:
 | 
				
			||||||
          return ListTile();
 | 
					          if (!await GroupsHelper.respondInvitation(_currGroup.id, true))
 | 
				
			||||||
        },
 | 
					            throw Exception(
 | 
				
			||||||
      ));
 | 
					                "Failed to respond to group membership invitation!");
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case GroupMembershipLevel.PENDING:
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case GroupMembershipLevel.ADMINISTRATOR:
 | 
				
			||||||
 | 
					        case GroupMembershipLevel.MODERATOR:
 | 
				
			||||||
 | 
					        case GroupMembershipLevel.MEMBER:
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Check if the user can not access yet the group
 | 
				
			||||||
 | 
					      if ((_currGroup.membershipLevel == GroupMembershipLevel.VISITOR &&
 | 
				
			||||||
 | 
					              _currGroup.registrationLevel != GroupRegistrationLevel.OPEN) ||
 | 
				
			||||||
 | 
					          _currGroup.membershipLevel == GroupMembershipLevel.PENDING) {
 | 
				
			||||||
 | 
					        await alert(context,
 | 
				
			||||||
 | 
					            tr("You can not access this group yet, please wait for a member of the group to accept your request. Hopefully this will not be too long. Please check back soon!"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await ForezGroupHelper.setId(_currGroup.id);
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    } catch (e, s) {
 | 
				
			||||||
 | 
					      logError(e, s);
 | 
				
			||||||
 | 
					      snack(context, tr("Failed to register to group!"));
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,9 +141,9 @@ class GroupsHelper {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Perform a simple membership request
 | 
					  /// Perform a simple membership request
 | 
				
			||||||
  Future<bool> _simpleMembershipRequest(int groupID, String uri,
 | 
					  static Future<bool> _simpleMembershipRequest(int groupID, String uri,
 | 
				
			||||||
          {Map<String, String> args}) async =>
 | 
					          {Map<String, String> args}) async =>
 | 
				
			||||||
      (await (APIRequest(uri: uri, needLogin: true)
 | 
					      (await (APIRequest.withLogin(uri)
 | 
				
			||||||
                ..addInt("id", groupID)
 | 
					                ..addInt("id", groupID)
 | 
				
			||||||
                ..addArgs(args == null ? Map() : args))
 | 
					                ..addArgs(args == null ? Map() : args))
 | 
				
			||||||
              .exec())
 | 
					              .exec())
 | 
				
			||||||
@@ -158,11 +158,11 @@ class GroupsHelper {
 | 
				
			|||||||
      _simpleMembershipRequest(groupID, "groups/cancel_request");
 | 
					      _simpleMembershipRequest(groupID, "groups/cancel_request");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Send a new membership request
 | 
					  /// Send a new membership request
 | 
				
			||||||
  Future<bool> sendRequest(int groupID) async =>
 | 
					  static Future<bool> sendRequest(int groupID) async =>
 | 
				
			||||||
      _simpleMembershipRequest(groupID, "groups/send_request");
 | 
					      _simpleMembershipRequest(groupID, "groups/send_request");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Respond to a group membership invitation
 | 
					  /// Respond to a group membership invitation
 | 
				
			||||||
  Future<bool> respondInvitation(int groupID, bool accept) async =>
 | 
					  static Future<bool> respondInvitation(int groupID, bool accept) async =>
 | 
				
			||||||
      _simpleMembershipRequest(groupID, "groups/respond_invitation", args: {
 | 
					      _simpleMembershipRequest(groupID, "groups/respond_invitation", args: {
 | 
				
			||||||
        "accept": accept ? "true" : "false",
 | 
					        "accept": accept ? "true" : "false",
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ enum PreferencesKeyList {
 | 
				
			|||||||
  SHOW_PERFORMANCE_OVERLAY,
 | 
					  SHOW_PERFORMANCE_OVERLAY,
 | 
				
			||||||
  PUSH_NOTIFICATIONS_STATUS,
 | 
					  PUSH_NOTIFICATIONS_STATUS,
 | 
				
			||||||
  IS_TOUR_SEEN,
 | 
					  IS_TOUR_SEEN,
 | 
				
			||||||
 | 
					  FOREZ_GROUP,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const _PreferenceKeysName = {
 | 
					const _PreferenceKeysName = {
 | 
				
			||||||
@@ -25,6 +26,7 @@ const _PreferenceKeysName = {
 | 
				
			|||||||
  PreferencesKeyList.SHOW_PERFORMANCE_OVERLAY: "perfs_overlay",
 | 
					  PreferencesKeyList.SHOW_PERFORMANCE_OVERLAY: "perfs_overlay",
 | 
				
			||||||
  PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS: "push_notifications_status",
 | 
					  PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS: "push_notifications_status",
 | 
				
			||||||
  PreferencesKeyList.IS_TOUR_SEEN: "is_tour_seen",
 | 
					  PreferencesKeyList.IS_TOUR_SEEN: "is_tour_seen",
 | 
				
			||||||
 | 
					  PreferencesKeyList.FOREZ_GROUP: "forez_group",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PreferencesHelper {
 | 
					class PreferencesHelper {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
import 'package:meta/meta.dart';
 | 
					import 'package:meta/meta.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Group information
 | 
					/// Group information
 | 
				
			||||||
@@ -71,6 +72,25 @@ class Group implements Comparable<Group> {
 | 
				
			|||||||
      (membershipLevel == GroupMembershipLevel.MEMBER &&
 | 
					      (membershipLevel == GroupMembershipLevel.MEMBER &&
 | 
				
			||||||
          postCreationLevel == GroupPostCreationLevel.MEMBERS);
 | 
					          postCreationLevel == GroupPostCreationLevel.MEMBERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String get membershipText {
 | 
				
			||||||
 | 
					    switch (membershipLevel) {
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.ADMINISTRATOR:
 | 
				
			||||||
 | 
					        return tr("Administrator");
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.MODERATOR:
 | 
				
			||||||
 | 
					        return tr("Moderator");
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.MEMBER:
 | 
				
			||||||
 | 
					        return tr("Member");
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.INVITED:
 | 
				
			||||||
 | 
					        return tr("Invited");
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.PENDING:
 | 
				
			||||||
 | 
					        return tr("Requested");
 | 
				
			||||||
 | 
					      case GroupMembershipLevel.VISITOR:
 | 
				
			||||||
 | 
					        return tr("Visitor");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw new Exception("Unreachable statement!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  int compareTo(Group other) => id.compareTo(other.id);
 | 
					  int compareTo(Group other) => id.compareTo(other.id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,7 +87,7 @@ class _GroupMembershipWidgetState extends SafeState<GroupMembershipWidget> {
 | 
				
			|||||||
            message: tr("Do you really want to reject this invitation?")))
 | 
					            message: tr("Do you really want to reject this invitation?")))
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!await GroupsHelper().respondInvitation(_id, accept)) {
 | 
					    if (!await GroupsHelper.respondInvitation(_id, accept)) {
 | 
				
			||||||
      showSimpleSnack(context, tr("Could not respond to your invitation!"));
 | 
					      showSimpleSnack(context, tr("Could not respond to your invitation!"));
 | 
				
			||||||
      if (this.widget.onError != null) this.widget.onError();
 | 
					      if (this.widget.onError != null) this.widget.onError();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -147,7 +147,7 @@ class _GroupMembershipWidgetState extends SafeState<GroupMembershipWidget> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /// Create new membership request
 | 
					  /// Create new membership request
 | 
				
			||||||
  void _requestMembership() async {
 | 
					  void _requestMembership() async {
 | 
				
			||||||
    if (!await GroupsHelper().sendRequest(_id)) {
 | 
					    if (!await GroupsHelper.sendRequest(_id)) {
 | 
				
			||||||
      showSimpleSnack(context, tr("Could not send your membership request!"));
 | 
					      showSimpleSnack(context, tr("Could not send your membership request!"));
 | 
				
			||||||
      if (this.widget.onError != null) this.widget.onError();
 | 
					      if (this.widget.onError != null) this.widget.onError();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,9 @@ class LoginRoutesTheme extends StatelessWidget {
 | 
				
			|||||||
            accentColor: Colors.white,
 | 
					            accentColor: Colors.white,
 | 
				
			||||||
            hintColor: Colors.white,
 | 
					            hintColor: Colors.white,
 | 
				
			||||||
            textTheme: TextTheme(subtitle1: TextStyle(color: Colors.white)),
 | 
					            textTheme: TextTheme(subtitle1: TextStyle(color: Colors.white)),
 | 
				
			||||||
 | 
					            radioTheme: RadioThemeData(
 | 
				
			||||||
 | 
					              fillColor: MaterialStateProperty.all(Colors.white),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            colorScheme: ColorScheme(
 | 
					            colorScheme: ColorScheme(
 | 
				
			||||||
              primary: Colors.white,
 | 
					              primary: Colors.white,
 | 
				
			||||||
              primaryVariant: Colors.white,
 | 
					              primaryVariant: Colors.white,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user