feat(chats): полная загрузка списка чатов через пагинацию (opcode 53)
This commit is contained in:
@@ -586,6 +586,7 @@ class AccountModule {
|
|||||||
await _saveSyncState(data, serverTime, profile.id);
|
await _saveSyncState(data, serverTime, profile.id);
|
||||||
await ContactsModule.syncFromLoginPayload(data, profile.id);
|
await ContactsModule.syncFromLoginPayload(data, profile.id);
|
||||||
await chats.syncFromLoginPayload(data, profile.id, profile.id);
|
await chats.syncFromLoginPayload(data, profile.id, profile.id);
|
||||||
|
unawaited(chats.paginateChats(_api, profile.id, profile.id, data));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ContactsModule.syncFromServer(_api, profile.id);
|
await ContactsModule.syncFromServer(_api, profile.id);
|
||||||
|
|||||||
@@ -372,6 +372,8 @@ class ChatsModule {
|
|||||||
final _messageEventsController = StreamController<MessageEvent>.broadcast();
|
final _messageEventsController = StreamController<MessageEvent>.broadcast();
|
||||||
Stream<MessageEvent> get messageEvents => _messageEventsController.stream;
|
Stream<MessageEvent> get messageEvents => _messageEventsController.stream;
|
||||||
|
|
||||||
|
int? _paginatedAccountId;
|
||||||
|
|
||||||
void emitMessageSent(int chatId, String tempId, CachedMessage message) {
|
void emitMessageSent(int chatId, String tempId, CachedMessage message) {
|
||||||
_messageEventsController.add(MessageSentEvent(chatId, tempId, message));
|
_messageEventsController.add(MessageSentEvent(chatId, tempId, message));
|
||||||
}
|
}
|
||||||
@@ -1136,42 +1138,100 @@ class ChatsModule {
|
|||||||
? data['presence'] as Map
|
? data['presence'] as Map
|
||||||
: {};
|
: {};
|
||||||
PresenceFetch.primeAll(presenceMap);
|
PresenceFetch.primeAll(presenceMap);
|
||||||
final cachedAt = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
|
|
||||||
final existingRows = await AppDatabase.loadChats(accountId);
|
await _persistChatMaps(
|
||||||
final existing = {
|
chats,
|
||||||
for (final row in existingRows)
|
accountId,
|
||||||
row['id'] as int: CachedChat.fromDbRow(row),
|
currentUserId,
|
||||||
};
|
contactsMap: contactsMap,
|
||||||
|
chatsConfig: chatsConfig,
|
||||||
final rows = <Map<String, dynamic>>[];
|
presenceMap: presenceMap,
|
||||||
for (final c in chats.whereType<Map>()) {
|
);
|
||||||
final map = c.cast<dynamic, dynamic>();
|
|
||||||
final parsed = parseChatRow(
|
|
||||||
map,
|
|
||||||
accountId,
|
|
||||||
currentUserId,
|
|
||||||
contactsMap,
|
|
||||||
chatsConfig,
|
|
||||||
presenceMap,
|
|
||||||
existing,
|
|
||||||
cachedAt,
|
|
||||||
);
|
|
||||||
if (parsed == null) continue;
|
|
||||||
final row = parsed.toDbRow();
|
|
||||||
row['in_list'] = map['status'] == 'HIDDEN' ? 2 : 1;
|
|
||||||
rows.add(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rows.isNotEmpty) {
|
|
||||||
await AppDatabase.saveChats(rows);
|
|
||||||
_bump();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.e("Ошибка при синке: $e");
|
logger.e("Ошибка при синке: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> _persistChatMaps(
|
||||||
|
List<dynamic> chats,
|
||||||
|
int accountId,
|
||||||
|
int currentUserId, {
|
||||||
|
Map<int, Map<dynamic, dynamic>> contactsMap = const {},
|
||||||
|
Map<dynamic, dynamic> chatsConfig = const {},
|
||||||
|
Map<dynamic, dynamic> presenceMap = const {},
|
||||||
|
}) async {
|
||||||
|
final cachedAt = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
final existingRows = await AppDatabase.loadChats(
|
||||||
|
accountId,
|
||||||
|
includeHidden: true,
|
||||||
|
);
|
||||||
|
final existing = {
|
||||||
|
for (final row in existingRows)
|
||||||
|
row['id'] as int: CachedChat.fromDbRow(row),
|
||||||
|
};
|
||||||
|
|
||||||
|
final rows = <Map<String, dynamic>>[];
|
||||||
|
for (final c in chats.whereType<Map>()) {
|
||||||
|
final map = c.cast<dynamic, dynamic>();
|
||||||
|
final parsed = parseChatRow(
|
||||||
|
map,
|
||||||
|
accountId,
|
||||||
|
currentUserId,
|
||||||
|
contactsMap,
|
||||||
|
chatsConfig,
|
||||||
|
presenceMap,
|
||||||
|
existing,
|
||||||
|
cachedAt,
|
||||||
|
);
|
||||||
|
if (parsed == null) continue;
|
||||||
|
final row = parsed.toDbRow();
|
||||||
|
row['in_list'] = map['status'] == 'HIDDEN' ? 2 : 1;
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.isNotEmpty) {
|
||||||
|
await AppDatabase.saveChats(rows);
|
||||||
|
_bump();
|
||||||
|
}
|
||||||
|
return rows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> paginateChats(
|
||||||
|
Api api,
|
||||||
|
int accountId,
|
||||||
|
int currentUserId,
|
||||||
|
Map<dynamic, dynamic> loginData,
|
||||||
|
) async {
|
||||||
|
if (_paginatedAccountId == accountId) return;
|
||||||
|
_paginatedAccountId = accountId;
|
||||||
|
try {
|
||||||
|
var marker = loginData['chatMarker'];
|
||||||
|
if (marker is! int || marker <= 0) return;
|
||||||
|
|
||||||
|
const count = 50;
|
||||||
|
var page = 0;
|
||||||
|
while (page < 200) {
|
||||||
|
page++;
|
||||||
|
final resp = await api.sendRequestMap(Opcode.chatsList, {
|
||||||
|
'marker': marker,
|
||||||
|
'count': count,
|
||||||
|
});
|
||||||
|
if (resp == null) break;
|
||||||
|
final chats = resp['chats'];
|
||||||
|
if (chats is! List || chats.isEmpty) break;
|
||||||
|
|
||||||
|
await _persistChatMaps(chats, accountId, currentUserId);
|
||||||
|
|
||||||
|
final next = resp['marker'];
|
||||||
|
if (next is! int || next == marker || chats.length < count) break;
|
||||||
|
marker = next;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_paginatedAccountId = null;
|
||||||
|
logger.w('Пагинация чатов: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<CachedChat>> getChats(
|
Future<List<CachedChat>> getChats(
|
||||||
int accountId, {
|
int accountId, {
|
||||||
bool includeHidden = false,
|
bool includeHidden = false,
|
||||||
|
|||||||
Reference in New Issue
Block a user