fix: add event dedup, back button handling, and wake lock for calls
- Deduplicate signaling events via processedEventIds set in CallManager to prevent duplicate processing from multiple relays - BackHandler on CallScreen calls hangup() before navigating back - KeepScreenOn composable adds FLAG_KEEP_SCREEN_ON during calls and clears it on dispose https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.call
|
||||
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -40,6 +42,7 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -50,6 +53,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -73,7 +77,13 @@ fun CallScreen(
|
||||
) {
|
||||
val callState by callManager.state.collectAsState()
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = androidx.compose.ui.platform.LocalContext.current
|
||||
val context = LocalContext.current
|
||||
|
||||
BackHandler(enabled = callState !is CallState.Idle && callState !is CallState.Ended) {
|
||||
scope.launch { callManager.hangup() }
|
||||
}
|
||||
|
||||
KeepScreenOn()
|
||||
|
||||
when (val state = callState) {
|
||||
is CallState.Idle -> {
|
||||
@@ -363,3 +373,15 @@ private fun formatDuration(seconds: Long): String {
|
||||
val secs = seconds % 60
|
||||
return "%02d:%02d".format(mins, secs)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun KeepScreenOn() {
|
||||
val context = LocalContext.current
|
||||
DisposableEffect(Unit) {
|
||||
val window = (context as? android.app.Activity)?.window
|
||||
window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
onDispose {
|
||||
window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ class CallManager(
|
||||
|
||||
private var timeoutJob: Job? = null
|
||||
private var resetJob: Job? = null
|
||||
private val processedEventIds = mutableSetOf<String>()
|
||||
|
||||
companion object {
|
||||
const val CALL_TIMEOUT_MS = 60_000L // 60 seconds ringing timeout
|
||||
@@ -198,6 +199,7 @@ class CallManager(
|
||||
|
||||
fun onSignalingEvent(event: Event) {
|
||||
if (isEventTooOld(event)) return
|
||||
if (!processedEventIds.add(event.id)) return
|
||||
|
||||
when (event) {
|
||||
is CallOfferEvent -> onIncomingCallEvent(event)
|
||||
@@ -234,6 +236,7 @@ class CallManager(
|
||||
cancelTimeout()
|
||||
resetJob?.cancel()
|
||||
resetJob = null
|
||||
processedEventIds.clear()
|
||||
}
|
||||
|
||||
private fun transitionToEnded(
|
||||
|
||||
Reference in New Issue
Block a user