Files
afterwork/lib/data/providers/friends_provider.dart
2024-11-08 20:30:23 +00:00

171 lines
6.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import '../../domain/entities/friend.dart';
import '../../data/repositories/friends_repository_impl.dart';
/// [FriendsProvider] est un `ChangeNotifier` qui gère la logique de gestion des amis.
/// Il utilise [FriendsRepositoryImpl] pour interagir avec l'API et assure la gestion des états,
/// comme le chargement, la pagination et les erreurs éventuelles.
class FriendsProvider with ChangeNotifier {
final FriendsRepositoryImpl friendsRepository;
final Logger _logger = Logger(); // Logger pour suivre toutes les actions.
// Liste privée des amis récupérée depuis l'API
List<Friend> _friendsList = [];
bool _isLoading = false; // Indique si une opération de chargement est en cours
bool _hasMore = true; // Indique s'il reste des amis à charger
int _currentPage = 0;
final int _friendsPerPage = 10; // Nombre d'amis par page pour la pagination
/// Constructeur de [FriendsProvider] qui requiert une instance de [FriendsRepositoryImpl].
FriendsProvider({required this.friendsRepository});
// Getters pour accéder aux états depuis l'interface utilisateur
bool get isLoading => _isLoading;
bool get hasMore => _hasMore;
List<Friend> get friendsList => _friendsList;
/// Récupère la liste paginée des amis pour un utilisateur donné.
///
/// [userId] : L'identifiant unique de l'utilisateur.
/// [loadMore] : Indique s'il s'agit d'une demande de chargement supplémentaire pour la pagination.
///
/// Cette méthode :
/// - Vérifie si un chargement est déjà en cours.
/// - Initialise ou poursuit la pagination.
/// - Exclut l'utilisateur lui-même de la liste.
/// - Gère les erreurs et logue chaque étape pour une traçabilité complète.
Future<void> fetchFriends(String userId, {bool loadMore = false}) async {
if (_isLoading) {
_logger.w('[LOG] Chargement déjà en cours, annulation de la nouvelle demande.');
return;
}
_isLoading = true;
notifyListeners();
_logger.i('[LOG] Début du chargement des amis pour l\'utilisateur $userId.');
// Réinitialisation uniquement si ce n'est pas un chargement supplémentaire
if (!loadMore) {
_friendsList = [];
_currentPage = 0;
_hasMore = true;
_logger.i('[LOG] Réinitialisation de la pagination et de la liste des amis.');
}
try {
_logger.i('[LOG] Chargement de la page $_currentPage des amis pour l\'utilisateur $userId.');
final newFriends = await friendsRepository.fetchFriends(userId, _currentPage, _friendsPerPage);
if (newFriends.isEmpty) {
_hasMore = false;
_logger.i('[LOG] Fin de liste atteinte, plus d\'amis à charger.');
} else {
for (var friend in newFriends) {
if (friend.friendId != userId) {
_friendsList.add(friend);
_logger.i("[LOG] Ajout de l'ami : ID = ${friend.friendId}, Nom = ${friend.friendFirstName} ${friend.friendLastName}");
} else {
_logger.w("[WARN] Exclusion de l'utilisateur lui-même de la liste d'amis : ${friend.friendId}");
}
}
_currentPage++;
_logger.i('[LOG] Page suivante préparée pour le prochain chargement, page actuelle : $_currentPage');
}
} catch (e) {
_logger.e('[ERROR] Erreur lors de la récupération des amis : $e');
} finally {
_isLoading = false;
_logger.i('[LOG] Fin du chargement des amis.');
notifyListeners();
}
}
/// Supprime un ami dans l'API et met à jour la liste localement.
///
/// [friendId] : Identifiant unique de l'ami à supprimer.
///
/// Loggue chaque étape pour assurer un suivi précis de l'opération.
Future<void> removeFriend(String friendId) async {
try {
_logger.i('[LOG] Tentative de suppression de l\'ami avec l\'ID : $friendId');
await friendsRepository.removeFriend(friendId);
_friendsList.removeWhere((friend) => friend.friendId == friendId);
_logger.i('[LOG] Ami supprimé localement avec succès : $friendId');
} catch (e) {
_logger.e('[ERROR] Erreur lors de la suppression de l\'ami : $e');
} finally {
notifyListeners();
}
}
/// Récupère les détails d'un ami via l'API.
///
/// [userId] : L'identifiant de l'utilisateur connecté.
/// [friendId] : Identifiant unique de l'ami.
///
/// Retourne un `Future<Friend?>` contenant les détails ou `null` en cas d'erreur.
Future<Friend?> fetchFriendDetails(String userId, String friendId) async {
try {
_logger.i('[LOG] Tentative de récupération des détails de l\'ami avec l\'ID : $friendId');
final friendDetails = await friendsRepository.getFriendDetails(friendId, userId);
if (friendDetails != null) {
_logger.i('[LOG] Détails de l\'ami récupérés avec succès : ${friendDetails.friendId}');
} else {
_logger.w('[LOG] Détails de l\'ami introuvables pour l\'ID : $friendId');
}
return friendDetails;
} catch (e) {
_logger.e('[ERROR] Exception lors de la récupération des détails de l\'ami : $e');
return null;
}
}
/// Convertit un statut sous forme de chaîne en [FriendStatus].
///
/// [status] : Le statut sous forme de chaîne.
///
/// Retourne un [FriendStatus] correspondant, ou `FriendStatus.unknown` si non reconnu.
FriendStatus _convertToFriendStatus(String status) {
switch (status.toLowerCase()) {
case 'pending':
return FriendStatus.pending;
case 'accepted':
return FriendStatus.accepted;
case 'blocked':
return FriendStatus.blocked;
default:
return FriendStatus.unknown;
}
}
/// Met à jour le statut d'un ami (par exemple : accepter, bloquer).
///
/// [friendId] : Identifiant unique de l'ami.
/// [status] : Nouveau statut pour l'ami sous forme de chaîne de caractères.
///
/// Loggue l'action, convertit le statut en `FriendStatus`, et met à jour la liste localement.
Future<void> updateFriendStatus(String friendId, String status) async {
try {
_logger.i('[LOG] Tentative de mise à jour du statut de l\'ami avec l\'ID : $friendId');
// Conversion du `String` en `FriendStatus` pour l'update locale
final friendStatus = _convertToFriendStatus(status);
await friendsRepository.updateFriendStatus(friendId, status);
// Mise à jour locale de la liste pour afficher le changement de statut
final friendIndex = _friendsList.indexWhere((friend) => friend.friendId == friendId);
if (friendIndex != -1) {
_friendsList[friendIndex] = _friendsList[friendIndex].copyWith(status: friendStatus);
_logger.i('[LOG] Statut de l\'ami mis à jour localement pour l\'ID : $friendId');
}
} catch (e) {
_logger.e('[ERROR] Erreur lors de la mise à jour du statut de l\'ami : $e');
} finally {
notifyListeners();
}
}
}