1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-30 00:36:28 +00:00
comunicmobile/lib/helpers/groups_helper.dart

217 lines
6.9 KiB
Dart

import 'package:comunic/lists/groups_list.dart';
import 'package:comunic/models/advanced_group_info.dart';
import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/group.dart';
import 'package:comunic/utils/api_utils.dart';
/// Groups helper
///
/// @author Pierre HUBERT
const _APIGroupsMembershipLevelsMap = {
"administrator": GroupMembershipLevel.ADMINISTRATOR,
"moderator": GroupMembershipLevel.MODERATOR,
"member": GroupMembershipLevel.MEMBER,
"invited": GroupMembershipLevel.INVITED,
"pending": GroupMembershipLevel.PENDING,
"visitor": GroupMembershipLevel.VISITOR
};
const _APIGroupsVisibilityLevelsMap = {
"open": GroupVisibilityLevel.OPEN,
"private": GroupVisibilityLevel.PRIVATE,
"secrete": GroupVisibilityLevel.SECRETE
};
const _APIGroupsRegistrationLevelsMap = {
"open": GroupRegistrationLevel.OPEN,
"moderated": GroupRegistrationLevel.MODERATED,
"closed": GroupRegistrationLevel.CLOSED
};
const _APIGroupsPostsCreationLevelsMap = {
"moderators": GroupPostCreationLevel.MODERATORS,
"members": GroupPostCreationLevel.MEMBERS
};
final _groupsListCache = GroupsList();
/// Callback for getting advanced user information
enum GetAdvancedInfoStatus { SUCCESS, ACCESS_DENIED }
class GetAdvancedInfoResult {
final GetAdvancedInfoStatus status;
final AdvancedGroupInfo info;
GetAdvancedInfoResult(this.status, this.info) : assert(status != null);
}
/// Groups helper
class GroupsHelper {
/// Download a list of groups information from the server
Future<GroupsList> _downloadList(Set<int> groups) async {
final response = await APIRequest(
uri: "groups/get_multiple_info",
needLogin: true,
args: {"list": groups.join(",")},
).exec();
if (response.code != 200) return null;
final list = GroupsList();
response
.getObject()
.forEach((k, d) => list[int.parse(k)] = _getGroupFromAPI(d));
return list;
}
/// Get a list of groups from the server. In case of error, this method throws
/// an exception
Future<GroupsList> getListOrThrow(Set<int> groups,
{bool force = false}) async {
final list = await getList(groups, force: force);
if (list == null) throw Exception("Could not get the list of groups!");
return list;
}
/// Get a list of groups from the server
Future<GroupsList> getList(Set<int> groups, {bool force = false}) async {
final list = GroupsList();
// Check which groups information to download
final toDownload = Set<int>();
groups.forEach((groupID) {
if (!force && _groupsListCache.containsKey(groupID))
list[groupID] = _groupsListCache[groupID];
else
toDownload.add(groupID);
});
// Download required groups information
if (toDownload.length > 0) {
final downloaded = await _downloadList(toDownload);
if (downloaded == null) return null;
list.addAll(downloaded);
_groupsListCache.addAll(downloaded);
}
return list;
}
/// Get information about a single group
///
/// Throws in case of failure
Future<Group> getSingle(int groupID, {bool force = false}) async {
return (await getListOrThrow(Set<int>()..add(groupID), force: force))
.values
.first;
}
/// Get the list of groups of a user
Future<Set<int>> getListUser() async =>
(await APIRequest(uri: "groups/get_my_list", needLogin: true).exec())
.assertOk()
.getArray()
.map((f) => cast<int>(f))
.toSet();
/// Perform a simple membership request
Future<bool> _simpleMembershipRequest(int groupID, String uri,
{Map<String, String> args}) async =>
(await (APIRequest(uri: uri, needLogin: true)
..addInt("id", groupID)
..addArgs(args == null ? Map() : args))
.exec())
.isOK;
/// Remove group membership
Future<bool> removeMembership(int groupID) async =>
_simpleMembershipRequest(groupID, "groups/remove_membership");
/// Cancel membership request
Future<bool> cancelRequest(int groupID) async =>
_simpleMembershipRequest(groupID, "groups/cancel_request");
/// Send a new membership request
Future<bool> sendRequest(int groupID) async =>
_simpleMembershipRequest(groupID, "groups/send_request");
/// Respond to a group membership invitation
Future<bool> respondInvitation(int groupID, bool accept) async =>
_simpleMembershipRequest(groupID, "groups/respond_invitation", args: {
"accept": accept ? "true" : "false",
});
/// Update group following status
Future<bool> setFollowing(int groupID, bool follow) async =>
(await (APIRequest(uri: "groups/set_following", needLogin: true)
..addInt("groupID", groupID)
..addBool("follow", follow))
.exec())
.isOK;
/// Get advanced information about the user
Future<GetAdvancedInfoResult> getAdvancedInfo(int groupID) async {
// Get advanced information about the user
final result =
await (APIRequest(uri: "groups/get_advanced_info", needLogin: true)
..addInt("id", groupID))
.exec();
switch (result.code) {
case 401:
return GetAdvancedInfoResult(GetAdvancedInfoStatus.ACCESS_DENIED, null);
case 200:
return GetAdvancedInfoResult(GetAdvancedInfoStatus.SUCCESS,
_getAdvancedGroupInfoFromAPI(result.getObject()));
default:
throw Exception("Could not get advanced group information!");
}
}
/// Turn an API entry into a group object
Group _getGroupFromAPI(Map<String, dynamic> map) {
return Group(
id: map["id"],
name: map["name"],
iconURL: map["icon_url"],
numberMembers: map["number_members"],
membershipLevel: _APIGroupsMembershipLevelsMap[map["membership"]],
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]],
registrationLevel:
_APIGroupsRegistrationLevelsMap[map["registration_level"]],
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]],
virtualDirectory: map["virtual_directory"],
following: map["following"]);
}
/// Get advanced group information
AdvancedGroupInfo _getAdvancedGroupInfoFromAPI(Map<String, dynamic> map) =>
AdvancedGroupInfo(
id: map["id"],
name: map["name"],
iconURL: map["icon_url"],
numberMembers: map["number_members"],
membershipLevel: _APIGroupsMembershipLevelsMap[map["membership"]],
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]],
registrationLevel:
_APIGroupsRegistrationLevelsMap[map["registration_level"]],
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]],
virtualDirectory: map["virtual_directory"],
following: map["following"],
timeCreate: map["time_create"],
description: map["description"],
url: map["url"],
likes: map["number_likes"],
userLike: map["is_liking"],
);
}