From 2bb860e97f8475c25fe5a8be00bd396f38aeeaef Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Apr 2026 21:13:26 +0000 Subject: [PATCH] fix: show video UI when upgrading voice call to video The call screen used state.callType (set at call initiation) to decide whether to render video. When a voice call was upgraded to video via the toggle button, callType remained VOICE so the video grid and local preview were never shown despite the track being created and sent. Replace the static isVideoCall check with hasActiveVideo that also considers isVideoEnabled and the presence of remote video tracks. Fixes both the full-screen group call UI and the PIP overlay. https://claude.ai/code/session_015TvWJoAEsfc2ohiRoT9sTr --- .../amethyst/ui/call/CallScreen.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallScreen.kt index 20eab7fe4..563c10f45 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallScreen.kt @@ -412,7 +412,10 @@ private fun ConnectedCallUI( val isAudioMuted by (callController?.isAudioMuted ?: defaultFalse).collectAsState() val isVideoEnabled by (callController?.isVideoEnabled ?: defaultTrue).collectAsState() val currentAudioRoute by (callController?.audioRoute ?: defaultRoute).collectAsState() - val isVideoCall = state.callType == com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType.VIDEO + val hasActiveVideo = + state.callType == com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType.VIDEO || + isVideoEnabled || + remoteVideoTracks.isNotEmpty() var showAddParticipant by remember { mutableStateOf(false) } @@ -439,7 +442,7 @@ private fun ConnectedCallUI( state.allPeerPubKeys - accountViewModel.account.signer.pubKey } - if (isVideoCall) { + if (hasActiveVideo) { // Video call: always show the peer grid with video for active peers, avatar for inactive PeerVideoGrid( peerPubKeys = otherMembers, @@ -802,7 +805,11 @@ private fun PipConnectedCallUI( val activePeerVideos by (callController?.activePeerVideos ?: emptySetFlow).collectAsState() val defaultFalse = remember { kotlinx.coroutines.flow.MutableStateFlow(false) } val isRemoteVideoActive by (callController?.isRemoteVideoActive ?: defaultFalse).collectAsState() - val isVideoCall = state.callType == com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType.VIDEO + val isVideoEnabled by (callController?.isVideoEnabled ?: defaultFalse).collectAsState() + val hasActiveVideo = + state.callType == com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType.VIDEO || + isVideoEnabled || + remoteVideoTracks.isNotEmpty() val otherMembers = remember(state.allPeerPubKeys) { @@ -815,8 +822,8 @@ private fun PipConnectedCallUI( .fillMaxSize() .background(Color.Black), ) { - if (isVideoCall) { - // Video call: show first active peer's video or avatar + if (hasActiveVideo) { + // Video active: show first active peer's video or avatar val firstActivePeer = otherMembers.firstOrNull { it in activePeerVideos } val activeTrack = firstActivePeer?.let { remoteVideoTracks[it] } if (activeTrack != null) {