From 821e1a06895276245fcb9e188021804573a4db0f Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Tue, 7 Apr 2026 19:53:12 +0530 Subject: [PATCH] feat: implement automatic message delivery acknowledgement to trigger real-time double-tick status updates --- lib/features/messaging/data/socket_service.dart | 17 +++++++++++++++++ .../providers/messaging_provider.dart | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/lib/features/messaging/data/socket_service.dart b/lib/features/messaging/data/socket_service.dart index a51c2ff..4b0efdf 100644 --- a/lib/features/messaging/data/socket_service.dart +++ b/lib/features/messaging/data/socket_service.dart @@ -139,6 +139,13 @@ class SocketService { _socket!.on('new_message', (data) { try { final message = ChatMessage.fromJson(data as Map); + // Auto-ack delivery so sender gets real-time double-tick + try { + _socket?.emit('message_received', { + 'messageId': message.id, + 'conversationId': message.conversationId, + }); + } catch (_) {} _messageController.add(message); } catch (e) { _log.e('Error parsing new_message: $e'); @@ -305,6 +312,16 @@ class SocketService { _socket?.emit('mark_read', {'conversationId': conversationId}); } + /// Acknowledge that we (the receiver) have received a message via socket. + /// Backend marks it as DELIVERED and emits `message_delivered` to the sender, + /// making the sender's tick update from single → double in real time. + void ackMessageReceived(String conversationId, String messageId) { + _socket?.emit('message_received', { + 'conversationId': conversationId, + 'messageId': messageId, + }); + } + void dispose() { disconnect(); _messageController.close(); diff --git a/lib/features/messaging/presentation/providers/messaging_provider.dart b/lib/features/messaging/presentation/providers/messaging_provider.dart index 0f3d603..3669bc6 100644 --- a/lib/features/messaging/presentation/providers/messaging_provider.dart +++ b/lib/features/messaging/presentation/providers/messaging_provider.dart @@ -106,6 +106,10 @@ class MessagingNotifier extends StateNotifier { final isMine = message.senderId == _currentUserId; if (isMine) return; + // Immediately ack delivery to backend so sender's tick goes single → double. + // This works regardless of Redis presence state and avoids races on send. + _socket.ackMessageReceived(convId, message.id); + currentMessages.insert(0, message); final updatedMessages = Map>.from(state.messages)