fix: prevent infinite chat loading (#822)

This commit is contained in:
Diego Beraldin 2024-05-10 19:29:33 +02:00 committed by GitHub
parent 40771de15f
commit 17c821c9ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 24 deletions

View File

@ -232,7 +232,6 @@ class InboxChatScreen(
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
reverseLayout = true,
state = lazyListState,
) {
@ -240,7 +239,7 @@ class InboxChatScreen(
Spacer(modifier = Modifier.height(Spacing.s))
}
if (uiState.messages.isEmpty() && uiState.initial) {
items(10) {
items(5) {
MessageCardPlaceholder()
}
}

View File

@ -11,9 +11,12 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepo
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PrivateMessageRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class InboxChatViewModel(
private val otherUserId: Long,
@ -29,7 +32,6 @@ class InboxChatViewModel(
initialState = InboxChatMviModel.UiState(),
) {
private var currentPage: Int = 1
init {
@ -48,11 +50,11 @@ class InboxChatViewModel(
notificationCenter.subscribe(NotificationCenterEvent.Logout::class).onEach {
handleLogout()
}.launchIn(this)
launch {
withContext(Dispatchers.IO) {
val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0
updateState { it.copy(currentUserId = currentUserId) }
}
launch {
val user = userRepository.get(
id = otherUserId,
auth = auth,
@ -115,7 +117,7 @@ class InboxChatViewModel(
loadNextPage()
}
private suspend fun loadNextPage() {
private suspend fun loadNextPage(tryCount: Int = 0) {
val currentState = uiState.value
if (!currentState.canFetchMore || currentState.loading) {
updateState { it.copy(refreshing = false) }
@ -142,6 +144,7 @@ class InboxChatViewModel(
val itemsToAdd = itemList.orEmpty().filter {
it.creator?.id == otherUserId || it.recipient?.id == otherUserId
}
val shouldTryNextPage = itemsToAdd.isEmpty() && tryCount < 10
updateState {
val newItems = if (refreshing) {
itemsToAdd
@ -153,11 +156,11 @@ class InboxChatViewModel(
loading = false,
canFetchMore = itemList?.isEmpty() != true,
refreshing = false,
initial = itemsToAdd.isEmpty(),
initial = !shouldTryNextPage,
)
}
if (currentState.initial && itemsToAdd.isEmpty()) {
loadNextPage()
if (currentState.initial && shouldTryNextPage) {
loadNextPage(tryCount + 1)
}
}
@ -178,11 +181,11 @@ class InboxChatViewModel(
private fun handleMessageUpdate(newMessage: PrivateMessageModel) {
updateState {
it.copy(
messages = it.messages.map { m ->
if (m.id == newMessage.id) {
messages = it.messages.map { msg ->
if (msg.id == newMessage.id) {
newMessage
} else {
m
msg
}
}
)
@ -272,7 +275,7 @@ class InboxChatViewModel(
auth = auth,
)
updateState {
it.copy(messages = it.messages.filter { m -> m.id != message.id })
it.copy(messages = it.messages.filter { msg -> msg.id != message.id })
}
}
}

View File

@ -50,6 +50,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
@Composable
internal fun MessageCard(
modifier: Modifier = Modifier,
isMyMessage: Boolean = false,
content: String = "",
date: String = "",
@ -72,15 +73,22 @@ internal fun MessageCard(
var optionsExpanded by remember { mutableStateOf(false) }
var optionsOffset by remember { mutableStateOf(Offset.Zero) }
Box {
Box(
modifier = modifier.padding(
horizontal = Spacing.xs,
vertical = Spacing.xs,
)
) {
Canvas(
modifier = Modifier.size(mediumDistance).then(
if (isMyMessage) {
Modifier.align(Alignment.TopEnd)
} else {
Modifier.align(Alignment.TopStart)
}
)
modifier = Modifier
.size(mediumDistance)
.then(
if (isMyMessage) {
Modifier.align(Alignment.TopEnd)
} else {
Modifier.align(Alignment.TopStart)
}
)
) {
if (isMyMessage) {
val path = Path().apply {

View File

@ -3,12 +3,14 @@ package com.github.diegoberaldin.raccoonforlemmy.unit.chat.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.shimmerEffect
@Composable
@ -17,6 +19,7 @@ internal fun MessageCardPlaceholder() {
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.padding(horizontal = Spacing.xs, vertical = Spacing.xs)
.clip(RoundedCornerShape(CornerSize.s))
.shimmerEffect()
)

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class InboxMessagesViewModel(
private val identityRepository: IdentityRepository,
@ -57,7 +58,7 @@ class InboxMessagesViewModel(
handleLogout()
}.launchIn(this)
launch(Dispatchers.IO) {
withContext(Dispatchers.IO) {
val auth = identityRepository.authToken.value.orEmpty()
val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0
updateState { it.copy(currentUserId = currentUserId) }
@ -65,10 +66,11 @@ class InboxMessagesViewModel(
if (uiState.value.initial) {
val value = coordinator.unreadOnly.value
changeUnreadOnly(value)
refresh(initial = true)
}
updateUnreadItems()
}
updateUnreadItems()
}
}