Files
geo/app/lib/presentation/widgets/connectivity_indicator.dart

157 lines
5.2 KiB
Dart

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<ConnectivityResult> 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<ConnectivityResult> 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;
}
}
}