Add sender avatar display and member list enhancements in chat group

This commit is contained in:
Van Leemput Dayron
2025-11-13 18:35:00 +01:00
parent 41402e1b2c
commit 9101a94691

View File

@@ -380,77 +380,118 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
bubbleColor = isDark ? Colors.grey[800]! : Colors.grey[200]!; bubbleColor = isDark ? Colors.grey[800]! : Colors.grey[200]!;
textColor = isDark ? Colors.white : Colors.black87; textColor = isDark ? Colors.white : Colors.black87;
} }
// Trouver le membre qui a envoyé le message pour récupérer sa photo
final senderMember = widget.group.members.firstWhere(
(m) => m.userId == message.senderId,
orElse: () => null as dynamic,
) as dynamic;
return Align( return Align(
alignment: isMe ? Alignment.centerRight : Alignment.centerLeft, alignment: isMe ? Alignment.centerRight : Alignment.centerLeft,
child: GestureDetector( child: GestureDetector(
onLongPress: () => _showMessageOptions(context, message, isMe, currentUserId), onLongPress: () => _showMessageOptions(context, message, isMe, currentUserId),
child: Container( child: Padding(
margin: const EdgeInsets.symmetric(vertical: 4), padding: EdgeInsets.symmetric(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), horizontal: 8,
constraints: BoxConstraints( vertical: 4,
maxWidth: MediaQuery.of(context).size.width * 0.7,
), ),
decoration: BoxDecoration( child: Row(
color: bubbleColor, mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start,
borderRadius: BorderRadius.only( crossAxisAlignment: CrossAxisAlignment.end,
topLeft: const Radius.circular(16),
topRight: const Radius.circular(16),
bottomLeft: Radius.circular(isMe ? 16 : 4),
bottomRight: Radius.circular(isMe ? 4 : 16),
),
),
child: Column(
crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [ children: [
// Avatar du sender (seulement pour les autres messages)
if (!isMe) ...[ if (!isMe) ...[
Text( CircleAvatar(
message.senderName, radius: 16,
style: TextStyle( backgroundImage: (senderMember != null &&
fontSize: 12, senderMember.profilePictureUrl != null &&
fontWeight: FontWeight.bold, senderMember.profilePictureUrl!.isNotEmpty)
color: isDark ? Colors.grey[400] : Colors.grey[700], ? NetworkImage(senderMember.profilePictureUrl!)
), : null,
child: (senderMember == null ||
senderMember.profilePictureUrl == null ||
senderMember.profilePictureUrl!.isEmpty)
? Text(
message.senderName.isNotEmpty
? message.senderName[0].toUpperCase()
: '?',
style: const TextStyle(fontSize: 12),
)
: null,
), ),
const SizedBox(height: 4), const SizedBox(width: 8),
], ],
Text(
message.text, Container(
style: TextStyle(fontSize: 15, color: textColor), margin: const EdgeInsets.symmetric(vertical: 4),
), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
const SizedBox(height: 4), constraints: BoxConstraints(
Row( maxWidth: MediaQuery.of(context).size.width * 0.65,
mainAxisSize: MainAxisSize.min, ),
children: [ decoration: BoxDecoration(
Text( color: bubbleColor,
_formatTime(message.timestamp), borderRadius: BorderRadius.only(
style: TextStyle( topLeft: const Radius.circular(16),
fontSize: 11, topRight: const Radius.circular(16),
color: textColor.withValues(alpha: 0.7), bottomLeft: Radius.circular(isMe ? 16 : 4),
), bottomRight: Radius.circular(isMe ? 4 : 16),
),
if (message.isEdited) ...[
const SizedBox(width: 4),
Text(
'(modifié)',
style: TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: textColor.withValues(alpha: 0.6),
),
),
],
],
),
// Afficher les réactions
if (message.reactions.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Wrap(
spacing: 4,
children: _buildReactionChips(message, currentUserId),
), ),
), ),
child: Column(
crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
if (!isMe) ...[
Text(
message.senderName,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: isDark ? Colors.grey[400] : Colors.grey[700],
),
),
const SizedBox(height: 4),
],
Text(
message.text,
style: TextStyle(fontSize: 15, color: textColor),
),
const SizedBox(height: 4),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_formatTime(message.timestamp),
style: TextStyle(
fontSize: 11,
color: textColor.withValues(alpha: 0.7),
),
),
if (message.isEdited) ...[
const SizedBox(width: 4),
Text(
'(modifié)',
style: TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: textColor.withValues(alpha: 0.6),
),
),
],
],
),
// Afficher les réactions
if (message.reactions.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Wrap(
spacing: 4,
children: _buildReactionChips(message, currentUserId),
),
),
],
),
),
], ],
), ),
), ),
@@ -642,11 +683,26 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
itemCount: widget.group.members.length, itemCount: widget.group.members.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final member = widget.group.members[index]; final member = widget.group.members[index];
final initials = member.pseudo.isNotEmpty
? member.pseudo[0].toUpperCase()
: (member.firstName.isNotEmpty
? member.firstName[0].toUpperCase()
: '?');
return ListTile( return ListTile(
leading: CircleAvatar( leading: CircleAvatar(
child: Text(member.pseudo.substring(0, 1).toUpperCase()), backgroundImage: (member.profilePictureUrl != null &&
member.profilePictureUrl!.isNotEmpty)
? NetworkImage(member.profilePictureUrl!)
: null,
child: (member.profilePictureUrl == null || member.profilePictureUrl!.isEmpty)
? Text(initials)
: null,
), ),
title: Text(member.pseudo), title: Text(member.pseudo),
subtitle: member.role == 'admin'
? const Text('Administrateur', style: TextStyle(fontSize: 12))
: null,
); );
}, },
), ),