руки переломаю

This commit is contained in:
prime
2026-04-29 19:02:44 +10:00
parent 5db5dfabf5
commit d9cbadbbb7
20 changed files with 145 additions and 66 deletions
+6
View File
@@ -237,6 +237,11 @@ class Api {
_dispatcher.registerHandler(opcode, handler);
}
/// Снимает обработчик пушей с указанного опкода.
void unregisterPushHandler(int opcode) {
_dispatcher.unregisterHandler(opcode);
}
/// Стрим всех входящих пушей от сервера.
Stream<Packet> get pushStream => _dispatcher.pushStream;
@@ -248,6 +253,7 @@ class Api {
_connection.dispose();
_stateController.close();
_sessionExpiredController.close();
_handshakeSuccessController.close();
}
// Внутрянка
+1 -1
View File
@@ -25,7 +25,7 @@ class ChatFolder {
factory ChatFolder.fromJson(Map<String, dynamic> json) {
return ChatFolder(
id: json['id'].toString(),
id: json['id']?.toString() ?? '',
title: json['title']?.toString() ?? '',
emoji: json['emoji']?.toString(),
include: (json['include'] as List<dynamic>?)
+17 -11
View File
@@ -289,7 +289,7 @@ class LoginSyncParams {
draftsSync: int.tryParse(values[SyncKey.draftsSync] ?? '') ?? 0,
bannersSync: int.tryParse(values[SyncKey.bannersSync] ?? '') ?? 0,
presenceSync: int.tryParse(values[SyncKey.presenceSync] ?? '') ?? -1,
lastLogin: int.parse(lastLogin),
lastLogin: int.tryParse(lastLogin) ?? 0,
configHash: values[SyncKey.configHash],
chatCacheFingerprint: values[SyncKey.chatCacheFingerprint],
);
@@ -646,19 +646,25 @@ class AccountModule {
Future<ProfileData> _processProfileUpdate(Packet packet) async {
_api.registerPushHandler(Opcode.notifProfile, (p) {});
await for (final push in _api.pushStream.where(
(p) => p.opcode == Opcode.notifProfile,
)) {
final payload = push.payload;
if (payload is Map) {
final profile = payload['profile'];
if (profile is Map) {
final contact = profile['contact'];
if (contact is Map) {
return ProfileData.fromServerMap(contact.cast<dynamic, dynamic>());
try {
await for (final push in _api.pushStream
.where((p) => p.opcode == Opcode.notifProfile)
.timeout(const Duration(seconds: 15))) {
final payload = push.payload;
if (payload is Map) {
final profile = payload['profile'];
if (profile is Map) {
final contact = profile['contact'];
if (contact is Map) {
return ProfileData.fromServerMap(contact.cast<dynamic, dynamic>());
}
}
}
}
} on TimeoutException {
throw Exception('Таймаут ожидания обновления профиля');
} finally {
_api.unregisterPushHandler(Opcode.notifProfile);
}
throw Exception('Не удалось получить обновлённый профиль');
}
+2 -2
View File
@@ -92,8 +92,8 @@ class CallsModule {
msg['id']?.toString() ??
DateTime.now().millisecondsSinceEpoch.toString();
final name = contact?.firstName != null
? '${contact!.firstName} ${contact.lastName ?? ''}'.trim()
final name = (contact != null && contact.firstName.isNotEmpty)
? '${contact.firstName} ${contact.lastName ?? ''}'.trim()
: 'Неизвестный';
extractedCalls.add(
+23 -9
View File
@@ -3,6 +3,21 @@ import 'dart:convert';
import '../../core/storage/app_database.dart';
import '../../core/utils/logger.dart';
Map<int, int> _parseParticipants(dynamic raw) {
try {
final decoded = raw is String ? jsonDecode(raw) : raw;
if (decoded is Map) {
return decoded.map((k, v) => MapEntry(
k is int ? k : int.parse(k.toString()),
v is int ? v : int.tryParse(v.toString()) ?? 0,
));
}
} catch (e) {
logger.e('Failed to parse participants: $e');
}
return {};
}
class CachedChat {
final int id;
final int accountId;
@@ -59,8 +74,7 @@ class CachedChat {
dontDisturbUntil: row['dont_disturb_until'] as int,
isOnline: (row['is_online'] as int) == 1,
seenTime: row['seen_time'] as int,
// watafuc
participants: Map<String, int>.from(jsonDecode(row['participants'])).map((k, v) => MapEntry(int.parse(k), v))
participants: _parseParticipants(row['participants'])
);
Map<String, dynamic> toDbRow() => {
@@ -242,7 +256,7 @@ class ChatsModule {
isOnline = (presence['status'] as int?) == 1;
}
}
Map<int, int> participants = Map<int, int>.from(chat['participants']);
Map<int, int> participants = _parseParticipants(chat['participants']);
return CachedChat(
id: id,
@@ -282,12 +296,12 @@ class ChatsModule {
static String? _nameFromContact(Map<dynamic, dynamic> contact) {
final names = contact['names'];
if (names is! List || names.isEmpty) return null;
final name =
names.firstWhere(
(n) => n is Map && n['type'] == 'ONEME',
orElse: () => names.first,
)
as Map;
final nameRaw = names.firstWhere(
(n) => n is Map && n['type'] == 'ONEME',
orElse: () => names.firstWhere((n) => n is Map, orElse: () => null),
);
if (nameRaw is! Map) return null;
final name = nameRaw;
return name['name'] as String?;
}
}
+6 -6
View File
@@ -72,12 +72,12 @@ class ContactsModule {
final names = contact['names'];
if (names is List && names.isNotEmpty) {
final name =
names.firstWhere(
(n) => n is Map && n['type'] == 'ONEME',
orElse: () => names.first,
)
as Map;
final nameRaw = names.firstWhere(
(n) => n is Map && n['type'] == 'ONEME',
orElse: () => names.firstWhere((n) => n is Map, orElse: () => null),
);
if (nameRaw is! Map) return null;
final name = nameRaw;
firstName = (name['firstName'] as String?) ?? '';
lastName = name['lastName'] as String?;
}
+9 -10
View File
@@ -155,7 +155,9 @@ class MessagesModule {
}
if (rows.isNotEmpty) {
AppDatabase.saveMessages(rows).ignore();
AppDatabase.saveMessages(rows).catchError((e) {
debugPrint('saveMessages error: $e');
});
}
return results;
@@ -257,9 +259,8 @@ class MessagesModule {
if (data is! Map) return null;
final content = data['content'];
if (content is String) {
return Uri.parse(content).host.isNotEmpty ? null : null;
}
if (content is Uint8List) return content;
if (content is List<int>) return Uint8List.fromList(content);
return null;
} catch (e) {
return null;
@@ -295,9 +296,8 @@ class MessagesModule {
if (data is! Map) return null;
final content = data['content'];
if (content is String) {
return Uri.parse(content).host.isNotEmpty ? null : null;
}
if (content is Uint8List) return content;
if (content is List<int>) return Uint8List.fromList(content);
return null;
} catch (e) {
return null;
@@ -333,9 +333,8 @@ class MessagesModule {
if (data is! Map) return null;
final content = data['content'];
if (content is String) {
return Uri.parse(content).host.isNotEmpty ? null : null;
}
if (content is Uint8List) return content;
if (content is List<int>) return Uint8List.fromList(content);
return null;
} catch (e) {
return null;