fix(transport): Zstd-распаковка, гонка PacketReceiver, fix имён и стикеров
This commit is contained in:
@@ -266,7 +266,15 @@ class Api {
|
||||
}
|
||||
|
||||
Future<void> _onDataReceived(Uint8List data) async {
|
||||
await for (final packet in _receiver.feed(data)) {
|
||||
final rawPackets = _receiver.feed(data);
|
||||
for (final raw in rawPackets) {
|
||||
final Packet packet;
|
||||
try {
|
||||
packet = await unpackPacket(raw);
|
||||
} catch (e) {
|
||||
logger.e('PacketReceiver: ошибка распаковки: $e');
|
||||
continue;
|
||||
}
|
||||
if (packet.isError &&
|
||||
packet.payload is Map &&
|
||||
(packet.payload['message'] == 'FAIL_LOGIN_TOKEN' ||
|
||||
|
||||
@@ -160,7 +160,6 @@ class ChatsModule {
|
||||
static Future<List<CachedChat>> getChats(int accountId) async {
|
||||
try {
|
||||
final rows = await AppDatabase.loadChats(accountId);
|
||||
|
||||
return rows.map(CachedChat.fromDbRow).toList();
|
||||
} catch (e) {
|
||||
logger.e("Ошибка при получении чатов: $e");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import '../../core/storage/app_database.dart';
|
||||
import 'messages.dart';
|
||||
|
||||
class CachedContact {
|
||||
final int id;
|
||||
@@ -44,22 +45,65 @@ class ContactsModule {
|
||||
final contacts = data['contacts'];
|
||||
if (contacts is! List || contacts.isEmpty) return;
|
||||
|
||||
final rows = contacts
|
||||
.whereType<Map>()
|
||||
.map((c) => _parseContact(c.cast<dynamic, dynamic>(), accountId))
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.toList();
|
||||
final rows = <Map<String, dynamic>>[];
|
||||
for (final raw in contacts.whereType<Map>()) {
|
||||
final contact = raw.cast<dynamic, dynamic>();
|
||||
final row = _parseContact(contact, accountId);
|
||||
if (row != null) rows.add(row);
|
||||
_primeContactCache(contact);
|
||||
}
|
||||
|
||||
if (rows.isNotEmpty) {
|
||||
await AppDatabase.saveContacts(rows);
|
||||
}
|
||||
}
|
||||
|
||||
static void _primeContactCache(Map<dynamic, dynamic> contact) {
|
||||
final id = contact['id'];
|
||||
if (id is! int) return;
|
||||
|
||||
final names = contact['names'];
|
||||
if (names is List && names.isNotEmpty) {
|
||||
final nameRaw = names.firstWhere(
|
||||
(n) => n is Map && n['type'] == 'ONEME',
|
||||
orElse: () => names.firstWhere((n) => n is Map, orElse: () => null),
|
||||
);
|
||||
if (nameRaw is Map) {
|
||||
final firstName = (nameRaw['firstName'] as String?) ?? '';
|
||||
final lastName = nameRaw['lastName'] as String?;
|
||||
final fullName = (lastName != null && lastName.isNotEmpty)
|
||||
? '$firstName $lastName'
|
||||
: firstName;
|
||||
if (fullName.isNotEmpty) ContactCache.put(id, fullName);
|
||||
}
|
||||
}
|
||||
|
||||
final baseUrl = contact['baseUrl'] as String?;
|
||||
if (baseUrl != null && baseUrl.isNotEmpty) {
|
||||
ContactCache.putAvatar(id, baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<CachedContact>> getContacts(int accountId) async {
|
||||
final rows = await AppDatabase.loadContacts(accountId);
|
||||
return rows.map(CachedContact.fromDbRow).toList();
|
||||
}
|
||||
|
||||
/// Прогревает in-memory ContactCache из локальных контактов.
|
||||
/// Нужно вызывать на cold start: иначе кэш пуст до следующего логина.
|
||||
static Future<void> primeCacheFromDb(int accountId) async {
|
||||
final contacts = await getContacts(accountId);
|
||||
for (final c in contacts) {
|
||||
final fullName = (c.lastName != null && c.lastName!.isNotEmpty)
|
||||
? '${c.firstName} ${c.lastName}'
|
||||
: c.firstName;
|
||||
if (fullName.isNotEmpty) ContactCache.put(c.id, fullName);
|
||||
if (c.baseUrl != null && c.baseUrl!.isNotEmpty) {
|
||||
ContactCache.putAvatar(c.id, c.baseUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, dynamic>? _parseContact(
|
||||
Map<dynamic, dynamic> contact,
|
||||
int accountId,
|
||||
|
||||
Reference in New Issue
Block a user