|
|
@@ -0,0 +1,114 @@
|
|
|
+import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
+import 'package:physigo/friends/models/friend_request.dart';
|
|
|
+import '../models/friend.dart';
|
|
|
+import '../models/friend_relation.dart';
|
|
|
+
|
|
|
+const userId = "tlmysIvwTBaoZKWqBofx";
|
|
|
+
|
|
|
+class FriendsService {
|
|
|
+ static final _db = FirebaseFirestore.instance;
|
|
|
+ static final _friends = _db.collection("Friends");
|
|
|
+ static final _users = _db.collection("Users");
|
|
|
+
|
|
|
+ static Future<List<Friend>> getFriends() async {
|
|
|
+ return _getFriendsByStatus(RequestStatus.accepted);
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<List<FriendRequest>> getPendingRequests() async {
|
|
|
+ final friendRequests =
|
|
|
+ await _friends.where("friend_id", isEqualTo: userId).where("request_status", isEqualTo: "pending").get();
|
|
|
+ if (friendRequests.docs.isEmpty) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ final friendsIdRequestsId = {for (final r in friendRequests.docs) r.data()['user_id']: r.id};
|
|
|
+ final friendsInfo = await _users.where(FieldPath.documentId, whereIn: friendsIdRequestsId.keys.toList()).get();
|
|
|
+ return friendsInfo.docs
|
|
|
+ .map((f) => FriendRequest(
|
|
|
+ requestId: friendsIdRequestsId[f.id]!,
|
|
|
+ friendName: f.data()['name'],
|
|
|
+ friendSurname: f.data()['surname'],
|
|
|
+ ))
|
|
|
+ .toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<void> addFriend(String friendSharedId) async {
|
|
|
+ try {
|
|
|
+ final query = (await _users.where("shared_id", isEqualTo: friendSharedId).get());
|
|
|
+ if (query.docs.isEmpty) {
|
|
|
+ return Future.error("This account doesn't exist");
|
|
|
+ }
|
|
|
+ final friend = query.docs.first;
|
|
|
+ await _checkExistingFriendRelation(friend.id);
|
|
|
+ final friendRequest = {"user_id": userId, "friend_id": friend.id, "request_status": "pending"};
|
|
|
+ await _friends.add(friendRequest);
|
|
|
+ } catch (error) {
|
|
|
+ return Future.error(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<void> acceptFriendRequest(FriendRequest friendRequest) async {
|
|
|
+ final newStatus = {"request_status": "accepted"};
|
|
|
+ await _friends.doc(friendRequest.requestId).update(newStatus);
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<void> refuseFriendRequest(FriendRequest friendRequest) async {
|
|
|
+ final newStatus = {"request_status": "rejected"};
|
|
|
+ await _friends.doc(friendRequest.requestId).update(newStatus);
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<List<Friend>> _getFriendsByStatus(RequestStatus status) async {
|
|
|
+ final friendsByUserId = _friends.where("user_id", isEqualTo: userId).get();
|
|
|
+ final friendsByFriendId = _friends.where("friend_id", isEqualTo: userId).get();
|
|
|
+ final friendRelations = (await Future.wait([friendsByUserId, friendsByFriendId]))
|
|
|
+ .expand((query) => query.docs)
|
|
|
+ .map((friendRelation) => FriendRelation.fromMap(friendRelation.id, friendRelation.data(), userId))
|
|
|
+ .where((friendRelation) => friendRelation.requestStatus == status)
|
|
|
+ .toList();
|
|
|
+
|
|
|
+ final friends = await _getFriendsFromFriendRelations(friendRelations);
|
|
|
+ return friends;
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<List<Friend>> _getFriendsFromFriendRelations(List<FriendRelation> friendRelations) async {
|
|
|
+ final users = await _db
|
|
|
+ .collection('Users')
|
|
|
+ .where(FieldPath.documentId, whereIn: friendRelations.map((e) => e.friendId).toList())
|
|
|
+ .get();
|
|
|
+ final friends = users.docs.map((friend) {
|
|
|
+ final data = friend.data();
|
|
|
+ final friendRelation = friendRelations.firstWhere((element) => element.friendId == friend.id);
|
|
|
+ return Friend(
|
|
|
+ id: friend.id,
|
|
|
+ name: data['name'],
|
|
|
+ surname: data['surname'],
|
|
|
+ status: friendRelation.requestStatus,
|
|
|
+ relationId: friendRelation.id,
|
|
|
+ );
|
|
|
+ }).toList();
|
|
|
+ return friends;
|
|
|
+ }
|
|
|
+
|
|
|
+ static Future<void> _checkExistingFriendRelation(String friendId) async {
|
|
|
+ if (friendId == userId) {
|
|
|
+ return Future.error("You already are your own friend");
|
|
|
+ }
|
|
|
+
|
|
|
+ var friendRelation = await _db
|
|
|
+ .collection("Friends")
|
|
|
+ .where("user_id", isEqualTo: userId)
|
|
|
+ .where("friend_id", isEqualTo: friendId)
|
|
|
+ .get();
|
|
|
+ if (friendRelation.docs.isNotEmpty) {
|
|
|
+ return Future.error("You already sent a request to this person");
|
|
|
+ }
|
|
|
+
|
|
|
+ friendRelation = await _db
|
|
|
+ .collection("Friends")
|
|
|
+ .where("friend_id", isEqualTo: userId)
|
|
|
+ .where("user_id", isEqualTo: friendId)
|
|
|
+ .get();
|
|
|
+ if (friendRelation.docs.isNotEmpty) {
|
|
|
+ return Future.error("They already sent you a request");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|