Skip to content

Commit b14dc9e

Browse files
Prevent duplicate GetOrCreateChannel calls when paginating messages (#6016)
* Prevent calling fillTheGap when paginating messages. * Prevent calling loadOlderMessages if already loading. * Update CHANGELOG.md. * Update channel loading states if GetOrCreateChannel fails. --------- Co-authored-by: Aleksandar Apostolov <[email protected]>
1 parent 4c0f314 commit b14dc9e

File tree

5 files changed

+40
-18
lines changed

5 files changed

+40
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
## stream-chat-android-state
4040
### 🐞 Fixed
41+
- Prevent duplicate `GetOrCreateChannel` calls when paginating messages. [#6016](https://github.com/GetStream/stream-chat-android/pull/6016)
4142

4243
### ⬆️ Improved
4344

stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/channel/internal/ChannelLogic.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,12 @@ internal class ChannelLogic(
237237
val offlineChannel = runChannelQueryOffline(request)
238238

239239
val onlineResult = runChannelQueryOnline(request)
240-
.onSuccess { fillTheGap(request.messagesLimit(), loadedMessages, it.messages) }
240+
.onSuccess {
241+
// Fill the missing messages gap only if loading around ID
242+
if (request.isFilteringAroundIdMessages()) {
243+
fillTheGap(request.messagesLimit(), loadedMessages, it.messages)
244+
}
245+
}
241246

242247
return when {
243248
onlineResult is Result.Success -> onlineResult
@@ -480,15 +485,6 @@ internal class ChannelLogic(
480485
channelStateLogic.removeMessagesBefore(date, systemMessage)
481486
}
482487

483-
/**
484-
* Hides the messages created before the given date.
485-
*
486-
* @param date The date used for generating result.
487-
*/
488-
internal fun hideMessagesBefore(date: Date) {
489-
channelStateLogic.hideMessagesBefore(date)
490-
}
491-
492488
private fun upsertReminder(messageId: String, reminder: MessageReminder) {
493489
val message = reminder.message ?: mutableState.getMessageById(messageId) ?: return
494490
upsertEventMessage(message.copy(reminder = reminder.toMessageReminderInfo()))

stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/channel/internal/ChannelStateLogic.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,8 @@ internal class ChannelStateLogic(
784784
}
785785
mutableState.recoveryNeeded = true
786786
}
787+
mutableState.setLoadingOlderMessages(false)
788+
mutableState.setLoadingNewerMessages(false)
787789
}
788790

789791
/**

stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/channel/internal/ChannelStateLogicTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import io.getstream.chat.android.state.model.querychannels.pagination.internal.Q
5151
import io.getstream.chat.android.state.plugin.state.channel.internal.ChannelMutableState
5252
import io.getstream.chat.android.state.plugin.state.global.internal.MutableGlobalState
5353
import io.getstream.chat.android.test.TestCoroutineExtension
54+
import io.getstream.result.Error
5455
import kotlinx.coroutines.flow.MutableStateFlow
5556
import org.amshove.kluent.`should be equal to`
5657
import org.amshove.kluent.`should not be equal to`
@@ -65,6 +66,7 @@ import org.mockito.kotlin.doAnswer
6566
import org.mockito.kotlin.doReturn
6667
import org.mockito.kotlin.eq
6768
import org.mockito.kotlin.mock
69+
import org.mockito.kotlin.never
6870
import org.mockito.kotlin.spy
6971
import org.mockito.kotlin.times
7072
import org.mockito.kotlin.verify
@@ -789,6 +791,28 @@ internal class ChannelStateLogicTest {
789791
)
790792
}
791793

794+
@Test
795+
fun `When propagateQueryError is called for recoverable error, Then channel is marked for recovery and loading is reset`() {
796+
// when
797+
channelStateLogic.propagateQueryError(Error.GenericError("Test error"))
798+
799+
// then
800+
verify(mutableState).recoveryNeeded = true
801+
verify(mutableState).setLoadingOlderMessages(false)
802+
verify(mutableState).setLoadingNewerMessages(false)
803+
}
804+
805+
@Test
806+
fun `When propagateQueryError is called for unrecoverable error, Then channel is not marked for recovery and loading is reset`() {
807+
// when
808+
channelStateLogic.propagateQueryError(Error.NetworkError("Test network error", 500))
809+
810+
// then
811+
verify(mutableState, never()).recoveryNeeded = any<Boolean>()
812+
verify(mutableState).setLoadingOlderMessages(false)
813+
verify(mutableState).setLoadingNewerMessages(false)
814+
}
815+
792816
companion object {
793817

794818
@JvmField

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListController.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,15 +1210,14 @@ public class MessageListController(
12101210
logger.d { "[loadOlderMessages] messageLimit: $messageLimit" }
12111211
if (clientState.isOffline) return
12121212

1213-
_mode.value.run {
1214-
when (this) {
1215-
is MessageMode.Normal -> {
1216-
if (channelState.value?.endOfOlderMessages?.value == true) return
1217-
chatClient.loadOlderMessages(cid, messageLimit).enqueue()
1218-
}
1219-
1220-
is MessageMode.MessageThread -> threadLoadMore(this)
1213+
when (val mode = _mode.value) {
1214+
is MessageMode.Normal -> {
1215+
val endOfOlderMessages = channelState.value?.endOfOlderMessages?.value == true
1216+
val loadingOlderMessages = channelState.value?.loadingOlderMessages?.value == true
1217+
if (endOfOlderMessages || loadingOlderMessages) return
1218+
chatClient.loadOlderMessages(cid, messageLimit).enqueue()
12211219
}
1220+
is MessageMode.MessageThread -> threadLoadMore(mode)
12221221
}
12231222
}
12241223

0 commit comments

Comments
 (0)