feat: Manage socket connection lifecycle based on authentication status and ensure chat screen joins rooms only when socket is connected.
This commit is contained in:
@@ -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/auth_repository.dart';
|
||||||
import 'package:real_estate_mobile/features/auth/data/models/register_request.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/auth/data/models/user_model.dart';
|
||||||
|
import 'package:real_estate_mobile/features/messaging/data/socket_service.dart';
|
||||||
|
|
||||||
// Auth state
|
// Auth state
|
||||||
enum AuthStatus { initial, loading, authenticated, error }
|
enum AuthStatus { initial, loading, authenticated, error }
|
||||||
@@ -69,6 +70,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
// Wire up force logout callback so API client can reset auth state
|
// Wire up force logout callback so API client can reset auth state
|
||||||
// when token refresh fails
|
// when token refresh fails
|
||||||
ApiClient.onForceLogout = () {
|
ApiClient.onForceLogout = () {
|
||||||
|
SocketService().disconnect();
|
||||||
state = const AuthState();
|
state = const AuthState();
|
||||||
};
|
};
|
||||||
checkAuthStatus();
|
checkAuthStatus();
|
||||||
@@ -89,6 +91,8 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
status: AuthStatus.authenticated,
|
status: AuthStatus.authenticated,
|
||||||
user: user,
|
user: user,
|
||||||
);
|
);
|
||||||
|
// Connect socket for real-time updates (matching web's PresenceProvider)
|
||||||
|
_connectSocket();
|
||||||
// Register for push notifications after auth confirmed
|
// Register for push notifications after auth confirmed
|
||||||
_initPushNotifications();
|
_initPushNotifications();
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
@@ -100,6 +104,8 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
state = state.copyWith(status: AuthStatus.loading);
|
state = state.copyWith(status: AuthStatus.loading);
|
||||||
|
// Disconnect socket before logout
|
||||||
|
SocketService().disconnect();
|
||||||
// Unregister FCM token before clearing auth
|
// Unregister FCM token before clearing auth
|
||||||
await PushNotificationService().unregister();
|
await PushNotificationService().unregister();
|
||||||
await _repository.logout();
|
await _repository.logout();
|
||||||
@@ -136,6 +142,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
status: AuthStatus.authenticated,
|
status: AuthStatus.authenticated,
|
||||||
user: result['user'] as UserModel,
|
user: result['user'] as UserModel,
|
||||||
);
|
);
|
||||||
|
_connectSocket();
|
||||||
_initPushNotifications();
|
_initPushNotifications();
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
@@ -186,6 +193,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
user: user,
|
user: user,
|
||||||
registeredEmail: email,
|
registeredEmail: email,
|
||||||
);
|
);
|
||||||
|
_connectSocket();
|
||||||
_initPushNotifications();
|
_initPushNotifications();
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
@@ -221,6 +229,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
status: AuthStatus.authenticated,
|
status: AuthStatus.authenticated,
|
||||||
user: authResponse.user,
|
user: authResponse.user,
|
||||||
);
|
);
|
||||||
|
_connectSocket();
|
||||||
_initPushNotifications();
|
_initPushNotifications();
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
@@ -253,6 +262,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
status: AuthStatus.authenticated,
|
status: AuthStatus.authenticated,
|
||||||
user: authResponse.user,
|
user: authResponse.user,
|
||||||
);
|
);
|
||||||
|
_connectSocket();
|
||||||
_initPushNotifications();
|
_initPushNotifications();
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
@@ -271,6 +281,10 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
state = const AuthState();
|
state = const AuthState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _connectSocket() {
|
||||||
|
SocketService().connect();
|
||||||
|
}
|
||||||
|
|
||||||
void _initPushNotifications() {
|
void _initPushNotifications() {
|
||||||
final push = PushNotificationService();
|
final push = PushNotificationService();
|
||||||
push.initialize().then((_) => push.registerAfterLogin());
|
push.initialize().then((_) => push.registerAfterLogin());
|
||||||
|
|||||||
@@ -37,8 +37,17 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
|||||||
notifier.setActiveConversation(widget.conversationId);
|
notifier.setActiveConversation(widget.conversationId);
|
||||||
notifier.loadMessages(widget.conversationId);
|
notifier.loadMessages(widget.conversationId);
|
||||||
notifier.markAsRead(widget.conversationId);
|
notifier.markAsRead(widget.conversationId);
|
||||||
// Join socket room for real-time updates
|
// Join socket room for real-time updates (socket is connected at auth time)
|
||||||
_socket.joinConversation(widget.conversationId);
|
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);
|
_scrollController.addListener(_onScroll);
|
||||||
_messageController.addListener(_onTextChanged);
|
_messageController.addListener(_onTextChanged);
|
||||||
|
|||||||
Reference in New Issue
Block a user