Amélioration de la splash_page et du login
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:geosector_app/core/repositories/user_repository.dart';
|
||||
import 'package:geosector_app/core/theme/app_theme.dart';
|
||||
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
||||
import 'package:geosector_app/core/services/app_info_service.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
import 'package:geosector_app/core/data/models/user_model.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
@@ -15,10 +13,11 @@ 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';
|
||||
import 'package:geosector_app/core/services/hive_reset_state_service.dart';
|
||||
import 'package:geosector_app/presentation/widgets/clear_cache_dialog.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class SplashPage extends StatefulWidget {
|
||||
const SplashPage({super.key});
|
||||
@@ -58,12 +57,28 @@ class _SplashPageState extends State<SplashPage>
|
||||
String _statusMessage = "Initialisation...";
|
||||
double _progress = 0.0;
|
||||
bool _showButtons = false;
|
||||
String _appVersion = '';
|
||||
|
||||
final List<String> _initializationSteps = [
|
||||
"Initialisation des services...",
|
||||
"Vérification de l'authentification...",
|
||||
"Chargement des données..."
|
||||
];
|
||||
Future<void> _getAppVersion() async {
|
||||
try {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = packageInfo.version;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de la version: $e');
|
||||
// Fallback sur la version du AppInfoService si elle existe
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = AppInfoService.fullVersion
|
||||
.split(' ')
|
||||
.last; // Extraire juste le numéro
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -89,33 +104,12 @@ class _SplashPageState extends State<SplashPage>
|
||||
// Démarrer l'animation immédiatement
|
||||
_animationController.forward();
|
||||
|
||||
// Vérifier si Hive a été réinitialisé
|
||||
_checkHiveReset();
|
||||
_getAppVersion();
|
||||
|
||||
// Simuler le processus d'initialisation
|
||||
_startInitialization();
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si Hive a été réinitialisé et afficher le dialogue si nécessaire
|
||||
void _checkHiveReset() {
|
||||
// Vérifier si Hive a été réinitialisé et si le dialogue n'a pas encore été affiché
|
||||
if (hiveResetStateService.wasReset && !hiveResetStateService.dialogShown) {
|
||||
// Attendre que le widget soit complètement construit
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
// Afficher le dialogue de nettoyage du cache
|
||||
ClearCacheDialog.show(
|
||||
context,
|
||||
onClose: () {
|
||||
// Marquer le dialogue comme ayant été affiché
|
||||
hiveResetStateService.markDialogAsShown();
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_animationController.dispose();
|
||||
@@ -123,11 +117,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
}
|
||||
|
||||
void _startInitialization() async {
|
||||
// Étape 1: Initialisation des services
|
||||
// Étape 1: Initialisation des boîtes Hive (0% à 75%)
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[0];
|
||||
_progress = 0.2;
|
||||
_statusMessage = "Initialisation des données...";
|
||||
_progress = 0.0;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,20 +129,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
await _initializeAllHiveBoxes();
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// Étape 2: Vérification de l'authentification
|
||||
// Étape 2: Initialisation des services (75% à 100%)
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[1];
|
||||
_progress = 0.4;
|
||||
});
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// Étape 3: Chargement des données
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[2];
|
||||
_progress = 1.0; // Directement à 100% après la 3ème étape
|
||||
_statusMessage = "Préparation de l'application...";
|
||||
_progress = 0.75;
|
||||
});
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
@@ -157,15 +142,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
setState(() {
|
||||
_isInitializing = false;
|
||||
_showButtons = true;
|
||||
_progress = 1.0; // S'assurer que la barre est à 100%
|
||||
});
|
||||
|
||||
// Attendre quelques secondes avant de rediriger automatiquement
|
||||
// si l'utilisateur est déjà connecté
|
||||
if (userRepository.isLoggedIn) {
|
||||
Timer(const Duration(seconds: 2), () {
|
||||
_redirectToAppropriateScreen();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,8 +180,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
},
|
||||
];
|
||||
|
||||
// Calculer l'incrément de progression pour chaque boîte
|
||||
final progressIncrement = 0.2 / boxesToOpen.length;
|
||||
// Calculer l'incrément de progression pour chaque boîte (0.75 / nombre de boîtes)
|
||||
final progressIncrement = 0.75 / boxesToOpen.length;
|
||||
double currentProgress = 0.0;
|
||||
|
||||
// Ouvrir chaque boîte si elle n'est pas déjà ouverte
|
||||
@@ -212,12 +190,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
final displayName = boxesToOpen[i]['display'] as String;
|
||||
|
||||
// Mettre à jour la barre de progression et le message
|
||||
currentProgress += progressIncrement;
|
||||
currentProgress = progressIncrement * (i + 1);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = displayName;
|
||||
_progress =
|
||||
0.2 * (currentProgress / 0.2); // Normaliser entre 0 et 0.2
|
||||
_progress = currentProgress;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -266,10 +243,27 @@ class _SplashPageState extends State<SplashPage>
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = 'Toutes les boîtes sont prêtes';
|
||||
_progress = 0.2;
|
||||
_progress = 0.8;
|
||||
});
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = "Préparation de l'application...";
|
||||
_progress = 0.9;
|
||||
});
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
// Finalisation
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isInitializing = false;
|
||||
_showButtons = true;
|
||||
_progress = 1.0;
|
||||
});
|
||||
}
|
||||
debugPrint('Toutes les boîtes Hive sont maintenant ouvertes');
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'initialisation des boîtes Hive: $e');
|
||||
@@ -283,33 +277,9 @@ class _SplashPageState extends State<SplashPage>
|
||||
}
|
||||
}
|
||||
|
||||
void _redirectToAppropriateScreen() {
|
||||
if (!mounted) return;
|
||||
|
||||
// Utiliser l'instance globale de userRepository définie dans app.dart
|
||||
if (userRepository.isLoggedIn) {
|
||||
debugPrint('SplashPage: Redirection d\'utilisateur connecté');
|
||||
|
||||
// Récupérer directement le rôle utilisateur
|
||||
final roleValue = userRepository.getUserRole();
|
||||
debugPrint('SplashPage: Rôle utilisateur = $roleValue');
|
||||
|
||||
// Redirection simple basée sur le rôle
|
||||
if (roleValue > 1) {
|
||||
debugPrint('SplashPage: Redirection vers /admin (rôle $roleValue > 1)');
|
||||
context.go('/admin');
|
||||
} else {
|
||||
debugPrint('SplashPage: Redirection vers /user (rôle $roleValue = 1)');
|
||||
context.go('/user');
|
||||
}
|
||||
}
|
||||
// Ne redirige plus vers la landing page
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final size = MediaQuery.of(context).size;
|
||||
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
@@ -424,7 +394,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/login', extra: {'type': 'user'});
|
||||
context.go(
|
||||
'/login/user'); // Utiliser la route spécifique
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.green,
|
||||
@@ -449,13 +420,14 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Bouton Connexion Administrateur
|
||||
// Bouton Connexion Administrateur
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/login', extra: {'type': 'admin'});
|
||||
context.go(
|
||||
'/login/admin'); // Utiliser la route spécifique
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
@@ -479,18 +451,74 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
const SizedBox(
|
||||
height: 32), // 2 espaces sous le bouton précédent
|
||||
|
||||
// Lien d'inscription
|
||||
// Bouton d'inscription
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: TextButton(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: Text(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
vertical: 16,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
elevation: 2,
|
||||
),
|
||||
child: const Text(
|
||||
'Pas encore inscrit ?',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Lien vers le site web
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: TextButton.icon(
|
||||
onPressed: () {
|
||||
// Déterminer l'URL du site web en fonction de l'environnement
|
||||
String webUrl = 'https://geosector.fr';
|
||||
|
||||
if (kIsWeb) {
|
||||
final host = Uri.base.host;
|
||||
if (host.startsWith('dapp.')) {
|
||||
webUrl = 'https://dev.geosector.fr';
|
||||
} else if (host.startsWith('rapp.')) {
|
||||
webUrl = 'https://rec.geosector.fr';
|
||||
} else if (host.startsWith('app.')) {
|
||||
webUrl = 'https://geosector.fr';
|
||||
}
|
||||
}
|
||||
|
||||
// Ouvrir l'URL dans une nouvelle fenêtre/onglet
|
||||
launchUrl(
|
||||
Uri.parse(webUrl),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.language,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
label: Text(
|
||||
'Site web Geosector',
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -506,6 +534,38 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
),
|
||||
),
|
||||
// Badge de version en bas à droite
|
||||
if (_appVersion.isNotEmpty)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: AnimatedOpacity(
|
||||
opacity: _showButtons ? 0.7 : 0.5,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'v$_appVersion',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user