From 456830a4fadb7709345e95c5a69b34e6bf4ef420 Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 12 Nov 2023 21:08:56 +0100 Subject: [PATCH] feat: reconnect mechanism that doesn't limit retry count Signed-off-by: Infi --- .../components/chat/DisconnectedNotice.kt | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/chat/revolt/components/chat/DisconnectedNotice.kt b/app/src/main/java/chat/revolt/components/chat/DisconnectedNotice.kt index cab70a1b..d99b8813 100644 --- a/app/src/main/java/chat/revolt/components/chat/DisconnectedNotice.kt +++ b/app/src/main/java/chat/revolt/components/chat/DisconnectedNotice.kt @@ -1,5 +1,6 @@ package chat.revolt.components.chat +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Row @@ -16,6 +17,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -28,6 +31,10 @@ import chat.revolt.R import chat.revolt.api.realtime.DisconnectionState import chat.revolt.api.settings.GlobalState import chat.revolt.ui.theme.Theme +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.launch private val NON_MATERIAL_COLOURS = mapOf( DisconnectionState.Disconnected to (Color(0xff4E0C0C) to Color(0xffff1744)), @@ -76,23 +83,28 @@ private fun DisconnectedNoticeBase( @Composable fun DisconnectedNotice(state: DisconnectionState, onReconnect: () -> Unit) { - val retries = remember { mutableStateOf(0) } + // This is a coroutine-based retry mechanism that will retry every 10 seconds + // until the connection is re-established. If the connection is re-established + // we don't need to keep retrying. + val job = remember { mutableStateOf(null) } + val scope = rememberCoroutineScope() LaunchedEffect(state) { - when (state) { - DisconnectionState.Disconnected -> { - if (retries.value < 3) { - onReconnect() - retries.value++ + snapshotFlow { state } + .distinctUntilChanged() + .collect { state -> + if (state == DisconnectionState.Disconnected) { + job.value = scope.launch { + while (true) { + Log.d("DisconnectedNotice", "Trying to reconnect.") + onReconnect() + delay(10_000) + } + } + } else { + job.value?.cancel() } } - - DisconnectionState.Connected -> { - retries.value = 0 - } - - else -> Unit - } } val materialColours = mapOf(