import 'package:flutter/material.dart'; import 'package:geosector_app/core/services/connectivity_service.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales /// Widget qui affiche l'état de la connexion Internet class ConnectivityIndicator extends StatelessWidget { /// Si true, affiche un message d'erreur lorsque l'appareil est déconnecté final bool showErrorMessage; /// Si true, affiche un badge avec le type de connexion (WiFi, données mobiles) final bool showConnectionType; /// Callback appelé lorsque l'état de la connexion change final Function(bool isConnected)? onConnectivityChanged; const ConnectivityIndicator({ super.key, this.showErrorMessage = true, this.showConnectionType = true, this.onConnectivityChanged, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); // Utiliser l'instance globale de connectivityService définie dans app.dart final isConnected = connectivityService.isConnected; final connectionType = connectivityService.connectionType; final connectionStatus = connectivityService.connectionStatus; // Appeler le callback si fourni, mais pas directement dans le build // pour éviter les problèmes de rendu WidgetsBinding.instance.addPostFrameCallback((_) { if (onConnectivityChanged != null) { onConnectivityChanged!(isConnected); } }); if (!isConnected && showErrorMessage) { return Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), margin: const EdgeInsets.only(bottom: 8), decoration: BoxDecoration( color: theme.colorScheme.error.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all( color: theme.colorScheme.error.withOpacity(0.3), ), ), child: Row( children: [ Icon( Icons.wifi_off, color: theme.colorScheme.error, size: 18, ), const SizedBox(width: 8), Expanded( child: Text( 'Aucune connexion Internet. Certaines fonctionnalités peuvent être limitées.', style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.error, ), ), ), ], ), ); } else if (isConnected && showConnectionType) { // Obtenir la couleur et l'icône en fonction du type de connexion final color = _getConnectionColor(connectionStatus, theme); final icon = _getConnectionIcon(connectionStatus); return Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all( color: color.withOpacity(0.3), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, color: color, size: 14, ), const SizedBox(width: 4), Text( connectionType, style: theme.textTheme.bodySmall?.copyWith( color: color, fontWeight: FontWeight.bold, ), ), ], ), ); } // Si aucune condition n'est remplie ou si showErrorMessage et showConnectionType sont false return const SizedBox.shrink(); } /// Retourne l'icône correspondant au type de connexion IconData _getConnectionIcon(List statusList) { // Utiliser le premier type de connexion qui n'est pas 'none' ConnectivityResult status = statusList.firstWhere( (result) => result != ConnectivityResult.none, orElse: () => ConnectivityResult.none); switch (status) { case ConnectivityResult.wifi: return Icons.wifi; case ConnectivityResult.mobile: return Icons.signal_cellular_alt; case ConnectivityResult.ethernet: return Icons.lan; case ConnectivityResult.bluetooth: return Icons.bluetooth; case ConnectivityResult.vpn: return Icons.vpn_key; default: return Icons.wifi_off; } } /// Retourne la couleur correspondant au type de connexion Color _getConnectionColor( List statusList, ThemeData theme) { // Utiliser le premier type de connexion qui n'est pas 'none' ConnectivityResult status = statusList.firstWhere( (result) => result != ConnectivityResult.none, orElse: () => ConnectivityResult.none); switch (status) { case ConnectivityResult.wifi: return Colors.green; case ConnectivityResult.mobile: return Colors.blue; case ConnectivityResult.ethernet: return Colors.purple; case ConnectivityResult.bluetooth: return Colors.indigo; case ConnectivityResult.vpn: return Colors.orange; default: return theme.colorScheme.error; } } }