feat: Version 3.6.3 - Carte IGN, mode boussole, corrections Flutter analyze

Nouvelles fonctionnalités:
- #215 Mode boussole + carte IGN/satellite (Mode terrain)
- #53 Définition zoom maximal pour éviter sur-zoom
- #14 Correction bug F5 déconnexion
- #204 Design couleurs flashy
- #205 Écrans utilisateurs simplifiés

Corrections Flutter analyze:
- Suppression warnings room.g.dart, chat_service.dart, api_service.dart
- 0 error, 0 warning, 30 infos (suggestions de style)

Autres:
- Intégration tuiles IGN Plan et IGN Ortho (geopf.fr)
- flutter_compass pour Android/iOS
- Réorganisation assets store

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 17:46:03 +01:00
parent 232940b1eb
commit 5b6808db25
62 changed files with 1428 additions and 3130 deletions

View File

@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:geosector_app/core/theme/app_theme.dart';
import 'package:geosector_app/core/services/theme_service.dart';
import 'package:go_router/go_router.dart';
// Import conditionnel pour le web
import 'package:universal_html/html.dart' as html;
import 'package:geosector_app/core/services/current_user_service.dart';
import 'package:geosector_app/core/repositories/user_repository.dart';
@@ -45,10 +48,80 @@ class GeosectorApp extends StatefulWidget {
}
class _GeosectorAppState extends State<GeosectorApp> with WidgetsBindingObserver {
// Clé globale pour accéder au contexte de l'app (pour les dialogues)
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// Sur Web, intercepter F5 / Ctrl+R pour proposer un refresh des données
if (kIsWeb) {
_setupF5Interceptor();
}
}
/// Configure l'interception de F5/Ctrl+R sur Web
void _setupF5Interceptor() {
html.window.onKeyDown.listen((event) {
// Détecter F5 ou Ctrl+R
final isF5 = event.key == 'F5';
final isCtrlR = (event.ctrlKey || event.metaKey) && event.key?.toLowerCase() == 'r';
if (isF5 || isCtrlR) {
event.preventDefault();
debugPrint('🔄 F5/Ctrl+R intercepté - Affichage du dialogue de refresh');
_showRefreshDialog();
}
});
debugPrint('🌐 Intercepteur F5/Ctrl+R configuré pour Web');
}
/// Affiche le dialogue de confirmation de refresh
void _showRefreshDialog() {
final context = navigatorKey.currentContext;
if (context == null) {
debugPrint('⚠️ Impossible d\'afficher le dialogue - contexte non disponible');
return;
}
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext dialogContext) {
return AlertDialog(
title: const Row(
children: [
Icon(Icons.refresh, color: Colors.blue),
SizedBox(width: 12),
Text('Recharger les données ?'),
],
),
content: const Text(
'Voulez-vous actualiser vos données depuis le serveur ?\n\n'
'Vos modifications non synchronisées seront conservées.',
),
actions: [
TextButton(
onPressed: () {
Navigator.of(dialogContext).pop();
debugPrint('❌ Refresh annulé par l\'utilisateur');
},
child: const Text('Non'),
),
ElevatedButton(
onPressed: () {
Navigator.of(dialogContext).pop();
debugPrint('✅ Refresh demandé par l\'utilisateur');
// TODO: Implémenter le refresh des données via API
},
child: const Text('Oui, recharger'),
),
],
);
},
);
}
@override
@@ -159,6 +232,7 @@ class _GeosectorAppState extends State<GeosectorApp> with WidgetsBindingObserver
/// Création du routeur avec configuration pour URLs propres
GoRouter _createRouter() {
return GoRouter(
navigatorKey: navigatorKey,
initialLocation: '/',
routes: [
GoRoute(