feat: Integrate AvatarRepository into chat components for improved avatar handling and caching

This commit is contained in:
2026-01-28 00:28:56 +05:00
parent f92bc8b0d5
commit 8702539d09
8 changed files with 142 additions and 73 deletions

View File

@@ -30,6 +30,11 @@ class AvatarRepository(
private const val MAX_AVATAR_HISTORY = 5 // Хранить последние N аватаров
}
// Repository scope для coroutines
private val repositoryScope = kotlinx.coroutines.CoroutineScope(
kotlinx.coroutines.SupervisorJob() + Dispatchers.IO
)
// In-memory cache (как decodedAvatarsCache в desktop)
// publicKey -> Flow<List<AvatarInfo>>
private val memoryCache = mutableMapOf<String, MutableStateFlow<List<AvatarInfo>>>()
@@ -49,9 +54,10 @@ class AvatarRepository(
val flow = MutableStateFlow<List<AvatarInfo>>(emptyList())
memoryCache[publicKey] = flow
// Подписываемся на изменения в БД
// Подписываемся на изменения в БД с использованием repository scope
avatarDao.getAvatars(publicKey)
.onEach { entities ->
Log.d(TAG, "📥 DB update for $publicKey: ${entities.size} entities")
val avatars = if (allDecode) {
// Загружаем всю историю
entities.mapNotNull { entity ->
@@ -64,8 +70,9 @@ class AvatarRepository(
}?.let { listOf(it) } ?: emptyList()
}
flow.value = avatars
Log.d(TAG, "✅ Flow updated for $publicKey: ${avatars.size} avatars")
}
.launchIn(kotlinx.coroutines.CoroutineScope(Dispatchers.IO))
.launchIn(repositoryScope)
return flow.asStateFlow()
}
@@ -90,6 +97,7 @@ class AvatarRepository(
try {
// Сохраняем файл
val filePath = AvatarFileManager.saveAvatar(context, base64Image, fromPublicKey)
Log.d(TAG, "💾 Avatar file saved for $fromPublicKey: $filePath")
// Сохраняем в БД
val entity = AvatarCacheEntity(
@@ -98,13 +106,26 @@ class AvatarRepository(
timestamp = System.currentTimeMillis()
)
avatarDao.insertAvatar(entity)
Log.d(TAG, "💾 Avatar entity inserted to DB for $fromPublicKey")
// Очищаем старые аватары (оставляем только последние N)
avatarDao.deleteOldAvatars(fromPublicKey, MAX_AVATAR_HISTORY)
Log.d(TAG, "Saved avatar for $fromPublicKey")
// 🔄 Обновляем memory cache если он существует
val cachedFlow = memoryCache[fromPublicKey]
if (cachedFlow != null) {
val avatarInfo = loadAndDecryptAvatar(entity)
if (avatarInfo != null) {
cachedFlow.value = listOf(avatarInfo)
Log.d(TAG, "✅ Memory cache updated for $fromPublicKey")
}
} else {
Log.d(TAG, " No memory cache for $fromPublicKey, will be loaded on next getAvatars()")
}
Log.d(TAG, "✅ Saved avatar for $fromPublicKey")
} catch (e: Exception) {
Log.e(TAG, "Failed to save avatar", e)
Log.e(TAG, "Failed to save avatar for $fromPublicKey", e)
}
}
}