feat: Implement real-time agent connection state updates and enhance app shell navigation transitions.

This commit is contained in:
pradeepkumar
2026-03-26 09:46:40 +05:30
parent e9d069b09b
commit 22187c8b13
4 changed files with 56 additions and 3 deletions

View File

@@ -41,9 +41,17 @@ class _AppShellState extends State<AppShell> {
), ),
Expanded( Expanded(
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 150),
switchInCurve: Curves.easeOut,
switchOutCurve: Curves.easeIn, switchOutCurve: Curves.easeIn,
switchInCurve: Curves.easeOut,
layoutBuilder: (currentChild, previousChildren) {
return Stack(
children: [
...previousChildren,
if (currentChild != null) currentChild,
],
);
},
transitionBuilder: (child, animation) { transitionBuilder: (child, animation) {
return FadeTransition( return FadeTransition(
opacity: animation, opacity: animation,
@@ -51,7 +59,7 @@ class _AppShellState extends State<AppShell> {
); );
}, },
child: KeyedSubtree( child: KeyedSubtree(
key: ValueKey(widget.child.runtimeType), key: ValueKey(GoRouterState.of(context).uri.toString()),
child: widget.child, child: widget.child,
), ),
), ),

View File

@@ -1,7 +1,10 @@
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:real_estate_mobile/features/agents/data/agents_repository.dart'; import 'package:real_estate_mobile/features/agents/data/agents_repository.dart';
import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart'; import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart';
import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart'; import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart';
import 'package:real_estate_mobile/features/messaging/data/socket_service.dart';
class AgentDetailState { class AgentDetailState {
final AgentProfile? agent; final AgentProfile? agent;
@@ -375,10 +378,22 @@ class SpecializationCard {
class AgentDetailNotifier extends StateNotifier<AgentDetailState> { class AgentDetailNotifier extends StateNotifier<AgentDetailState> {
final AgentsRepository _repo; final AgentsRepository _repo;
final String agentId; final String agentId;
StreamSubscription? _connectionResponseSub;
AgentDetailNotifier(this._repo, this.agentId) AgentDetailNotifier(this._repo, this.agentId)
: super(const AgentDetailState()) { : super(const AgentDetailState()) {
_load(); _load();
// Listen for real-time connection response (accepted/rejected)
_connectionResponseSub =
SocketService().onConnectionResponse.listen((_) {
if (mounted) loadConnectionStatus();
});
}
@override
void dispose() {
_connectionResponseSub?.cancel();
super.dispose();
} }
Future<void> _load() async { Future<void> _load() async {

View File

@@ -1,5 +1,8 @@
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:real_estate_mobile/features/agents/data/agents_repository.dart'; import 'package:real_estate_mobile/features/agents/data/agents_repository.dart';
import 'package:real_estate_mobile/features/messaging/data/socket_service.dart';
class AgentNetworkState { class AgentNetworkState {
final List<Map<String, dynamic>> pendingRequests; final List<Map<String, dynamic>> pendingRequests;
@@ -36,9 +39,21 @@ class AgentNetworkState {
class AgentNetworkNotifier extends StateNotifier<AgentNetworkState> { class AgentNetworkNotifier extends StateNotifier<AgentNetworkState> {
final AgentsRepository _repo; final AgentsRepository _repo;
StreamSubscription? _connectionRequestSub;
AgentNetworkNotifier(this._repo) : super(const AgentNetworkState()) { AgentNetworkNotifier(this._repo) : super(const AgentNetworkState()) {
loadData(); loadData();
// Listen for real-time connection request events
_connectionRequestSub =
SocketService().onConnectionRequest.listen((_) {
if (mounted) loadData();
});
}
@override
void dispose() {
_connectionRequestSub?.cancel();
super.dispose();
} }
Future<void> loadData() async { Future<void> loadData() async {

View File

@@ -32,6 +32,8 @@ class SocketService {
final _supportMessageController = StreamController<SupportMessage>.broadcast(); final _supportMessageController = StreamController<SupportMessage>.broadcast();
final _supportTypingStartController = StreamController<Map<String, dynamic>>.broadcast(); final _supportTypingStartController = StreamController<Map<String, dynamic>>.broadcast();
final _supportTypingStopController = StreamController<Map<String, dynamic>>.broadcast(); final _supportTypingStopController = StreamController<Map<String, dynamic>>.broadcast();
final _connectionRequestController = StreamController<Map<String, dynamic>>.broadcast();
final _connectionResponseController = StreamController<Map<String, dynamic>>.broadcast();
Stream<ChatMessage> get onNewMessage => _messageController.stream; Stream<ChatMessage> get onNewMessage => _messageController.stream;
Stream<Map<String, dynamic>> get onTypingStart => _typingStartController.stream; Stream<Map<String, dynamic>> get onTypingStart => _typingStartController.stream;
@@ -42,6 +44,8 @@ class SocketService {
Stream<SupportMessage> get onSupportMessage => _supportMessageController.stream; Stream<SupportMessage> get onSupportMessage => _supportMessageController.stream;
Stream<Map<String, dynamic>> get onSupportTypingStart => _supportTypingStartController.stream; Stream<Map<String, dynamic>> get onSupportTypingStart => _supportTypingStartController.stream;
Stream<Map<String, dynamic>> get onSupportTypingStop => _supportTypingStopController.stream; Stream<Map<String, dynamic>> get onSupportTypingStop => _supportTypingStopController.stream;
Stream<Map<String, dynamic>> get onConnectionRequest => _connectionRequestController.stream;
Stream<Map<String, dynamic>> get onConnectionResponse => _connectionResponseController.stream;
bool get isConnected => _isConnected; bool get isConnected => _isConnected;
Future<void> connect() async { Future<void> connect() async {
@@ -153,6 +157,15 @@ class SocketService {
_supportTypingStopController.add(Map<String, dynamic>.from(data as Map)); _supportTypingStopController.add(Map<String, dynamic>.from(data as Map));
}); });
// Connection request events (real-time updates)
_socket!.on('connection_request', (data) {
_connectionRequestController.add(Map<String, dynamic>.from(data as Map));
});
_socket!.on('connection_response', (data) {
_connectionResponseController.add(Map<String, dynamic>.from(data as Map));
});
_socket!.connect(); _socket!.connect();
} }
@@ -274,5 +287,7 @@ class SocketService {
_supportMessageController.close(); _supportMessageController.close();
_supportTypingStartController.close(); _supportTypingStartController.close();
_supportTypingStopController.close(); _supportTypingStopController.close();
_connectionRequestController.close();
_connectionResponseController.close();
} }
} }