150 lines
5.1 KiB
Dart
150 lines
5.1 KiB
Dart
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();
|
|
});
|