feat: Release version 3.1.4 - Mode terrain et génération PDF
✨ Nouvelles fonctionnalités: - Ajout du mode terrain pour utilisation mobile hors connexion - Génération automatique de reçus PDF avec template personnalisé - Révision complète du système de cartes avec amélioration des performances 🔧 Améliorations techniques: - Refactoring du module chat avec architecture simplifiée - Optimisation du système de sécurité NIST SP 800-63B - Amélioration de la gestion des secteurs géographiques - Support UTF-8 étendu pour les noms d'utilisateurs 📱 Application mobile: - Nouveau mode terrain dans user_field_mode_page - Interface utilisateur adaptative pour conditions difficiles - Synchronisation offline améliorée 🗺️ Cartographie: - Optimisation des performances MapBox - Meilleure gestion des tuiles hors ligne - Amélioration de l'affichage des secteurs 📄 Documentation: - Ajout guide Android (ANDROID-GUIDE.md) - Documentation sécurité API (API-SECURITY.md) - Guide module chat (CHAT_MODULE.md) 🐛 Corrections: - Résolution des erreurs 400 lors de la création d'utilisateurs - Correction de la validation des noms d'utilisateurs - Fix des problèmes de synchronisation chat 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ class AppKeys {
|
||||
static const String settingsBoxName = 'settings';
|
||||
static const String membresBoxName = 'membres';
|
||||
static const String userSectorBoxName = 'user_sector';
|
||||
static const String chatConversationsBoxName = 'chat_conversations';
|
||||
static const String chatRoomsBoxName = 'chat_rooms';
|
||||
static const String chatMessagesBoxName = 'chat_messages';
|
||||
static const String regionsBoxName = 'regions';
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/presentation/widgets/loading_spin_overlay.dart';
|
||||
import 'package:geosector_app/core/models/loading_state.dart';
|
||||
import 'package:geosector_app/chat/services/chat_info_service.dart';
|
||||
|
||||
class UserRepository extends ChangeNotifier {
|
||||
bool _isLoading = false;
|
||||
@@ -276,7 +277,17 @@ class UserRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Étape 5: Traitement de toutes les autres données via DataLoadingService
|
||||
// Étape 5: Traitement des infos chat
|
||||
if (apiResult['chat'] != null) {
|
||||
try {
|
||||
ChatInfoService.instance.updateFromLogin(apiResult);
|
||||
debugPrint('💬 Infos chat mises à jour');
|
||||
} catch (chatError) {
|
||||
debugPrint('⚠️ Erreur traitement infos chat: $chatError');
|
||||
}
|
||||
}
|
||||
|
||||
// Étape 6: Traitement de toutes les autres données via DataLoadingService
|
||||
try {
|
||||
await DataLoadingService.instance.processLoginData(apiResult);
|
||||
} catch (processingError) {
|
||||
@@ -316,6 +327,9 @@ class UserRepository extends ChangeNotifier {
|
||||
// Effacer les données via les services singleton
|
||||
await CurrentUserService.instance.clearUser();
|
||||
await CurrentAmicaleService.instance.clearAmicale();
|
||||
|
||||
// Réinitialiser les infos chat
|
||||
ChatInfoService.instance.reset();
|
||||
|
||||
// Nettoyage des données via HiveService (préserve les utilisateurs)
|
||||
await HiveService.instance.cleanDataOnLogout();
|
||||
|
||||
@@ -65,6 +65,14 @@ class ConnectivityService extends ChangeNotifier {
|
||||
|
||||
/// Constructeur du service de connectivité
|
||||
ConnectivityService() {
|
||||
// Initialiser avec une connexion par défaut (supposée disponible)
|
||||
// Ceci sera mis à jour rapidement par _initConnectivity()
|
||||
if (kIsWeb) {
|
||||
_connectionStatus = [ConnectivityResult.wifi];
|
||||
} else {
|
||||
// Sur mobile, on suppose qu'il y a au moins une connexion jusqu'à vérification
|
||||
_connectionStatus = [ConnectivityResult.wifi];
|
||||
}
|
||||
_initConnectivity();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
import 'package:geosector_app/core/repositories/client_repository.dart';
|
||||
import 'package:geosector_app/chat/models/conversation_model.dart';
|
||||
import 'package:geosector_app/chat/models/message_model.dart';
|
||||
// Chat imports removed - using new simplified chat module
|
||||
import 'package:geosector_app/core/models/loading_state.dart';
|
||||
|
||||
/// Service singleton pour gérer le chargement et la gestion des données au login
|
||||
@@ -54,10 +53,7 @@ class DataLoadingService extends ChangeNotifier {
|
||||
Hive.box<UserSectorModel>(AppKeys.userSectorBoxName);
|
||||
Box<AmicaleModel> get _amicaleBox =>
|
||||
Hive.box<AmicaleModel>(AppKeys.amicaleBoxName);
|
||||
Box<ConversationModel> get _chatConversationBox =>
|
||||
Hive.box<ConversationModel>(AppKeys.chatConversationsBoxName);
|
||||
Box<MessageModel> get _chatMessageBox =>
|
||||
Hive.box<MessageModel>(AppKeys.chatMessagesBoxName);
|
||||
// Chat boxes removed - handled by new chat module
|
||||
Box get _settingsBox => Hive.box(AppKeys.settingsBoxName);
|
||||
|
||||
/// Traite toutes les données reçues de l'API lors du login
|
||||
@@ -569,7 +565,7 @@ class DataLoadingService extends ChangeNotifier {
|
||||
AppKeys.membresBoxName,
|
||||
AppKeys.userSectorBoxName,
|
||||
AppKeys.amicaleBoxName,
|
||||
AppKeys.chatConversationsBoxName,
|
||||
AppKeys.chatRoomsBoxName,
|
||||
AppKeys.chatMessagesBoxName,
|
||||
AppKeys.settingsBoxName,
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||
import 'package:geosector_app/core/data/models/region_model.dart';
|
||||
import 'package:geosector_app/chat/models/chat_adapters.dart';
|
||||
// Chat adapters removed - handled by new chat module
|
||||
|
||||
class HiveAdapters {
|
||||
/// Enregistre tous les TypeAdapters nécessaires
|
||||
@@ -42,24 +42,7 @@ class HiveAdapters {
|
||||
Hive.registerAdapter(AmicaleModelAdapter());
|
||||
}
|
||||
|
||||
// Chat adapters
|
||||
if (!Hive.isAdapterRegistered(20)) {
|
||||
Hive.registerAdapter(ConversationModelAdapter());
|
||||
}
|
||||
if (!Hive.isAdapterRegistered(21)) {
|
||||
Hive.registerAdapter(MessageModelAdapter());
|
||||
}
|
||||
if (!Hive.isAdapterRegistered(22)) {
|
||||
Hive.registerAdapter(ParticipantModelAdapter());
|
||||
}
|
||||
if (!Hive.isAdapterRegistered(23)) {
|
||||
Hive.registerAdapter(AnonymousUserModelAdapter());
|
||||
}
|
||||
if (!Hive.isAdapterRegistered(24)) {
|
||||
Hive.registerAdapter(AudienceTargetModelAdapter());
|
||||
}
|
||||
if (!Hive.isAdapterRegistered(25)) {
|
||||
Hive.registerAdapter(NotificationSettingsAdapter());
|
||||
}
|
||||
// Chat adapters are now handled by the chat module itself
|
||||
// TypeIds 50-60 are reserved for chat module
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||
import 'package:geosector_app/core/data/models/region_model.dart';
|
||||
import 'package:geosector_app/chat/models/chat_adapters.dart';
|
||||
import 'package:geosector_app/chat/models/room.dart';
|
||||
import 'package:geosector_app/chat/models/message.dart';
|
||||
|
||||
/// Service pour réinitialiser et recréer les Hive Boxes
|
||||
/// Utilisé pour résoudre les problèmes d'incompatibilité après mise à jour des modèles
|
||||
@@ -91,12 +92,8 @@ class HiveResetService {
|
||||
Hive.registerAdapter(UserSectorModelAdapter());
|
||||
|
||||
// Enregistrer les adaptateurs pour le chat
|
||||
Hive.registerAdapter(ConversationModelAdapter());
|
||||
Hive.registerAdapter(MessageModelAdapter());
|
||||
Hive.registerAdapter(ParticipantModelAdapter());
|
||||
Hive.registerAdapter(AnonymousUserModelAdapter());
|
||||
Hive.registerAdapter(AudienceTargetModelAdapter());
|
||||
Hive.registerAdapter(NotificationSettingsAdapter());
|
||||
Hive.registerAdapter(RoomAdapter());
|
||||
Hive.registerAdapter(MessageAdapter());
|
||||
|
||||
// Vérifier si RegionModelAdapter est disponible
|
||||
try {
|
||||
@@ -117,7 +114,7 @@ class HiveResetService {
|
||||
await Hive.openBox(AppKeys.settingsBoxName);
|
||||
|
||||
// Ouvrir les boîtes de chat
|
||||
await Hive.openBox<ConversationModel>(AppKeys.chatConversationsBoxName);
|
||||
await Hive.openBox<MessageModel>(AppKeys.chatMessagesBoxName);
|
||||
await Hive.openBox<Room>(AppKeys.chatRoomsBoxName);
|
||||
await Hive.openBox<Message>(AppKeys.chatMessagesBoxName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ import 'package:geosector_app/core/data/models/sector_model.dart';
|
||||
import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||
import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||
import 'package:geosector_app/chat/models/conversation_model.dart';
|
||||
import 'package:geosector_app/chat/models/message_model.dart';
|
||||
// Chat imports removed - using new simplified chat module
|
||||
|
||||
/// Service singleton centralisé pour la gestion complète des Box Hive
|
||||
/// Utilisé par main.dart pour l'initialisation et par logout pour le nettoyage
|
||||
@@ -35,8 +34,7 @@ class HiveService {
|
||||
HiveBoxConfig<PassageModel>(AppKeys.passagesBoxName, 'PassageModel'),
|
||||
HiveBoxConfig<MembreModel>(AppKeys.membresBoxName, 'MembreModel'),
|
||||
HiveBoxConfig<UserSectorModel>(AppKeys.userSectorBoxName, 'UserSectorModel'),
|
||||
HiveBoxConfig<ConversationModel>(AppKeys.chatConversationsBoxName, 'ConversationModel'),
|
||||
HiveBoxConfig<MessageModel>(AppKeys.chatMessagesBoxName, 'MessageModel'),
|
||||
// Chat boxes removed - handled by new chat module
|
||||
HiveBoxConfig<dynamic>(AppKeys.settingsBoxName, 'Settings'),
|
||||
HiveBoxConfig<dynamic>(AppKeys.regionsBoxName, 'Regions'),
|
||||
];
|
||||
@@ -403,12 +401,7 @@ class HiveService {
|
||||
case 'UserSectorModel':
|
||||
await Hive.openBox<UserSectorModel>(config.name);
|
||||
break;
|
||||
case 'ConversationModel':
|
||||
await Hive.openBox<ConversationModel>(config.name);
|
||||
break;
|
||||
case 'MessageModel':
|
||||
await Hive.openBox<MessageModel>(config.name);
|
||||
break;
|
||||
// Chat boxes removed - handled by new chat module
|
||||
default:
|
||||
// Pour Settings, Regions, etc.
|
||||
await Hive.openBox(config.name);
|
||||
@@ -455,6 +448,37 @@ class HiveService {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Vérification rapide que les boxes critiques sont initialisées
|
||||
/// Utilisé par LoginPage pour détecter si une redirection vers SplashPage est nécessaire
|
||||
bool areBoxesInitialized() {
|
||||
try {
|
||||
// Vérifier seulement les boxes critiques pour le login
|
||||
final criticalBoxes = [
|
||||
AppKeys.userBoxName, // Nécessaire pour getCurrentUser
|
||||
AppKeys.membresBoxName, // Nécessaire pour le pré-remplissage
|
||||
AppKeys.settingsBoxName, // Nécessaire pour les préférences
|
||||
];
|
||||
|
||||
for (final boxName in criticalBoxes) {
|
||||
if (!Hive.isBoxOpen(boxName)) {
|
||||
debugPrint('⚠️ Box critique non ouverte: $boxName');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Vérifier aussi le flag d'initialisation
|
||||
if (!_isInitialized) {
|
||||
debugPrint('⚠️ HiveService non initialisé');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur vérification boxes: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Récupération sécurisée d'une Box typée
|
||||
Box<T> getTypedBox<T>(String boxName) {
|
||||
if (!Hive.isBoxOpen(boxName)) {
|
||||
|
||||
Reference in New Issue
Block a user