feat: Add logger service and improve expense dialog with enhanced receipt management and calculation logic.
This commit is contained in:
@@ -12,7 +12,7 @@ import '../../models/message.dart';
|
||||
import '../../repositories/group_repository.dart';
|
||||
|
||||
/// Chat group content widget for group messaging functionality.
|
||||
///
|
||||
///
|
||||
/// This widget provides a complete chat interface for group members to
|
||||
/// communicate within a travel group. Features include:
|
||||
/// - Real-time message loading and sending
|
||||
@@ -20,7 +20,7 @@ import '../../repositories/group_repository.dart';
|
||||
/// - Message reactions (like/unlike)
|
||||
/// - Scroll-to-bottom functionality
|
||||
/// - Message status indicators
|
||||
///
|
||||
///
|
||||
/// The widget integrates with MessageBloc for state management and
|
||||
/// handles various message operations through the bloc pattern.
|
||||
class ChatGroupContent extends StatefulWidget {
|
||||
@@ -28,13 +28,10 @@ class ChatGroupContent extends StatefulWidget {
|
||||
final Group group;
|
||||
|
||||
/// Creates a chat group content widget.
|
||||
///
|
||||
///
|
||||
/// Args:
|
||||
/// [group]: The group object containing group details and ID
|
||||
const ChatGroupContent({
|
||||
super.key,
|
||||
required this.group,
|
||||
});
|
||||
const ChatGroupContent({super.key, required this.group});
|
||||
|
||||
@override
|
||||
State<ChatGroupContent> createState() => _ChatGroupContentState();
|
||||
@@ -43,16 +40,16 @@ class ChatGroupContent extends StatefulWidget {
|
||||
class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
/// Controller for the message input field
|
||||
final _messageController = TextEditingController();
|
||||
|
||||
|
||||
/// Controller for managing scroll position in the message list
|
||||
final _scrollController = ScrollController();
|
||||
|
||||
|
||||
/// Currently selected message for editing (null if not editing)
|
||||
Message? _editingMessage;
|
||||
|
||||
/// Repository pour gérer les groupes
|
||||
final _groupRepository = GroupRepository();
|
||||
|
||||
|
||||
/// Subscription pour écouter les changements des membres du groupe
|
||||
late StreamSubscription<List<GroupMember>> _membersSubscription;
|
||||
|
||||
@@ -61,18 +58,20 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
super.initState();
|
||||
// Load messages when the widget initializes
|
||||
context.read<MessageBloc>().add(LoadMessages(widget.group.id));
|
||||
|
||||
|
||||
// Écouter les changements des membres du groupe
|
||||
_membersSubscription = _groupRepository.watchGroupMembers(widget.group.id).listen((updatedMembers) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
widget.group.members.clear();
|
||||
widget.group.members.addAll(updatedMembers);
|
||||
_membersSubscription = _groupRepository
|
||||
.watchGroupMembers(widget.group.id)
|
||||
.listen((updatedMembers) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
widget.group.members.clear();
|
||||
widget.group.members.addAll(updatedMembers);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_messageController.dispose();
|
||||
@@ -82,11 +81,11 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}
|
||||
|
||||
/// Sends a new message or updates an existing message.
|
||||
///
|
||||
///
|
||||
/// Handles both sending new messages and editing existing ones based
|
||||
/// on the current editing state. Validates input and clears the input
|
||||
/// field after successful submission.
|
||||
///
|
||||
///
|
||||
/// Args:
|
||||
/// [currentUser]: The user sending or editing the message
|
||||
void _sendMessage(user_state.UserModel currentUser) {
|
||||
@@ -96,33 +95,33 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
if (_editingMessage != null) {
|
||||
// Edit mode - update existing message
|
||||
context.read<MessageBloc>().add(
|
||||
UpdateMessage(
|
||||
groupId: widget.group.id,
|
||||
messageId: _editingMessage!.id,
|
||||
newText: messageText,
|
||||
),
|
||||
);
|
||||
UpdateMessage(
|
||||
groupId: widget.group.id,
|
||||
messageId: _editingMessage!.id,
|
||||
newText: messageText,
|
||||
),
|
||||
);
|
||||
_cancelEdit();
|
||||
} else {
|
||||
// Send mode - create new message
|
||||
context.read<MessageBloc>().add(
|
||||
SendMessage(
|
||||
groupId: widget.group.id,
|
||||
text: messageText,
|
||||
senderId: currentUser.id,
|
||||
senderName: currentUser.prenom,
|
||||
),
|
||||
);
|
||||
SendMessage(
|
||||
groupId: widget.group.id,
|
||||
text: messageText,
|
||||
senderId: currentUser.id,
|
||||
senderName: currentUser.prenom,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_messageController.clear();
|
||||
}
|
||||
|
||||
/// Initiates editing mode for a selected message.
|
||||
///
|
||||
///
|
||||
/// Sets the message as the currently editing message and populates
|
||||
/// the input field with the message text for modification.
|
||||
///
|
||||
///
|
||||
/// Args:
|
||||
/// [message]: The message to edit
|
||||
void _editMessage(Message message) {
|
||||
@@ -133,7 +132,7 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}
|
||||
|
||||
/// Cancels the current editing operation.
|
||||
///
|
||||
///
|
||||
/// Resets the editing state and clears the input field,
|
||||
/// returning to normal message sending mode.
|
||||
void _cancelEdit() {
|
||||
@@ -144,46 +143,43 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}
|
||||
|
||||
/// Deletes a message from the group chat.
|
||||
///
|
||||
///
|
||||
/// Sends a delete event to the MessageBloc to remove the specified
|
||||
/// message from the group's message history.
|
||||
///
|
||||
///
|
||||
/// Args:
|
||||
/// [messageId]: The ID of the message to delete
|
||||
void _deleteMessage(String messageId) {
|
||||
context.read<MessageBloc>().add(
|
||||
DeleteMessage(
|
||||
groupId: widget.group.id,
|
||||
messageId: messageId,
|
||||
),
|
||||
);
|
||||
DeleteMessage(groupId: widget.group.id, messageId: messageId),
|
||||
);
|
||||
}
|
||||
|
||||
void _reactToMessage(String messageId, String userId, String reaction) {
|
||||
context.read<MessageBloc>().add(
|
||||
ReactToMessage(
|
||||
groupId: widget.group.id,
|
||||
messageId: messageId,
|
||||
userId: userId,
|
||||
reaction: reaction,
|
||||
),
|
||||
);
|
||||
ReactToMessage(
|
||||
groupId: widget.group.id,
|
||||
messageId: messageId,
|
||||
userId: userId,
|
||||
reaction: reaction,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _removeReaction(String messageId, String userId) {
|
||||
context.read<MessageBloc>().add(
|
||||
RemoveReaction(
|
||||
groupId: widget.group.id,
|
||||
messageId: messageId,
|
||||
userId: userId,
|
||||
),
|
||||
);
|
||||
RemoveReaction(
|
||||
groupId: widget.group.id,
|
||||
messageId: messageId,
|
||||
userId: userId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
|
||||
return BlocBuilder<UserBloc, user_state.UserState>(
|
||||
builder: (context, userState) {
|
||||
if (userState is! user_state.UserLoaded) {
|
||||
@@ -203,7 +199,10 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
Text(widget.group.name, style: const TextStyle(fontSize: 18)),
|
||||
Text(
|
||||
'${widget.group.members.length} membre${widget.group.members.length > 1 ? 's' : ''}',
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -255,7 +254,8 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
itemBuilder: (context, index) {
|
||||
final message = state.messages[index];
|
||||
final isMe = message.senderId == currentUser.id;
|
||||
final showDate = index == 0 ||
|
||||
final showDate =
|
||||
index == 0 ||
|
||||
!_isSameDay(
|
||||
state.messages[index - 1].timestamp,
|
||||
message.timestamp,
|
||||
@@ -263,8 +263,14 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
if (showDate) _buildDateSeparator(message.timestamp),
|
||||
_buildMessageBubble(message, isMe, isDark, currentUser.id),
|
||||
if (showDate)
|
||||
_buildDateSeparator(message.timestamp),
|
||||
_buildMessageBubble(
|
||||
message,
|
||||
isMe,
|
||||
isDark,
|
||||
currentUser.id,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
@@ -280,14 +286,15 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
if (_editingMessage != null)
|
||||
Container(
|
||||
color: isDark ? Colors.blue[900] : Colors.blue[100],
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.edit, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(
|
||||
child: Text('Modification du message'),
|
||||
),
|
||||
const Expanded(child: Text('Modification du message')),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: _cancelEdit,
|
||||
@@ -315,11 +322,13 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
child: TextField(
|
||||
controller: _messageController,
|
||||
decoration: InputDecoration(
|
||||
hintText: _editingMessage != null
|
||||
? 'Modifier le message...'
|
||||
hintText: _editingMessage != null
|
||||
? 'Modifier le message...'
|
||||
: 'Écrire un message...',
|
||||
filled: true,
|
||||
fillColor: isDark ? Colors.grey[850] : Colors.grey[100],
|
||||
fillColor: isDark
|
||||
? Colors.grey[850]
|
||||
: Colors.grey[100],
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
borderSide: BorderSide.none,
|
||||
@@ -336,9 +345,13 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
onPressed: () => _sendMessage(currentUser),
|
||||
icon: Icon(_editingMessage != null ? Icons.check : Icons.send),
|
||||
icon: Icon(
|
||||
_editingMessage != null ? Icons.check : Icons.send,
|
||||
),
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
backgroundColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.all(12),
|
||||
),
|
||||
@@ -361,27 +374,17 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.chat_bubble_outline,
|
||||
size: 80,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
Icon(Icons.chat_bubble_outline, size: 80, color: Colors.grey[400]),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
'Aucun message',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Commencez la conversation !',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
style: TextStyle(fontSize: 14, color: Colors.grey[600]),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -389,10 +392,15 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMessageBubble(Message message, bool isMe, bool isDark, String currentUserId) {
|
||||
Widget _buildMessageBubble(
|
||||
Message message,
|
||||
bool isMe,
|
||||
bool isDark,
|
||||
String currentUserId,
|
||||
) {
|
||||
final Color bubbleColor;
|
||||
final Color textColor;
|
||||
|
||||
|
||||
if (isMe) {
|
||||
bubbleColor = isDark ? const Color(0xFF1E3A5F) : const Color(0xFF90CAF9);
|
||||
textColor = isDark ? Colors.white : Colors.black87;
|
||||
@@ -402,42 +410,48 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}
|
||||
|
||||
// Trouver le membre qui a envoyé le message pour récupérer son pseudo actuel
|
||||
final senderMember = widget.group.members.firstWhere(
|
||||
(m) => m.userId == message.senderId,
|
||||
orElse: () => null as dynamic,
|
||||
) as dynamic;
|
||||
final senderMember =
|
||||
widget.group.members.firstWhere(
|
||||
(m) => m.userId == message.senderId,
|
||||
orElse: () => null as dynamic,
|
||||
)
|
||||
as dynamic;
|
||||
|
||||
// Utiliser le pseudo actuel du membre, ou le senderName en fallback
|
||||
final displayName = senderMember != null ? senderMember.pseudo : message.senderName;
|
||||
final displayName = senderMember != null
|
||||
? senderMember.pseudo
|
||||
: message.senderName;
|
||||
|
||||
return Align(
|
||||
alignment: isMe ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: GestureDetector(
|
||||
onLongPress: () => _showMessageOptions(context, message, isMe, currentUserId),
|
||||
onLongPress: () =>
|
||||
_showMessageOptions(context, message, isMe, currentUserId),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Row(
|
||||
mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||
mainAxisAlignment: isMe
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// Avatar du sender (seulement pour les autres messages)
|
||||
if (!isMe) ...[
|
||||
CircleAvatar(
|
||||
radius: 16,
|
||||
backgroundImage: (senderMember != null &&
|
||||
senderMember.profilePictureUrl != null &&
|
||||
senderMember.profilePictureUrl!.isNotEmpty)
|
||||
backgroundImage:
|
||||
(senderMember != null &&
|
||||
senderMember.profilePictureUrl != null &&
|
||||
senderMember.profilePictureUrl!.isNotEmpty)
|
||||
? NetworkImage(senderMember.profilePictureUrl!)
|
||||
: null,
|
||||
child: (senderMember == null ||
|
||||
senderMember.profilePictureUrl == null ||
|
||||
senderMember.profilePictureUrl!.isEmpty)
|
||||
child:
|
||||
(senderMember == null ||
|
||||
senderMember.profilePictureUrl == null ||
|
||||
senderMember.profilePictureUrl!.isEmpty)
|
||||
? Text(
|
||||
displayName.isNotEmpty
|
||||
? displayName[0].toUpperCase()
|
||||
displayName.isNotEmpty
|
||||
? displayName[0].toUpperCase()
|
||||
: '?',
|
||||
style: const TextStyle(fontSize: 12),
|
||||
)
|
||||
@@ -445,10 +459,13 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
|
||||
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 10,
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * 0.65,
|
||||
),
|
||||
@@ -462,7 +479,9 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||
crossAxisAlignment: isMe
|
||||
? CrossAxisAlignment.end
|
||||
: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (!isMe) ...[
|
||||
Text(
|
||||
@@ -476,11 +495,17 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
const SizedBox(height: 4),
|
||||
],
|
||||
Text(
|
||||
message.isDeleted ? 'a supprimé un message' : message.text,
|
||||
message.isDeleted
|
||||
? 'a supprimé un message'
|
||||
: message.text,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: message.isDeleted ? textColor.withValues(alpha: 0.5) : textColor,
|
||||
fontStyle: message.isDeleted ? FontStyle.italic : FontStyle.normal,
|
||||
color: message.isDeleted
|
||||
? textColor.withValues(alpha: 0.5)
|
||||
: textColor,
|
||||
fontStyle: message.isDeleted
|
||||
? FontStyle.italic
|
||||
: FontStyle.normal,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
@@ -528,7 +553,7 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
|
||||
List<Widget> _buildReactionChips(Message message, String currentUserId) {
|
||||
final reactionCounts = <String, List<String>>{};
|
||||
|
||||
|
||||
// Grouper les réactions par emoji
|
||||
message.reactions.forEach((userId, emoji) {
|
||||
reactionCounts.putIfAbsent(emoji, () => []).add(userId);
|
||||
@@ -550,7 +575,7 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: hasReacted
|
||||
color: hasReacted
|
||||
? Colors.blue.withValues(alpha: 0.3)
|
||||
: Colors.grey.withValues(alpha: 0.3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -565,7 +590,10 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
'${userIds.length}',
|
||||
style: const TextStyle(fontSize: 10, fontWeight: FontWeight.bold),
|
||||
style: const TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -574,7 +602,12 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
void _showMessageOptions(BuildContext context, Message message, bool isMe, String currentUserId) {
|
||||
void _showMessageOptions(
|
||||
BuildContext context,
|
||||
Message message,
|
||||
bool isMe,
|
||||
String currentUserId,
|
||||
) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => SafeArea(
|
||||
@@ -609,7 +642,10 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete, color: Colors.red),
|
||||
title: const Text('Supprimer', style: TextStyle(color: Colors.red)),
|
||||
title: const Text(
|
||||
'Supprimer',
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
_showDeleteConfirmation(context, message.id);
|
||||
@@ -712,20 +748,23 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
final member = widget.group.members[index];
|
||||
final initials = member.pseudo.isNotEmpty
|
||||
? member.pseudo[0].toUpperCase()
|
||||
: (member.firstName.isNotEmpty
|
||||
? member.firstName[0].toUpperCase()
|
||||
: '?');
|
||||
|
||||
: (member.firstName.isNotEmpty
|
||||
? member.firstName[0].toUpperCase()
|
||||
: '?');
|
||||
|
||||
// Construire le nom complet
|
||||
final fullName = '${member.firstName} ${member.lastName}'.trim();
|
||||
|
||||
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: (member.profilePictureUrl != null &&
|
||||
member.profilePictureUrl!.isNotEmpty)
|
||||
backgroundImage:
|
||||
(member.profilePictureUrl != null &&
|
||||
member.profilePictureUrl!.isNotEmpty)
|
||||
? NetworkImage(member.profilePictureUrl!)
|
||||
: null,
|
||||
child: (member.profilePictureUrl == null || member.profilePictureUrl!.isEmpty)
|
||||
child:
|
||||
(member.profilePictureUrl == null ||
|
||||
member.profilePictureUrl!.isEmpty)
|
||||
? Text(initials)
|
||||
: null,
|
||||
),
|
||||
@@ -743,8 +782,11 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: member.role == 'admin'
|
||||
? const Text('Administrateur', style: TextStyle(fontSize: 12))
|
||||
subtitle: member.role == 'admin'
|
||||
? const Text(
|
||||
'Administrateur',
|
||||
style: TextStyle(fontSize: 12),
|
||||
)
|
||||
: null,
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.edit, size: 18),
|
||||
@@ -774,7 +816,8 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: theme.dialogBackgroundColor,
|
||||
backgroundColor:
|
||||
theme.dialogTheme.backgroundColor ?? theme.colorScheme.surface,
|
||||
title: Text(
|
||||
'Changer le pseudo',
|
||||
style: theme.textTheme.titleLarge?.copyWith(
|
||||
@@ -785,9 +828,7 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
controller: pseudoController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Nouveau pseudo',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
@@ -825,11 +866,11 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
try {
|
||||
final updatedMember = member.copyWith(pseudo: newPseudo);
|
||||
await _groupRepository.addMember(widget.group.id, updatedMember);
|
||||
|
||||
|
||||
if (mounted) {
|
||||
// Le stream listener va automatiquement mettre à jour les membres
|
||||
// Pas besoin de fermer le dialog ou de faire un refresh manuel
|
||||
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Pseudo modifié en "$newPseudo"'),
|
||||
@@ -848,4 +889,4 @@ class _ChatGroupContentState extends State<ChatGroupContent> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user