Add sender avatar display and member list enhancements in chat group
This commit is contained in:
@@ -381,76 +381,117 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
|||||||
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,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user