feat: Implement messaging functionality with conversation and chat screens, and enhance agent detail views.
This commit is contained in:
149
lib/features/messaging/data/messaging_repository.dart
Normal file
149
lib/features/messaging/data/messaging_repository.dart
Normal file
@@ -0,0 +1,149 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:real_estate_mobile/core/constants/api_constants.dart';
|
||||
import 'package:real_estate_mobile/core/network/api_client.dart';
|
||||
import 'package:real_estate_mobile/core/network/api_exceptions.dart';
|
||||
import 'package:real_estate_mobile/features/messaging/data/models/messaging_models.dart';
|
||||
|
||||
final _log = Logger(printer: PrettyPrinter(methodCount: 0));
|
||||
|
||||
class MessagingRepository {
|
||||
final Dio _dio = ApiClient.instance.dio;
|
||||
|
||||
/// GET /messages/conversations
|
||||
Future<List<Conversation>> getConversations() async {
|
||||
try {
|
||||
final response = await _dio.get(ApiConstants.conversations);
|
||||
final data = response.data['data'] as List<dynamic>;
|
||||
return data
|
||||
.map((e) => Conversation.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to fetch conversations',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
} catch (e, stack) {
|
||||
_log.e('Conversation parsing error', error: e, stackTrace: stack);
|
||||
throw ApiException(message: 'Failed to parse conversations: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// POST /messages/conversations
|
||||
Future<Conversation> startConversation(String agentProfileId) async {
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
ApiConstants.conversations,
|
||||
data: {'agentProfileId': agentProfileId},
|
||||
);
|
||||
return Conversation.fromJson(
|
||||
response.data['data'] as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to start conversation',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /messages/conversations/:id
|
||||
Future<Conversation> getConversation(String id) async {
|
||||
try {
|
||||
final response = await _dio.get('${ApiConstants.conversations}/$id');
|
||||
return Conversation.fromJson(
|
||||
response.data['data'] as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to fetch conversation',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /messages/conversations/:id/messages?page=&limit=
|
||||
Future<({List<ChatMessage> messages, PaginationInfo pagination})> getMessages(
|
||||
String conversationId, {
|
||||
int page = 1,
|
||||
int limit = 50,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
'${ApiConstants.conversations}/$conversationId/messages',
|
||||
queryParameters: {'page': page, 'limit': limit},
|
||||
);
|
||||
final data = response.data['data'] as Map<String, dynamic>;
|
||||
final messages = (data['messages'] as List<dynamic>)
|
||||
.map((e) => ChatMessage.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
final pagination = PaginationInfo.fromJson(
|
||||
data['pagination'] as Map<String, dynamic>);
|
||||
return (messages: messages, pagination: pagination);
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to fetch messages',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// POST /messages/conversations/:id/messages
|
||||
Future<ChatMessage> sendMessage(
|
||||
String conversationId, {
|
||||
required String content,
|
||||
MessageType type = MessageType.text,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
'${ApiConstants.conversations}/$conversationId/messages',
|
||||
data: {
|
||||
'content': content,
|
||||
'messageType': type.toApiString(),
|
||||
},
|
||||
);
|
||||
return ChatMessage.fromJson(
|
||||
response.data['data'] as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to send message',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// PATCH /messages/conversations/:id/read
|
||||
Future<void> markAsRead(String conversationId) async {
|
||||
try {
|
||||
await _dio.patch('${ApiConstants.conversations}/$conversationId/read');
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to mark as read',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /messages/unread-count
|
||||
Future<int> getUnreadCount() async {
|
||||
try {
|
||||
final response = await _dio.get(ApiConstants.unreadCount);
|
||||
return response.data['data']['unreadCount'] as int? ?? 0;
|
||||
} on DioException catch (e) {
|
||||
if (e.error is ApiException) throw e.error as ApiException;
|
||||
throw ApiException(
|
||||
message: e.message ?? 'Failed to fetch unread count',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final messagingRepositoryProvider = Provider<MessagingRepository>((ref) {
|
||||
return MessagingRepository();
|
||||
});
|
||||
Reference in New Issue
Block a user