Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -60,6 +61,7 @@ class MainActivity : ComponentActivity() {
private val firebaseAnalytics by lazy { FirebaseAnalytics.getInstance(this) }

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
Comment thread
gpunto marked this conversation as resolved.
super.onCreate(savedInstanceState)

// Extract callId from intent if available
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ public fun User.Companion.builtInUsers(): List<User> {
image = "https://ca.slack-edge.com/T02RM6X6B-U05UD37MA1G-f062f8b7afc2-512",
),
User(
id = "liviu",
name = "Liviu",
id = "andrerego",
name = "André",
role = "user",
image = "https://ca.slack-edge.com/T02RM6X6B-U0604NCKKRA-76f99b6ba2c8-512",
image = "https://ca.slack-edge.com/T02RM6X6B-U083JCB6ZEY-2da235988b74-512",
),
User(
id = "kanat",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.getstream.video.android.ui

import android.net.Uri
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -127,7 +128,7 @@ enum class AppScreens(val route: String) {

fun routeWithArg(argValue: Any): String = when (this) {
Login -> this.route.replace("{auto_log_in}", argValue.toString())
CallLobby -> this.route.replace("{cid}", argValue.toString())
CallLobby -> this.route.replace("{cid}", Uri.encode(argValue.toString()))
else -> this.route
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.LockPerson
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
Expand All @@ -51,25 +46,27 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.getstream.video.android.BuildConfig
import io.getstream.video.android.CallActivity
import io.getstream.video.android.R
import io.getstream.video.android.compose.permission.VideoPermissionsState
import io.getstream.video.android.compose.permission.rememberCallPermissionsState
import io.getstream.video.android.compose.theme.VideoTheme
import io.getstream.video.android.compose.theme.design.StreamTokens
import io.getstream.video.android.compose.ui.components.avatar.UserAvatar
import io.getstream.video.android.compose.ui.components.base.StreamButtonStyleDefaults
import io.getstream.video.android.compose.ui.components.base.StreamIconButton
import io.getstream.video.android.compose.ui.components.base.StreamTextButton
import io.getstream.video.android.compose.ui.components.call.controls.ControlActions
import io.getstream.video.android.compose.ui.components.call.lobby.CallLobby
Expand All @@ -86,6 +83,7 @@ import io.getstream.video.android.mock.previewUsers
import io.getstream.video.android.model.User
import io.getstream.video.android.ui.common.StreamCallActivity
import kotlinx.coroutines.delay
import io.getstream.video.android.compose.R as ComposeR

@Composable
fun CallLobbyScreen(
Expand Down Expand Up @@ -181,47 +179,37 @@ private fun CallLobbyHeaderContent(
) {
Row(
modifier = Modifier
.padding(
horizontal = 16.dp,
vertical = 4.dp,
)
.padding(StreamTokens.spacingMd)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
val userValue = user.value
if (userValue != null) {
UserAvatar(
modifier = Modifier.size(32.dp),
modifier = Modifier.size(StreamTokens.size40),
userImage = userValue.image,
userName = userValue.userNameOrId,
)

Spacer(modifier = Modifier.width(4.dp))
Spacer(modifier = Modifier.width(StreamTokens.spacingXs))
}

Text(
modifier = Modifier.weight(1f),
color = Color.White,
text = userValue?.id.orEmpty(),
style = VideoTheme.typography.bodyDefault,
color = VideoTheme.colors.textPrimary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
fontSize = 16.sp,
)
IconButton(
modifier = Modifier
.padding(8.dp)
.testTag("Stream_LobbyCloseButton"),
onClick = {
onBack()
},
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = null,
tint = VideoTheme.colors.textPrimary,
)
}
StreamIconButton(
modifier = Modifier.testTag("Stream_LobbyCloseButton"),
onClick = onBack,
icon = painterResource(ComposeR.drawable.stream_design_ic_xmark),
contentDescription = null,
style = StreamButtonStyleDefaults.secondaryGhost,
)
}
}

Expand Down Expand Up @@ -294,31 +282,31 @@ private fun CallLobbyBodyPortrait(
// based on how you handle benchmarks or initial setup externally

Icon(
modifier = Modifier.size(36.dp),
imageVector = Icons.Default.Language,
modifier = Modifier.size(StreamTokens.iconSizeLg),
painter = painterResource(ComposeR.drawable.stream_design_ic_language),
tint = VideoTheme.colors.accentSuccess,
contentDescription = "",
)
Text(
modifier = Modifier.padding(16.dp),
modifier = Modifier.padding(StreamTokens.spacingMd),
text = "Set up your test call",
style = VideoTheme.typography.headingLarge,
)
val onCallAction: (CallAction) -> Unit = { action ->
when (action) {
is ToggleCamera -> onToggleCamera(action.isEnabled)
is ToggleMicrophone -> onToggleMicrophone(action.isEnabled)
is ToggleHifiAudio -> onToggleHifiAudio(action.isHifiAudioEnabled)
else -> Unit
}
}
val permissions = rememberCallPermissionsState(call = call)
val onCallAction = lobbyCallActionHandler(
permissions,
onToggleCamera,
onToggleMicrophone,
onToggleHifiAudio,
)
CallLobby(
call = call,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
.padding(StreamTokens.spacingMd),
isCameraEnabled = isCameraEnabled,
isMicrophoneEnabled = isMicrophoneEnabled,
permissions = permissions,
onCallAction = onCallAction,
lobbyControlsContent = { modifier, _ ->
ControlActions(
Expand Down Expand Up @@ -367,29 +355,29 @@ private fun CallLobbyBodyLandscape(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
val onCallAction: (CallAction) -> Unit = { action ->
when (action) {
is ToggleCamera -> onToggleCamera(action.isEnabled)
is ToggleMicrophone -> onToggleMicrophone(action.isEnabled)
is ToggleHifiAudio -> onToggleHifiAudio(action.isHifiAudioEnabled)
else -> Unit
}
}
val permissions = rememberCallPermissionsState(call = call)
val onCallAction = lobbyCallActionHandler(
permissions,
onToggleCamera,
onToggleMicrophone,
onToggleHifiAudio,
)

CallLobby(
call = call,
modifier = Modifier
.fillMaxWidth()
.padding(
start = 16.dp,
end = 16.dp,
start = StreamTokens.spacingMd,
end = StreamTokens.spacingMd,
),
isCameraEnabled = isCameraEnabled,
isMicrophoneEnabled = isMicrophoneEnabled,
permissions = permissions,
onCallAction = onCallAction,
lobbyControlsContent = { _, _ ->
lobbyControlsContent = { modifier, _ ->
Comment thread
gpunto marked this conversation as resolved.
ControlActions(
modifier = Modifier.padding(),
modifier = modifier,
call = call,
actions = buildDefaultLobbyControlActions(
call = call,
Expand Down Expand Up @@ -421,13 +409,13 @@ private fun CallLobbyBodyLandscape(
// LaunchedEffect to handle initial setup might need adjustments
// based on how you handle benchmarks or initial setup externally
Icon(
modifier = Modifier.size(36.dp),
imageVector = Icons.Default.Language,
modifier = Modifier.size(StreamTokens.iconSizeLg),
painter = painterResource(ComposeR.drawable.stream_design_ic_language),
tint = VideoTheme.colors.accentSuccess,
contentDescription = "",
)
Text(
modifier = Modifier.padding(16.dp),
modifier = Modifier.padding(StreamTokens.spacingMd),
text = "Set up your test call",
style = VideoTheme.typography.headingLarge,
)
Expand All @@ -437,6 +425,34 @@ private fun CallLobbyBodyLandscape(
}
}

/**
* Routes the lobby toggles to the view model. Turning on a device whose permission was denied asks
* for the permission again first, the same way the SDK default lobby controls do.
*/
private fun lobbyCallActionHandler(
permissions: VideoPermissionsState,
onToggleCamera: (Boolean) -> Unit,
onToggleMicrophone: (Boolean) -> Unit,
onToggleHifiAudio: (Boolean) -> Unit,
): (CallAction) -> Unit = { action ->
when (action) {
is ToggleCamera -> {
if (action.isEnabled && permissions.isCameraPermissionDenied) {
permissions.launchPermissionRequest()
}
onToggleCamera(action.isEnabled)
}
is ToggleMicrophone -> {
if (action.isEnabled && permissions.isMicrophonePermissionDenied) {
permissions.launchPermissionRequest()
}
onToggleMicrophone(action.isEnabled)
}
is ToggleHifiAudio -> onToggleHifiAudio(action.isHifiAudioEnabled)
else -> Unit
}
}

@Composable
private fun LobbyDescription(
callLobbyViewModel: CallLobbyViewModel,
Expand Down Expand Up @@ -471,7 +487,7 @@ private fun LobbyDescriptionContent(participantCounts: ParticipantCount?, onClic
)
}
Column(
modifier = Modifier.padding(16.dp),
modifier = Modifier.padding(StreamTokens.spacingMd),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Expand All @@ -483,18 +499,18 @@ private fun LobbyDescriptionContent(participantCounts: ParticipantCount?, onClic
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = Icons.Default.LockPerson,
painter = painterResource(ComposeR.drawable.stream_design_ic_lock),
tint = VideoTheme.colors.textPrimary,
contentDescription = "",
)

Text(
modifier = Modifier.padding(horizontal = 16.dp),
modifier = Modifier.padding(horizontal = StreamTokens.spacingMd),
text = text.first,
style = VideoTheme.typography.captionDefault,
)
}
Spacer(modifier = Modifier.size(16.dp))
Spacer(modifier = Modifier.size(StreamTokens.spacingMd))
StreamTextButton(
style = StreamButtonStyleDefaults.primarySolid,
modifier = Modifier
Expand Down
2 changes: 1 addition & 1 deletion demo-app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<string name="sign_out">Sign out</string>
<string name="logs">Share Logs</string>
<string name="call_settings">Call Settings</string>
<string name="join_description">Start a new call, join a meeting by \nentering the call ID or by scanning \na QR code.</string>
<string name="join_description">Start a new call, join a meeting by entering the call ID or by scanning a QR code.</string>
<string name="join_call">Join Call</string>
<string name="join_call_by_qr_code">Scan QR meeting code</string>
<string name="join_call_description">You are about to join a call. %d more people are in the call (%d anonymous).</string>
Expand Down
Loading
Loading