feat: add call buttons to group chat header

Adds voice and video call buttons to the group DM top bar, matching
the existing 1-on-1 DM header.  When tapped in a group chat, the
buttons invoke initiateGroupCall() which sends gift-wrapped offers
to every group member under a single call-id.

https://claude.ai/code/session_01WafqMofFQfWCQA5TcLvHRb
This commit is contained in:
Claude
2026-04-02 22:30:50 +00:00
parent f25c1df0e2
commit 5b7e47d87e
2 changed files with 41 additions and 4 deletions
@@ -49,18 +49,27 @@ fun ChatroomScreen(
nav: INav,
) {
val context = LocalContext.current
val isGroupChat = roomId.users.size > 1
val startVoiceCall =
rememberCallWithPermission(context) {
val peerPubKey = roomId.users.firstOrNull() ?: return@rememberCallWithPermission
ActiveCallHolder.set(accountViewModel.callManager, accountViewModel.callController, accountViewModel)
accountViewModel.callController?.initiateCall(peerPubKey, CallType.VOICE)
if (isGroupChat) {
accountViewModel.callController?.initiateGroupCall(roomId.users.toSet(), CallType.VOICE)
} else {
val peerPubKey = roomId.users.firstOrNull() ?: return@rememberCallWithPermission
accountViewModel.callController?.initiateCall(peerPubKey, CallType.VOICE)
}
CallActivity.launch(context)
}
val startVideoCall =
rememberCallWithPermission(context, isVideo = true) {
val peerPubKey = roomId.users.firstOrNull() ?: return@rememberCallWithPermission
ActiveCallHolder.set(accountViewModel.callManager, accountViewModel.callController, accountViewModel)
accountViewModel.callController?.initiateCall(peerPubKey, CallType.VIDEO)
if (isGroupChat) {
accountViewModel.callController?.initiateGroupCall(roomId.users.toSet(), CallType.VIDEO)
} else {
val peerPubKey = roomId.users.firstOrNull() ?: return@rememberCallWithPermission
accountViewModel.callController?.initiateCall(peerPubKey, CallType.VIDEO)
}
CallActivity.launch(context)
}
@@ -146,6 +146,34 @@ fun RenderRoomTopBar(
)
RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp).weight(1f), FontWeight.Normal, accountViewModel)
if (onVideoCallClick != null) {
IconButton(
onClick = { onVideoCallClick(room.users.joinToString(",")) },
modifier = Modifier.size(40.dp),
) {
Icon(
imageVector = Icons.Default.Videocam,
contentDescription = stringRes(R.string.call_video),
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp),
)
}
}
if (onCallClick != null) {
IconButton(
onClick = { onCallClick(room.users.joinToString(",")) },
modifier = Modifier.size(40.dp),
) {
Icon(
imageVector = Icons.Default.Call,
contentDescription = stringRes(R.string.call_voice),
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp),
)
}
}
}
},
extendableRow = {