Chepuhagram/lib/logic/contact_provider.dart

124 lines
4.2 KiB
Dart

import 'package:flutter/material.dart';
import '/data/models/contact_model.dart';
import '/data/repositories/contact_repository.dart';
import '/data/datasources/local_db_service.dart';
import '/domain/services/crypto_service.dart';
class ContactProvider extends ChangeNotifier {
final ContactRepository _repository = ContactRepository();
final LocalDbService _localDbService = LocalDbService();
final CryptoService _cryptoService = CryptoService();
List<Contact> _contacts = [];
List<Contact> _allContacts = [];
bool _isLoading = false;
bool _isFirstLoad = true;
String? _error;
int? _currentUserId;
List<Contact> get contacts => _contacts;
List<Contact> get allContacts => _allContacts;
bool get isLoading => _isLoading;
String? get error => _error;
void setCurrentUserId(int? id) {
_currentUserId = id;
notifyListeners();
}
int? getCurrentUserId() {
return _currentUserId;
}
Future<void> loadContacts() async {
if (_isFirstLoad) {
_isFirstLoad = false;
_isLoading = true;
}
_error = null;
notifyListeners();
try {
final allContacts = await _repository.fetchChatContacts();
// Фильтруем: исключаем себя (для основного списка - только чаты)
_contacts = allContacts
.where((contact) => contact.id != _currentUserId)
.toList();
_allContacts = _contacts;
_isLoading = false;
notifyListeners();
// Обогащаем превью последним сообщением из локальной БД, не блокируя UI.
_enrichContactsWithLastMessages();
} catch (e) {
_error = e.toString();
} finally {
// Если ошибка — выходим из состояния загрузки тут.
// Если всё ок — `_isLoading` уже сброшен выше, чтобы показать список быстрее.
if (_error != null) {
_isLoading = false;
}
notifyListeners();
}
}
// Метод для получения всех контактов (исключая себя) для нового чата
Future<void> loadAllContactsForNewChat() async {
_isLoading = true;
_error = null;
notifyListeners();
try {
final allContacts = await _repository.fetchAllUsers();
// Фильтруем только исключение самого себя
_allContacts = allContacts
.where((contact) => contact.id != _currentUserId)
.toList();
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
Future<void> _enrichContactsWithLastMessages() async {
print("Начинаем обогащать контакты последними сообщениями из локальной БД... Для текущего пользователя ID: $_currentUserId");
final myId = _currentUserId;
if (myId == null) return;
print("Текущий пользователь ID: $myId");
final myPrivKey = await _cryptoService.getPrivateKey();
final List<Contact> updated = List<Contact>.from(_contacts);
for (int i = 0; i < updated.length; i++) {
final contact = updated[i];
// 1) Если сервер уже прислал lastMessage — попробуем расшифровать превью.
print(contact.lastMessage);
if (contact.lastMessage != null &&
contact.lastMessage!.isNotEmpty &&
myPrivKey != null &&
contact.publicKey != null) {
try {
final sharedSecret = await _cryptoService.deriveSharedSecret(
myPrivKey,
contact.publicKey!,
);
final decrypted = await _cryptoService.decryptMessage(
contact.lastMessage!,
sharedSecret,
);
updated[i] = contact.copyWith(lastMessage: decrypted);
} catch (_) {
// Если расшифровать не удалось — оставляем как есть, дальше попробуем локальную БД.
}
}
}
_contacts = updated;
_allContacts = updated;
notifyListeners();
}
}