This commit is contained in:
pradeepkumar
2026-04-07 20:14:40 +05:30
parent 821e1a0689
commit 7737bcfd65

View File

@@ -44,10 +44,21 @@ class _ChatScreenState extends ConsumerState<ChatScreen>
final notifier = ref.read(messagingProvider.notifier); final notifier = ref.read(messagingProvider.notifier);
notifier.setActiveConversation(widget.conversationId); notifier.setActiveConversation(widget.conversationId);
notifier.loadMessages(widget.conversationId); notifier.loadMessages(widget.conversationId);
notifier.markAsRead(widget.conversationId);
// Initialize mute/star state from conversation data // Initialize mute/star state from conversation data
final conversations = ref.read(messagingProvider).conversations; final conversations = ref.read(messagingProvider).conversations;
final conv = conversations.where((c) => c.id == widget.conversationId).firstOrNull; 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) { if (conv != null) {
final currentUserId = ref.read(currentUserIdProvider); final currentUserId = ref.read(currentUserIdProvider);
final isUser = conv.userId == currentUserId; final isUser = conv.userId == currentUserId;
@@ -91,11 +102,20 @@ class _ChatScreenState extends ConsumerState<ChatScreen>
} }
@override @override
void dispose() { void deactivate() {
// Defer provider modification to avoid "modify during build" error // Clear active conversation BEFORE the widget tree is disposed so the
final notifier = ref.read(messagingProvider.notifier); // messaging_provider's onNewMessage listener immediately stops
Future.microtask(() => notifier.setActiveConversation(null)); // 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); WidgetsBinding.instance.removeObserver(this);
_connectionSub?.cancel(); _connectionSub?.cancel();
// Stop typing and leave room before disposing // Stop typing and leave room before disposing
@@ -272,8 +292,7 @@ class _ChatScreenState extends ConsumerState<ChatScreen>
} }
void _handleBack() { void _handleBack() {
final notifier = ref.read(messagingProvider.notifier); // deactivate() will clear activeConversationId — no need to do it here.
Future.microtask(() => notifier.setActiveConversation(null));
if (Navigator.of(context).canPop()) { if (Navigator.of(context).canPop()) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} else { } else {