mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 12:59:21 +00:00
Can request to join a Forez group
This commit is contained in:
parent
0cd6ed284b
commit
d178e8b1c3
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(
|
||||||
|
constraints: BoxConstraints(maxWidth: 300),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
Text(tr("Please choose now the Forez group you want to join...")),
|
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user