mirror of
https://github.com/fromchat-messenger/app.git
synced 2026-09-22 19:15:05 +03:00
Fix public chat avatars being blank until profile is opened
Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
+4
-1
@@ -1,6 +1,7 @@
|
|||||||
package ru.fromchat.api.local.db.store
|
package ru.fromchat.api.local.db.store
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import ru.fromchat.api.ApiClient
|
import ru.fromchat.api.ApiClient
|
||||||
import ru.fromchat.api.local.messages.ChatListPreviewState
|
import ru.fromchat.api.local.messages.ChatListPreviewState
|
||||||
import ru.fromchat.api.local.messages.ChatListPreviewStrings
|
import ru.fromchat.api.local.messages.ChatListPreviewStrings
|
||||||
@@ -21,7 +22,9 @@ object MessageRepository {
|
|||||||
MessageCacheStore.observeMessages(activeInstance(), conversationId)
|
MessageCacheStore.observeMessages(activeInstance(), conversationId)
|
||||||
|
|
||||||
fun observePublicMessages(): Flow<List<Message>> =
|
fun observePublicMessages(): Flow<List<Message>> =
|
||||||
observeMessages(conversationIdForGroup(GENERAL_PUBLIC_GROUP_ID))
|
observeMessages(conversationIdForGroup(GENERAL_PUBLIC_GROUP_ID)).map { rows ->
|
||||||
|
ProfileCache.enrichPublicMessagesForDisplay(rows)
|
||||||
|
}
|
||||||
|
|
||||||
fun observeDmMessages(otherUserId: Int): Flow<List<Message>> =
|
fun observeDmMessages(otherUserId: Int): Flow<List<Message>> =
|
||||||
observeMessages(conversationIdForDm(otherUserId))
|
observeMessages(conversationIdForDm(otherUserId))
|
||||||
|
|||||||
@@ -454,30 +454,33 @@ object ProfileCache {
|
|||||||
val uid = message.user_id
|
val uid = message.user_id
|
||||||
if (uid <= 0) return
|
if (uid <= 0) return
|
||||||
val existing = get(uid)
|
val existing = get(uid)
|
||||||
|
val incomingDisplay = message.displayName?.trim()?.takeIf { it.isNotEmpty() }
|
||||||
|
val incomingPic = message.profile_picture?.takeIf { it.isNotBlank() }
|
||||||
if (existing != null && !existing.isClientPreviewOnly) {
|
if (existing != null && !existing.isClientPreviewOnly) {
|
||||||
val patched = existing.copy(
|
val patched = existing.copy(
|
||||||
verified = message.verified ?: existing.verified,
|
verified = message.verified ?: existing.verified,
|
||||||
verificationStatus = message.verificationStatus ?: existing.verificationStatus,
|
verificationStatus = message.verificationStatus ?: existing.verificationStatus,
|
||||||
|
displayName = existing.displayName?.takeIf { it.isNotBlank() } ?: incomingDisplay,
|
||||||
|
profilePicture = existing.profilePicture?.takeIf { it.isNotBlank() } ?: incomingPic,
|
||||||
|
username = existing.username.trim().ifBlank { message.username.trim() },
|
||||||
)
|
)
|
||||||
if (patched != existing) put(patched)
|
if (patched != existing) put(patched)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val uname = message.username.trim().ifBlank { existing?.username?.trim().orEmpty() }
|
val uname = message.username.trim().ifBlank { existing?.username?.trim().orEmpty() }
|
||||||
val incomingDisplay = message.displayName?.trim()?.takeIf { it.isNotEmpty() }
|
val displayName = incomingDisplay ?: existing?.displayName?.takeIf { it.isNotBlank() }
|
||||||
?: existing?.displayName?.takeIf { it.isNotBlank() }
|
if (uname.isBlank() && displayName.isNullOrBlank()) return
|
||||||
if (uname.isBlank() && incomingDisplay.isNullOrBlank()) return
|
if (uname.isBlank() || displayName.isNullOrBlank()) {
|
||||||
if (uname.isBlank() || incomingDisplay.isNullOrBlank()) {
|
|
||||||
Logger.d(
|
Logger.d(
|
||||||
"ProfileCache",
|
"ProfileCache",
|
||||||
"mergePreviewFromPublicMessage missingIdentity id=$uid " +
|
"mergePreviewFromPublicMessage missingIdentity id=$uid " +
|
||||||
"hasUsername=${uname.isNotBlank()} hasDisplayName=${!incomingDisplay.isNullOrBlank()}",
|
"hasUsername=${uname.isNotBlank()} hasDisplayName=${!displayName.isNullOrBlank()}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val isDeleted = isDeletedPlaceholderUsername(uname) || existing?.deleted == true
|
val isDeleted = isDeletedPlaceholderUsername(uname) || existing?.deleted == true
|
||||||
val display = if (isDeleted) null else incomingDisplay
|
val display = if (isDeleted) null else displayName
|
||||||
val pic = if (isDeleted) null else message.profile_picture?.takeIf { it.isNotBlank() }
|
val pic = if (isDeleted) null else incomingPic ?: existing?.profilePicture
|
||||||
?: existing?.profilePicture
|
|
||||||
|
|
||||||
put(
|
put(
|
||||||
UserProfile(
|
UserProfile(
|
||||||
|
|||||||
+3
@@ -84,6 +84,7 @@ class PublicChatPanel(
|
|||||||
ProfileCache.enrichPublicMessageForDisplay(
|
ProfileCache.enrichPublicMessageForDisplay(
|
||||||
mergeMessageUiFields(fresh, message).copy(
|
mergeMessageUiFields(fresh, message).copy(
|
||||||
username = fresh.username,
|
username = fresh.username,
|
||||||
|
displayName = fresh.displayName,
|
||||||
profile_picture = fresh.profile_picture,
|
profile_picture = fresh.profile_picture,
|
||||||
verified = fresh.verified,
|
verified = fresh.verified,
|
||||||
verificationStatus = fresh.verificationStatus,
|
verificationStatus = fresh.verificationStatus,
|
||||||
@@ -179,6 +180,8 @@ class PublicChatPanel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun hydrateFromLocalCache() {
|
suspend fun hydrateFromLocalCache() {
|
||||||
|
// Sender display names live in ProfileCache (message rows only store userId).
|
||||||
|
runCatching { ProfileCache.hydrateFromDisk() }
|
||||||
hydrateMessagesFromLocalCache()
|
hydrateMessagesFromLocalCache()
|
||||||
runCatching { PublicChatProfileCache.hydrateFromDisk() }
|
runCatching { PublicChatProfileCache.hydrateFromDisk() }
|
||||||
PublicChatProfileCache.profile?.let { applyPublicChatProfile(it) }
|
PublicChatProfileCache.profile?.let { applyPublicChatProfile(it) }
|
||||||
|
|||||||
@@ -129,7 +129,17 @@ internal fun mergeMessageUiFields(db: Message, panel: Message?): Message {
|
|||||||
?: db.pendingFileAspectRatio?.takeIf { it > 0f }
|
?: db.pendingFileAspectRatio?.takeIf { it > 0f }
|
||||||
?: panel.fileDimensions?.firstOrNull()?.let { (w, h) -> aspectRatioFromDimensionPair(w, h) }
|
?: panel.fileDimensions?.firstOrNull()?.let { (w, h) -> aspectRatioFromDimensionPair(w, h) }
|
||||||
?: db.fileDimensions?.firstOrNull()?.let { (w, h) -> aspectRatioFromDimensionPair(w, h) }
|
?: db.fileDimensions?.firstOrNull()?.let { (w, h) -> aspectRatioFromDimensionPair(w, h) }
|
||||||
|
// DB rows only store userId; sender identity is reconstructed from ProfileCache and can
|
||||||
|
// briefly be blank. Keep non-blank panel fields (e.g. from a network payload) so text
|
||||||
|
// avatars / names are not wiped on every SQLDelight emission.
|
||||||
val merged = db.copy(
|
val merged = db.copy(
|
||||||
|
username = db.username.trim().ifBlank { panel.username.trim() },
|
||||||
|
displayName = db.displayName?.trim()?.takeIf { it.isNotEmpty() }
|
||||||
|
?: panel.displayName?.trim()?.takeIf { it.isNotEmpty() },
|
||||||
|
profile_picture = db.profile_picture?.takeIf { it.isNotBlank() }
|
||||||
|
?: panel.profile_picture?.takeIf { it.isNotBlank() },
|
||||||
|
verified = db.verified ?: panel.verified,
|
||||||
|
verificationStatus = db.verificationStatus ?: panel.verificationStatus,
|
||||||
pendingFileUri = when {
|
pendingFileUri = when {
|
||||||
confirmed -> localPreview
|
confirmed -> localPreview
|
||||||
else -> panel.pendingFileUri ?: db.pendingFileUri
|
else -> panel.pendingFileUri ?: db.pendingFileUri
|
||||||
|
|||||||
Reference in New Issue
Block a user