import 'package:comunic/enums/user_page_visibility.dart'; import 'package:comunic/helpers/database/users_database_helper.dart'; import 'package:comunic/lists/custom_emojies_list.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/advanced_user_info.dart'; import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/custom_emoji.dart'; import 'package:comunic/models/user.dart'; /// User helper /// /// Helper used to get information about the users of Comunic /// /// @author Pierre HUBERT /// Handle advanced information error enum GetUserAdvancedInformationErrorCause { NOT_FOUND, NETWORK_ERROR, NOT_AUTHORIZED } class GetUserAdvancedUserError extends Error { final GetUserAdvancedInformationErrorCause cause; GetUserAdvancedUserError(this.cause) : assert(cause != null); } class UsersHelper { final UsersDatabaseHelper _usersDatabaseHelper = UsersDatabaseHelper(); /// Download information about some given users ID /// /// Return the list of users information in case of success, null in case of /// failure Future _downloadInfo(List users) async { // Execute the request final response = await APIRequest( uri: "user/getInfoMultiple", needLogin: true, args: {"usersID": users.join(",")}).exec(); // Check if the request did not execute correctly if (response.code != 200) return null; final list = UsersList(); response.getObject().forEach( (k, v) => list.add( User( id: v["userID"], firstName: v["firstName"], lastName: v["lastName"], pageVisibility: v["publicPage"] == "false" ? UserPageVisibility.PRIVATE : (v["openPage"] == "false" ? UserPageVisibility.PRIVATE : UserPageVisibility.OPEN), virtualDirectory: v["virtualDirectory"] == "" ? null : v["virtualDirectory"], accountImageURL: v["accountImage"], customEmojies: _parseCustomEmojies(v["customEmojis"]), ), ), ); // Save the list _usersDatabaseHelper.insertOrUpdateAll(list); return list; } /// Get users information from a given [Set]. Throws an exception in case /// of failure Future getListWithThrow(Set users, {bool forceDownload = false}) async { final list = await getUsersInfo(users.toList(), forceDownload: forceDownload); if (list == null) throw Exception( "Could not get information about the given list of users!"); return list; } /// Get information about a single user. Throws in case of failure Future getSingleWithThrow(int user, {bool forceDownload = false}) async { return (await getListWithThrow(Set()..add(user), forceDownload: forceDownload))[0]; } /// Get users information from a given [Set] Future getList(Set users, {bool forceDownload = false}) async { return await getUsersInfo(users.toList()); } /// Get users information /// /// If [forceDownload] is set to true, the data will always be retrieved from /// the server, otherwise cached data will be used if available Future getUsersInfo(List users, {bool forceDownload = false}) async { List toDownload = List(); UsersList list = UsersList(); // Check cache for (int userID in users) { if (!forceDownload && await _usersDatabaseHelper.has(userID)) list.add(await _usersDatabaseHelper.get(userID)); else toDownload.add(userID); } // Process download if required if (toDownload.length > 0) { final downloadedList = await _downloadInfo(toDownload); if (downloadedList == null) return null; list.addAll(downloadedList); } return list; } /// Try to fetch advanced information about a user Future getAdvancedInfo(int id) async { final response = await APIRequest( uri: "user/getAdvancedUserInfo", needLogin: true, args: {"userID": id.toString()}).exec(); // Handle exceptions if (response.code != 200) { var cause = GetUserAdvancedInformationErrorCause.NETWORK_ERROR; if (response.code == 404) cause = GetUserAdvancedInformationErrorCause.NOT_FOUND; if (response.code == 401) cause = GetUserAdvancedInformationErrorCause.NOT_AUTHORIZED; throw new GetUserAdvancedUserError(cause); } final data = response.getObject(); return AdvancedUserInfo( id: data["userID"], firstName: data["firstName"], lastName: data["lastName"], pageVisibility: data["publicPage"] == "false" ? UserPageVisibility.PRIVATE : (data["openPage"] == "false" ? UserPageVisibility.PRIVATE : UserPageVisibility.OPEN), virtualDirectory: data["virtualDirectory"] == "" ? null : data["virtualDirectory"], accountImageURL: data["accountImage"], customEmojies: _parseCustomEmojies(data["customEmojis"]), publicNote: data["publicNote"], canPostTexts: data["can_post_texts"], ); } /// Parse the list of custom emojies CustomEmojiesList _parseCustomEmojies(List list) { final l = list.cast>(); return CustomEmojiesList() ..addAll(l .map((f) => CustomEmoji( id: f["id"], userID: f["userID"], shortcut: f["shortcut"], url: f["url"], )) .toList()); } }