syncConversation method
Syncs a specific conversation. Returns the SyncResult if successful.
Implementation
@override
Future<SyncResult?> syncConversation(String conversationId) async {
_syncStatusController.add(SyncStatus.syncing);
ChatLogger.info('Syncing conversation $conversationId');
try {
final result = await _adapter.syncConversation(conversationId);
// Save all data atomically within a transaction
await _database.runInTransaction(() async {
// Save conversations to database
for (final conversation in result.conversations) {
await _database.insertConversation(conversation);
}
// Save messages to database
for (final message in result.messages) {
await _database.insertMessage(message);
}
// Update the conversation's last message to the newest message from
// the sync. Without this, the conversation list preview stays stale
// because only the socket path (handleEvent → _handleMessageEvent)
// called updateConversationLastMessage. The newer-than guard in
// updateConversationLastMessage ensures we never overwrite with an
// older one.
if (result.messages.isNotEmpty) {
final newest = result.messages.reduce((a, b) {
final aTime = a.serverTimestamp ?? a.clientTimestamp;
final bTime = b.serverTimestamp ?? b.clientTimestamp;
return aTime.isAfter(bTime) ? a : b;
});
final newestTime = newest.serverTimestamp ?? newest.clientTimestamp;
await _database.updateConversationLastMessage(
conversationId,
messageId: newest.id,
messageAt: newestTime,
incrementUnread: false,
);
}
});
_syncStatusController.add(SyncStatus.completed);
ChatLogger.info('Conversation sync completed: $conversationId');
return result;
} catch (e, s) {
ChatLogger.error('Conversation sync failed: $conversationId', e, s);
_syncStatusController.add(SyncStatus.error);
rethrow;
}
}