feat: Enhance messaging read receipts and auto-read, fix auth 401 error suppression during logout, and refine agent profile expertise
This commit is contained in:
@@ -264,6 +264,26 @@ class ChatMessage {
|
||||
|
||||
bool isMine(String currentUserId) => senderId == currentUserId;
|
||||
|
||||
ChatMessage copyWith({MessageStatus? status, String? readAt, String? deliveredAt}) {
|
||||
return ChatMessage(
|
||||
id: id,
|
||||
conversationId: conversationId,
|
||||
senderId: senderId,
|
||||
content: content,
|
||||
messageType: messageType,
|
||||
fileUrl: fileUrl,
|
||||
fileName: fileName,
|
||||
fileSize: fileSize,
|
||||
mimeType: mimeType,
|
||||
status: status ?? this.status,
|
||||
deliveredAt: deliveredAt ?? this.deliveredAt,
|
||||
readAt: readAt ?? this.readAt,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
sender: sender,
|
||||
);
|
||||
}
|
||||
|
||||
factory ChatMessage.fromJson(Map<String, dynamic> json) {
|
||||
return ChatMessage(
|
||||
id: json['id'] as String,
|
||||
|
||||
@@ -143,6 +143,12 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
|
||||
conversations: updatedConversations,
|
||||
unreadCount: totalUnread,
|
||||
);
|
||||
|
||||
// Auto-mark as read if user is currently viewing this conversation
|
||||
final isActive = state.activeConversationId == convId;
|
||||
if (isActive) {
|
||||
markAsRead(convId);
|
||||
}
|
||||
}));
|
||||
|
||||
// Typing indicators
|
||||
@@ -165,16 +171,36 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
|
||||
}
|
||||
}));
|
||||
|
||||
// Read receipts
|
||||
// Read receipts — update message ticks and conversation unread count
|
||||
_subscriptions.add(_socket.onMessagesRead.listen((data) {
|
||||
if (!mounted) return;
|
||||
final convId = data['conversationId'] as String?;
|
||||
final readAt = data['readAt'] as String?;
|
||||
if (convId == null) return;
|
||||
|
||||
// Update conversation unread count
|
||||
final updatedConversations = state.conversations.map((c) {
|
||||
if (c.id == convId) return c.copyWith(unreadCount: 0);
|
||||
return c;
|
||||
}).toList();
|
||||
state = state.copyWith(conversations: updatedConversations);
|
||||
|
||||
// Update message statuses — mark current user's sent messages as READ
|
||||
final currentMessages = List<ChatMessage>.from(state.messages[convId] ?? []);
|
||||
final currentUserId = _currentUserId;
|
||||
bool messagesChanged = false;
|
||||
final updatedMessages = currentMessages.map((m) {
|
||||
if (m.senderId == currentUserId && m.status != MessageStatus.read) {
|
||||
messagesChanged = true;
|
||||
return m.copyWith(status: MessageStatus.read, readAt: readAt);
|
||||
}
|
||||
return m;
|
||||
}).toList();
|
||||
|
||||
final newMessages = messagesChanged
|
||||
? (Map<String, List<ChatMessage>>.from(state.messages)..[convId] = updatedMessages)
|
||||
: state.messages;
|
||||
|
||||
state = state.copyWith(conversations: updatedConversations, messages: newMessages);
|
||||
}));
|
||||
|
||||
// Reconnection: re-join active conversation room and catch up missed messages
|
||||
|
||||
Reference in New Issue
Block a user