diff --git a/lib/features/messaging/presentation/screens/chat_screen.dart b/lib/features/messaging/presentation/screens/chat_screen.dart index 770bf97..98f95fa 100644 --- a/lib/features/messaging/presentation/screens/chat_screen.dart +++ b/lib/features/messaging/presentation/screens/chat_screen.dart @@ -44,10 +44,21 @@ class _ChatScreenState extends ConsumerState final notifier = ref.read(messagingProvider.notifier); notifier.setActiveConversation(widget.conversationId); notifier.loadMessages(widget.conversationId); - notifier.markAsRead(widget.conversationId); // Initialize mute/star state from conversation data final conversations = ref.read(messagingProvider).conversations; final conv = conversations.where((c) => c.id == widget.conversationId).firstOrNull; + // Only mark as read when (a) there are actually unread messages and + // (b) the user stays on the chat long enough to be considered "viewing" + // it. If they accidentally tap a tile and bounce back, `mounted` will + // be false and we skip the read receipt — avoiding false blue ticks. + final hasUnread = (conv?.unreadCount ?? 0) > 0; + if (hasUnread) { + Future.delayed(const Duration(milliseconds: 600), () { + if (mounted) { + notifier.markAsRead(widget.conversationId); + } + }); + } if (conv != null) { final currentUserId = ref.read(currentUserIdProvider); final isUser = conv.userId == currentUserId; @@ -91,11 +102,20 @@ class _ChatScreenState extends ConsumerState } @override - void dispose() { - // Defer provider modification to avoid "modify during build" error - final notifier = ref.read(messagingProvider.notifier); - Future.microtask(() => notifier.setActiveConversation(null)); + void deactivate() { + // Clear active conversation BEFORE the widget tree is disposed so the + // messaging_provider's onNewMessage listener immediately stops + // auto-marking incoming messages as read for this chat. dispose() runs + // too late and used a microtask which created a race window. + try { + ref.read(messagingProvider.notifier).setActiveConversation(null); + } catch (_) {} + PushNotificationService().activeConversationId = null; + super.deactivate(); + } + @override + void dispose() { WidgetsBinding.instance.removeObserver(this); _connectionSub?.cancel(); // Stop typing and leave room before disposing @@ -272,8 +292,7 @@ class _ChatScreenState extends ConsumerState } void _handleBack() { - final notifier = ref.read(messagingProvider.notifier); - Future.microtask(() => notifier.setActiveConversation(null)); + // deactivate() will clear activeConversationId — no need to do it here. if (Navigator.of(context).canPop()) { Navigator.of(context).pop(); } else {