feat: reconnect mechanism that doesn't limit retry count

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-11-12 21:08:56 +01:00
parent 182566dcc0
commit 456830a4fa
1 changed files with 25 additions and 13 deletions

View File

@ -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<Job?>(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(