- Ajout système complet de gestion des secteurs avec contours géographiques - Import des contours départementaux depuis GeoJSON - API REST pour la gestion des secteurs (/api/sectors) - Service de géolocalisation pour déterminer les secteurs - Migration base de données avec tables x_departements_contours et sectors_adresses - Interface Flutter pour visualisation et gestion des secteurs - Ajout thème sombre dans l'application - Corrections diverses et optimisations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
156 lines
5.1 KiB
Dart
Executable File
156 lines
5.1 KiB
Dart
Executable File
import 'package:flutter/material.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;
|
|
}
|
|
}
|
|
}
|