import 'dart:async'; import 'package:flutter/material.dart'; import '../../core/utils/app_logger.dart'; import '../services/realtime_notification_service.dart'; /// Provider pour gérer la présence utilisateur (online/offline). /// /// Ce provider : /// - Écoute les mises à jour de présence via WebSocket /// - Maintient une map userId -> isOnline /// - Envoie un heartbeat toutes les 25 secondes pour maintenir le statut online /// - Notifie les widgets qui écoutent lors des changements de présence class PresenceProvider extends ChangeNotifier { PresenceProvider(); // Map userId -> isOnline final Map _presenceMap = {}; RealtimeNotificationService? _realtimeService; StreamSubscription? _presenceSubscription; Timer? _heartbeatTimer; /// Obtenir le statut online d'un utilisateur. bool isUserOnline(String userId) { return _presenceMap[userId] ?? false; } /// Connecter au service temps réel et démarrer heartbeat. void connectRealtime(RealtimeNotificationService service) { _realtimeService = service; // Écouter les mises à jour de présence _presenceSubscription = service.presenceStream.listen((update) { _presenceMap[update.userId] = update.isOnline; notifyListeners(); AppLogger.i( 'Présence mise à jour: ${update.userId} -> ${update.isOnline}', tag: 'PresenceProvider', ); }); // Démarrer heartbeat (toutes les 25 secondes) _startHeartbeat(); AppLogger.i('PresenceProvider connecté', tag: 'PresenceProvider'); } /// Démarrer le heartbeat pour maintenir le statut online. void _startHeartbeat() { _heartbeatTimer?.cancel(); _heartbeatTimer = Timer.periodic( const Duration(seconds: 25), (_) { _realtimeService?.sendHeartbeat(); AppLogger.d('Heartbeat envoyé', tag: 'PresenceProvider'); }, ); } /// Déconnecter et arrêter le heartbeat. void disconnectRealtime() { _presenceSubscription?.cancel(); _presenceSubscription = null; _heartbeatTimer?.cancel(); _heartbeatTimer = null; _realtimeService = null; _presenceMap.clear(); notifyListeners(); AppLogger.i('PresenceProvider déconnecté', tag: 'PresenceProvider'); } @override void dispose() { disconnectRealtime(); super.dispose(); } }