From 54fdd66270293638e5ecbe8d7c64914177a2a172 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Sun, 15 Mar 2026 00:30:12 +0530 Subject: [PATCH] feat: Manage socket connection lifecycle based on authentication status and ensure chat screen joins rooms only when socket is connected. --- .../auth/presentation/providers/auth_provider.dart | 14 ++++++++++++++ .../presentation/screens/chat_screen.dart | 13 +++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/features/auth/presentation/providers/auth_provider.dart b/lib/features/auth/presentation/providers/auth_provider.dart index 6bee8f0..52e4cde 100644 --- a/lib/features/auth/presentation/providers/auth_provider.dart +++ b/lib/features/auth/presentation/providers/auth_provider.dart @@ -6,6 +6,7 @@ import 'package:real_estate_mobile/core/storage/secure_storage.dart'; import 'package:real_estate_mobile/features/auth/data/auth_repository.dart'; import 'package:real_estate_mobile/features/auth/data/models/register_request.dart'; import 'package:real_estate_mobile/features/auth/data/models/user_model.dart'; +import 'package:real_estate_mobile/features/messaging/data/socket_service.dart'; // Auth state enum AuthStatus { initial, loading, authenticated, error } @@ -69,6 +70,7 @@ class AuthNotifier extends StateNotifier { // Wire up force logout callback so API client can reset auth state // when token refresh fails ApiClient.onForceLogout = () { + SocketService().disconnect(); state = const AuthState(); }; checkAuthStatus(); @@ -89,6 +91,8 @@ class AuthNotifier extends StateNotifier { status: AuthStatus.authenticated, user: user, ); + // Connect socket for real-time updates (matching web's PresenceProvider) + _connectSocket(); // Register for push notifications after auth confirmed _initPushNotifications(); } catch (_) { @@ -100,6 +104,8 @@ class AuthNotifier extends StateNotifier { Future logout() async { state = state.copyWith(status: AuthStatus.loading); + // Disconnect socket before logout + SocketService().disconnect(); // Unregister FCM token before clearing auth await PushNotificationService().unregister(); await _repository.logout(); @@ -136,6 +142,7 @@ class AuthNotifier extends StateNotifier { status: AuthStatus.authenticated, user: result['user'] as UserModel, ); + _connectSocket(); _initPushNotifications(); } on ApiException catch (e) { state = state.copyWith( @@ -186,6 +193,7 @@ class AuthNotifier extends StateNotifier { user: user, registeredEmail: email, ); + _connectSocket(); _initPushNotifications(); } on ApiException catch (e) { state = state.copyWith( @@ -221,6 +229,7 @@ class AuthNotifier extends StateNotifier { status: AuthStatus.authenticated, user: authResponse.user, ); + _connectSocket(); _initPushNotifications(); } on ApiException catch (e) { state = state.copyWith( @@ -253,6 +262,7 @@ class AuthNotifier extends StateNotifier { status: AuthStatus.authenticated, user: authResponse.user, ); + _connectSocket(); _initPushNotifications(); } on ApiException catch (e) { state = state.copyWith( @@ -271,6 +281,10 @@ class AuthNotifier extends StateNotifier { state = const AuthState(); } + void _connectSocket() { + SocketService().connect(); + } + void _initPushNotifications() { final push = PushNotificationService(); push.initialize().then((_) => push.registerAfterLogin()); diff --git a/lib/features/messaging/presentation/screens/chat_screen.dart b/lib/features/messaging/presentation/screens/chat_screen.dart index 759c6d2..4c0c7c4 100644 --- a/lib/features/messaging/presentation/screens/chat_screen.dart +++ b/lib/features/messaging/presentation/screens/chat_screen.dart @@ -37,8 +37,17 @@ class _ChatScreenState extends ConsumerState { notifier.setActiveConversation(widget.conversationId); notifier.loadMessages(widget.conversationId); notifier.markAsRead(widget.conversationId); - // Join socket room for real-time updates - _socket.joinConversation(widget.conversationId); + // Join socket room for real-time updates (socket is connected at auth time) + if (_socket.isConnected) { + _socket.joinConversation(widget.conversationId); + } else { + // Wait for socket connection then join + _socket.onConnectionChange.first.then((connected) { + if (connected && mounted) { + _socket.joinConversation(widget.conversationId); + } + }); + } }); _scrollController.addListener(_onScroll); _messageController.addListener(_onTextChanged);