140 lines
4.0 KiB
Dart
140 lines
4.0 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.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 {
|
|
final List<Map<String, dynamic>> pendingRequests;
|
|
final List<Map<String, dynamic>> connections;
|
|
final bool isLoading;
|
|
final String? error;
|
|
final Set<String> processingIds;
|
|
|
|
const AgentNetworkState({
|
|
this.pendingRequests = const [],
|
|
this.connections = const [],
|
|
this.isLoading = true,
|
|
this.error,
|
|
this.processingIds = const {},
|
|
});
|
|
|
|
AgentNetworkState copyWith({
|
|
List<Map<String, dynamic>>? pendingRequests,
|
|
List<Map<String, dynamic>>? connections,
|
|
bool? isLoading,
|
|
String? error,
|
|
Set<String>? processingIds,
|
|
bool clearError = false,
|
|
}) {
|
|
return AgentNetworkState(
|
|
pendingRequests: pendingRequests ?? this.pendingRequests,
|
|
connections: connections ?? this.connections,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
error: clearError ? null : (error ?? this.error),
|
|
processingIds: processingIds ?? this.processingIds,
|
|
);
|
|
}
|
|
}
|
|
|
|
class AgentNetworkNotifier extends StateNotifier<AgentNetworkState> {
|
|
final AgentsRepository _repo;
|
|
StreamSubscription? _connectionRequestSub;
|
|
|
|
AgentNetworkNotifier(this._repo) : super(const AgentNetworkState()) {
|
|
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 {
|
|
state = state.copyWith(isLoading: true, clearError: true);
|
|
try {
|
|
final results = await Future.wait([
|
|
_repo.getReceivedRequests('PENDING'),
|
|
_repo.getReceivedRequests('ACCEPTED'),
|
|
]);
|
|
state = state.copyWith(
|
|
pendingRequests: results[0],
|
|
connections: results[1],
|
|
isLoading: false,
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
error: 'Failed to load network data',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> acceptRequest(String requestId) async {
|
|
if (state.processingIds.contains(requestId)) return;
|
|
state = state.copyWith(
|
|
processingIds: {...state.processingIds, requestId},
|
|
);
|
|
|
|
final success = await _repo.respondToRequest(requestId, 'ACCEPTED');
|
|
if (success) {
|
|
// Move from pending to connections
|
|
final request = state.pendingRequests.firstWhere(
|
|
(r) => r['id'] == requestId,
|
|
orElse: () => <String, dynamic>{},
|
|
);
|
|
state = state.copyWith(
|
|
pendingRequests:
|
|
state.pendingRequests.where((r) => r['id'] != requestId).toList(),
|
|
connections: request.isNotEmpty
|
|
? [request, ...state.connections]
|
|
: state.connections,
|
|
processingIds: state.processingIds
|
|
.where((id) => id != requestId)
|
|
.toSet(),
|
|
);
|
|
} else {
|
|
state = state.copyWith(
|
|
processingIds: state.processingIds
|
|
.where((id) => id != requestId)
|
|
.toSet(),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> rejectRequest(String requestId) async {
|
|
if (state.processingIds.contains(requestId)) return;
|
|
state = state.copyWith(
|
|
processingIds: {...state.processingIds, requestId},
|
|
);
|
|
|
|
final success = await _repo.respondToRequest(requestId, 'REJECTED');
|
|
if (success) {
|
|
state = state.copyWith(
|
|
pendingRequests:
|
|
state.pendingRequests.where((r) => r['id'] != requestId).toList(),
|
|
processingIds: state.processingIds
|
|
.where((id) => id != requestId)
|
|
.toSet(),
|
|
);
|
|
} else {
|
|
state = state.copyWith(
|
|
processingIds: state.processingIds
|
|
.where((id) => id != requestId)
|
|
.toSet(),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
final agentNetworkProvider =
|
|
StateNotifierProvider.autoDispose<AgentNetworkNotifier, AgentNetworkState>(
|
|
(ref) => AgentNetworkNotifier(AgentsRepository()),
|
|
);
|