200 lines
5.9 KiB
Dart
200 lines
5.9 KiB
Dart
import 'dart:convert';
|
||
import 'package:http/http.dart' as http;
|
||
import '/core/constants.dart';
|
||
import '/data/models/contact_model.dart';
|
||
import '/domain/services/api_service.dart';
|
||
import 'package:flutter_http_cache/flutter_http_cache.dart';
|
||
|
||
class ContactRepository {
|
||
late final CachedHttpClient _client;
|
||
bool _isCacheInitialized = false;
|
||
final ApiService _apiService = ApiService();
|
||
|
||
ContactRepository() {
|
||
_initCachedClient();
|
||
}
|
||
|
||
// Единая инициализация кэша для всех запросов репозитория
|
||
void _initCachedClient() {
|
||
final cache = _apiService.cache;
|
||
_client = CachedHttpClient(
|
||
cache: cache,
|
||
defaultCachePolicy: CachePolicy.networkFirst,
|
||
);
|
||
}
|
||
|
||
Future<void> _ensureCacheReady() async {
|
||
if (!_isCacheInitialized) {
|
||
await _apiService.cache.initialize();
|
||
_isCacheInitialized = true;
|
||
}
|
||
}
|
||
|
||
Future<List<Contact>> fetchChatContacts({bool forceRefresh = false}) async {
|
||
final token = await _apiService.getAccessToken();
|
||
|
||
DateTime now = DateTime.now();
|
||
Duration offset = now.timeZoneOffset;
|
||
|
||
final Map<String, String> requestHeaders = {
|
||
'Authorization': 'Bearer $token',
|
||
'Content-Type': 'application/json',
|
||
};
|
||
|
||
if (forceRefresh) {
|
||
requestHeaders['Cache-Control'] = 'no-cache';
|
||
}
|
||
|
||
await _ensureCacheReady();
|
||
|
||
try {
|
||
final response = await _client.get(
|
||
Uri.parse('${AppConstants.baseUrl}/users/chats'),
|
||
headers: requestHeaders,
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
|
||
print(data);
|
||
return data.map((json) {
|
||
final contact = Contact.fromJson(json);
|
||
print(contact.lastMessageType);
|
||
if (contact.lastMessageTime != null) {
|
||
return contact.copyWith(
|
||
lastMessageTime: contact.lastMessageTime!.add(offset),
|
||
);
|
||
}
|
||
return contact;
|
||
}).toList();
|
||
} else {
|
||
throw Exception('Failed to load contacts');
|
||
}
|
||
} catch (e) {
|
||
print(
|
||
'⚠️ Ошибка сети при загрузке контактов: $e. Пробуем строгий кэш...',
|
||
);
|
||
|
||
// FALLBACK: Если сеть упала, принудительно создаем запрос с политикой cacheOnly
|
||
final offlineClient = CachedHttpClient(
|
||
cache: _apiService.cache,
|
||
defaultCachePolicy: CachePolicy.cacheOnly, // Читаем строго из кэша
|
||
);
|
||
|
||
try {
|
||
final response = await offlineClient.get(
|
||
Uri.parse('${AppConstants.baseUrl}/users/chats'),
|
||
headers: requestHeaders,
|
||
);
|
||
|
||
final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
|
||
return data.map((json) => Contact.fromJson(json)).toList();
|
||
} catch (cacheError) {
|
||
throw Exception('Нет доступа к сети. Проверте подключение к интернету.');
|
||
}
|
||
}
|
||
}
|
||
|
||
Future<List<Contact>> fetchAllUsers({bool forceRefresh = false}) async {
|
||
final token = await _apiService.getAccessToken();
|
||
|
||
DateTime now = DateTime.now();
|
||
Duration offset = now.timeZoneOffset;
|
||
|
||
if (token == null) {
|
||
throw Exception('No access token');
|
||
}
|
||
|
||
final Map<String, String> requestHeaders = {
|
||
'Authorization': 'Bearer $token',
|
||
'Content-Type': 'application/json',
|
||
};
|
||
|
||
if (forceRefresh) {
|
||
requestHeaders['Cache-Control'] = 'no-cache';
|
||
}
|
||
await _ensureCacheReady();
|
||
final response = await _client.get(
|
||
Uri.parse('${AppConstants.baseUrl}/users/all'),
|
||
headers: requestHeaders,
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
|
||
return data.map((json) {
|
||
final contact = Contact.fromJson(json);
|
||
if (contact.lastMessageTime != null) {
|
||
return contact.copyWith(
|
||
lastMessageTime: contact.lastMessageTime!.add(offset),
|
||
);
|
||
}
|
||
return contact;
|
||
}).toList();
|
||
} else {
|
||
throw Exception('Failed to load contacts');
|
||
}
|
||
}
|
||
|
||
Future<Contact> fetchContactById(
|
||
int userId, {
|
||
bool forceRefresh = false,
|
||
}) async {
|
||
final token = await _apiService.getAccessToken();
|
||
|
||
final Map<String, String> requestHeaders = {
|
||
'Authorization': 'Bearer $token',
|
||
'Content-Type': 'application/json',
|
||
};
|
||
|
||
if (forceRefresh) {
|
||
requestHeaders['Cache-Control'] = 'no-cache';
|
||
}
|
||
await _ensureCacheReady();
|
||
final response = await _client.get(
|
||
Uri.parse('${AppConstants.baseUrl}/users/$userId'),
|
||
headers: requestHeaders,
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(utf8.decode(response.bodyBytes));
|
||
return Contact.fromJson(data);
|
||
} else {
|
||
throw Exception('Не удалось загрузить данные контакта');
|
||
}
|
||
}
|
||
|
||
Future<List<Map<String, dynamic>>> getLastMessagesForContact(
|
||
int contactId, {
|
||
int limit = 2,
|
||
bool forceRefresh = false,
|
||
}) async {
|
||
final token = await _apiService.getAccessToken();
|
||
if (token == null) {
|
||
throw Exception('No access token');
|
||
}
|
||
|
||
final Map<String, String> requestHeaders = {
|
||
'Authorization': 'Bearer $token',
|
||
'Content-Type': 'application/json',
|
||
};
|
||
|
||
if (forceRefresh) {
|
||
requestHeaders['Cache-Control'] = 'no-cache';
|
||
}
|
||
|
||
await _ensureCacheReady();
|
||
final response = await _client.get(
|
||
Uri.parse(
|
||
'${AppConstants.baseUrl}/messages/last?contact_id=$contactId&limit=$limit',
|
||
),
|
||
headers: requestHeaders,
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
|
||
return data.map((item) => item as Map<String, dynamic>).toList();
|
||
} else {
|
||
throw Exception('Failed to load last messages');
|
||
}
|
||
}
|
||
}
|