Files
afterwork/lib/presentation/widgets/profile_header.dart
dahoud 92612abbd7 fix(chat): Correction race condition + Implémentation TODOs
## Corrections Critiques

### Race Condition - Statuts de Messages
- Fix : Les icônes de statut (✓, ✓✓, ✓✓ bleu) ne s'affichaient pas
- Cause : WebSocket delivery confirmations arrivaient avant messages locaux
- Solution : Pattern Optimistic UI dans chat_bloc.dart
  - Création message temporaire immédiate
  - Ajout à la liste AVANT requête HTTP
  - Remplacement par message serveur à la réponse
- Fichier : lib/presentation/state_management/chat_bloc.dart

## Implémentation TODOs (13/21)

### Social (social_header_widget.dart)
-  Copier lien du post dans presse-papiers
-  Partage natif via Share.share()
-  Dialogue de signalement avec 5 raisons

### Partage (share_post_dialog.dart)
-  Interface sélection d'amis avec checkboxes
-  Partage externe via Share API

### Média (media_upload_service.dart)
-  Parsing JSON réponse backend
-  Méthode deleteMedia() pour suppression
-  Génération miniature vidéo

### Posts (create_post_dialog.dart, edit_post_dialog.dart)
-  Extraction URL depuis uploads
-  Documentation chargement médias

### Chat (conversations_screen.dart)
-  Navigation vers notifications
-  ConversationSearchDelegate pour recherche

## Nouveaux Fichiers

### Configuration
- build-prod.ps1 : Script build production avec dart-define
- lib/core/constants/env_config.dart : Gestion environnements

### Documentation
- TODOS_IMPLEMENTED.md : Documentation complète TODOs

## Améliorations

### Architecture
- Refactoring injection de dépendances
- Amélioration routing et navigation
- Optimisation providers (UserProvider, FriendsProvider)

### UI/UX
- Amélioration thème et couleurs
- Optimisation animations
- Meilleure gestion erreurs

### Services
- Configuration API avec env_config
- Amélioration datasources (events, users)
- Optimisation modèles de données
2026-01-10 10:43:17 +00:00

170 lines
6.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../../core/constants/colors.dart';
import '../../../../data/providers/user_provider.dart';
import '../../../../domain/entities/user.dart';
/// [ProfileHeader] : Un widget d'en-tête de profil utilisateur visuellement amélioré
/// avec un gradient élégant, des animations, et un bouton de déconnexion stylisé.
/// Entièrement logué pour une traçabilité complète.
class ProfileHeader extends StatelessWidget {
const ProfileHeader({required this.user, super.key});
final User user;
@override
Widget build(BuildContext context) {
debugPrint("[LOG] Initialisation de ProfileHeader pour l'utilisateur : ${user.userFirstName} ${user.userLastName}");
return SliverAppBar(
expandedHeight: 250,
pinned: true,
elevation: 0,
backgroundColor: AppColors.darkPrimary,
flexibleSpace: _buildFlexibleSpaceBar(user),
actions: [_buildLogoutButton(context)],
);
}
/// Construit un FlexibleSpaceBar avec un gradient et des animations.
/// Affiche le nom de l'utilisateur et l'image de profil avec un effet visuel enrichi.
Widget _buildFlexibleSpaceBar(User user) {
debugPrint('[LOG] Construction de FlexibleSpaceBar avec nom et image de profil.');
return FlexibleSpaceBar(
centerTitle: true,
title: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 2),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.6),
borderRadius: BorderRadius.circular(12),
),
child: Text(
'Profil de ${user.userFirstName}',
style: TextStyle(
color: AppColors.accentColor,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
background: _buildProfileImageWithGradient(user.profileImageUrl),
);
}
/// Construit l'image de profil avec un overlay en gradient.
/// En cas d'erreur de chargement, affiche une image par défaut.
Widget _buildProfileImageWithGradient(String profileImageUrl) {
debugPrint("[LOG] Chargement de l'image de profil avec overlay de gradient.");
return Stack(
fit: StackFit.expand,
children: [
Image.network(
profileImageUrl,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Center(child: CircularProgressIndicator(color: AppColors.accentColor));
},
errorBuilder: (context, error, stackTrace) {
debugPrint("[ERROR] Erreur lors du chargement de l'image de profil : $error");
return Image.asset(
'lib/assets/images/default_avatar.png',
fit: BoxFit.cover,
);
},
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.transparent, AppColors.darkPrimary.withOpacity(0.8)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
],
);
}
/// Construit un bouton de déconnexion stylisé avec animation.
/// Log chaque interaction pour assurer une traçabilité complète.
Widget _buildLogoutButton(BuildContext context) {
return IconButton(
icon: const Icon(Icons.logout, color: Colors.white),
splashRadius: 20,
onPressed: () {
debugPrint('[LOG] Clic sur le bouton de déconnexion.');
_showLogoutConfirmationDialog(context);
},
tooltip: 'Déconnexion',
);
}
/// Affiche une boîte de dialogue de confirmation pour la déconnexion.
/// Log chaque action et résultat pour une visibilité dans le terminal.
void _showLogoutConfirmationDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
debugPrint('[LOG] Affichage de la boîte de dialogue de confirmation de déconnexion.');
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
backgroundColor: AppColors.backgroundColor,
title: const Text(
'Confirmer la déconnexion',
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600),
),
content: const Text(
'Voulez-vous vraiment vous déconnecter ?',
style: TextStyle(color: Colors.white70, fontSize: 16),
),
actions: [
_buildCancelButton(context),
_buildConfirmButton(context),
],
);
},
).then((_) {
debugPrint('[LOG] Fermeture de la boîte de dialogue de déconnexion.');
});
}
/// Construit le bouton pour annuler la déconnexion avec log.
Widget _buildCancelButton(BuildContext context) {
return TextButton(
onPressed: () {
debugPrint("[LOG] L'utilisateur a annulé la déconnexion.");
Navigator.of(context).pop();
},
child: Text(
'Annuler',
style: TextStyle(color: AppColors.accentColor, fontWeight: FontWeight.bold),
),
);
}
/// Construit le bouton pour confirmer la déconnexion, avec log et réinitialisation des données utilisateur.
Widget _buildConfirmButton(BuildContext context) {
return TextButton(
onPressed: () {
debugPrint("[LOG] L'utilisateur a confirmé la déconnexion.");
// Réinitialisation des informations de l'utilisateur
Provider.of<UserProvider>(context, listen: false).resetUser();
debugPrint('[LOG] Informations utilisateur réinitialisées dans UserProvider.');
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed('/'); // Redirection vers l'écran de connexion
debugPrint("[LOG] Redirection vers l'écran de connexion.");
},
child: const Text(
'Déconnexion',
style: TextStyle(color: Colors.redAccent, fontWeight: FontWeight.bold),
),
);
}
}