diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/CallScreen.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/CallScreen.kt index 11639bfee9f..170bda45079 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/CallScreen.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/CallScreen.kt @@ -400,7 +400,7 @@ fun CallScreen( isShowingSettingMenu = !isShowingSettingMenu }, ) - Spacer(modifier = Modifier.size(StreamTokens.spacingMd)) + Spacer(modifier = Modifier.size(StreamTokens.spacingXs)) if (isTablet()) { ScreenShareToggleAction( active = isScreenSharing, @@ -421,7 +421,7 @@ fun CallScreen( }, ) Spacer( - modifier = Modifier.size(StreamTokens.spacingMd), + modifier = Modifier.size(StreamTokens.spacingXs), ) } ToggleCameraAction( @@ -432,7 +432,7 @@ fun CallScreen( isCameraEnabled = isCameraEnabled, onCallAction = { call.camera.setEnabled(it.isEnabled) }, ) - Spacer(modifier = Modifier.size(StreamTokens.spacingMd)) + Spacer(modifier = Modifier.size(StreamTokens.spacingXs)) ToggleMicrophoneAction( modifier = Modifier .testTag( @@ -445,7 +445,7 @@ fun CallScreen( ) }, ) - Spacer(modifier = Modifier.size(StreamTokens.spacingMd)) + Spacer(modifier = Modifier.size(StreamTokens.spacingXs)) } Row { StreamBadgeBox( @@ -459,7 +459,7 @@ fun CallScreen( showParticipants = !showParticipants } } - Spacer(modifier = Modifier.size(StreamTokens.spacingMd)) + Spacer(modifier = Modifier.size(StreamTokens.spacingXs)) ChatDialogAction( modifier = Modifier.testTag("Stream_ChatButton"), messageCount = unreadCount, diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/ReactionsMenu.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/ReactionsMenu.kt index de2ae35d2e0..5ab05481227 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/ReactionsMenu.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/call/ReactionsMenu.kt @@ -24,8 +24,8 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.requiredHeight -import androidx.compose.foundation.layout.requiredWidth +import androidx.compose.foundation.layout.requiredSize +import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier @@ -33,6 +33,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import io.getstream.android.core.ui.design.StreamTokens import io.getstream.video.android.compose.theme.VideoTheme +import io.getstream.video.android.compose.ui.components.base.StreamButton import io.getstream.video.android.compose.ui.components.base.StreamButtonSize import io.getstream.video.android.compose.ui.components.base.StreamButtonStyleDefaults import io.getstream.video.android.compose.ui.components.base.StreamTextButton @@ -120,25 +121,26 @@ private fun ReactionItem( onEmojiSelected: (emoji: String) -> Unit, ) { val mappedEmoji = reactionMapper.map(reaction.emojiCode) - val text = if (showText) { - "$mappedEmoji ${reaction.displayText}" - } else { - mappedEmoji - } - val modifier = if (showText) { - Modifier.fillMaxWidth() + val onClick = { onEmojiSelected(reaction.emojiCode) } + if (showText) { + StreamTextButton( + modifier = Modifier.fillMaxWidth(), + style = StreamButtonStyleDefaults.secondaryOutline, + size = StreamButtonSize.Small, + text = "$mappedEmoji ${reaction.displayText}", + onClick = onClick, + ) } else { - Modifier - .requiredWidth(StreamTokens.size48) - .requiredHeight(StreamTokens.size48) + // A plain StreamButton: the label padding of StreamTextButton leaves no room for the emoji. + StreamButton( + modifier = Modifier.requiredSize(StreamTokens.size48), + style = StreamButtonStyleDefaults.secondaryOutline, + size = StreamButtonSize.Small, + onClick = onClick, + ) { + Text(text = mappedEmoji) + } } - StreamTextButton( - modifier = modifier, - style = StreamButtonStyleDefaults.secondaryOutline, - size = StreamButtonSize.Small, - text = text, - onClick = { onEmojiSelected(reaction.emojiCode) }, - ) } private fun sendReaction(scope: CoroutineScope, call: Call, emoji: String, onDismiss: () -> Unit) { diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/base/DynamicMenu.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/base/DynamicMenu.kt index 38838c53c61..f162453f7ac 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/base/DynamicMenu.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/base/DynamicMenu.kt @@ -18,15 +18,19 @@ package io.getstream.video.android.ui.menu.base import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Icon import androidx.compose.material.LinearProgressIndicator +import androidx.compose.material.LocalContentColor import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -40,12 +44,13 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import io.getstream.android.core.ui.design.StreamTokens import io.getstream.video.android.compose.theme.VideoTheme +import io.getstream.video.android.compose.ui.components.base.StreamButton 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.ui.closedcaptions.ClosedCaptionUiState import io.getstream.video.android.ui.menu.AudioUsageVoiceCommunicationUiState import io.getstream.video.android.ui.menu.TranscriptionAvailableUiState @@ -237,7 +242,7 @@ private fun LazyListScope.menuItems( items(items.size) { index -> val item = items[index] val highlight = item.highlight - StreamTextButton( + StreamButton( modifier = Modifier.fillMaxWidth(), onClick = { val actionItem = item as? ActionMenuItem @@ -247,10 +252,29 @@ private fun LazyListScope.menuItems( onNewSubmenu(it) } }, - text = item.title, - leadingIcon = item.icon.painter(), - style = if (highlight) StreamButtonStyleDefaults.primaryGhost else StreamButtonStyleDefaults.secondaryGhost, - ) + style = StreamButtonStyleDefaults.secondaryGhost, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = StreamTokens.spacingMd), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingSm), + ) { + Icon( + painter = item.icon.painter(), + contentDescription = null, + modifier = Modifier.size(StreamTokens.iconSizeMd), + tint = if (highlight) VideoTheme.colors.accentPrimary else LocalContentColor.current, + ) + Text( + text = item.title, + style = VideoTheme.typography.bodyDefault, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } } } diff --git a/stream-video-android-ui-compose/src/debug/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBarPreview.kt b/stream-video-android-ui-compose/src/debug/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBarPreview.kt index 68e9660a2cd..0130ae9a730 100644 --- a/stream-video-android-ui-compose/src/debug/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBarPreview.kt +++ b/stream-video-android-ui-compose/src/debug/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBarPreview.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import io.getstream.video.android.compose.theme.VideoTheme +import io.getstream.video.android.compose.ui.components.call.controls.actions.FlipCameraAction import io.getstream.video.android.mock.StreamPreviewDataUtils import io.getstream.video.android.mock.previewCall @@ -36,3 +37,46 @@ private fun CallAppBarRootPreview() { internal fun CallAppBarPreview() { CallAppBar(call = previewCall) } + +@Preview +@Composable +private fun CallAppBarUnevenSlotsRootPreview() { + StreamPreviewDataUtils.initializeStreamVideo(LocalContext.current) + VideoTheme { + CallAppBarUnevenSlotsPreview() + } +} + +@Composable +internal fun CallAppBarUnevenSlotsPreview() { + CallAppBar( + call = previewCall, + leadingContent = { + DefaultCallAppBarLeadingContent(onBackButtonClicked = {}) + FlipCameraAction(onCallAction = {}) + }, + ) +} + +@Preview +@Composable +private fun CallAppBarLongTitleRootPreview() { + StreamPreviewDataUtils.initializeStreamVideo(LocalContext.current) + VideoTheme { + CallAppBarLongTitlePreview() + } +} + +@Composable +internal fun CallAppBarLongTitlePreview() { + CallAppBar( + call = previewCall, + centerContent = { + CalLCenterContent( + text = "Weekly design review with the whole video team", + isRecording = false, + isReconnecting = false, + ) + }, + ) +} diff --git a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/Avatar.kt b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/Avatar.kt index 9813fafe571..9d4154d55e8 100644 --- a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/Avatar.kt +++ b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/Avatar.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.key import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -41,6 +42,7 @@ import com.skydoves.landscapist.coil.CoilImage import com.skydoves.landscapist.components.rememberImageComponent import com.skydoves.landscapist.placeholder.placeholder.PlaceholderPlugin import io.getstream.android.core.ui.design.StreamTokens +import io.getstream.video.android.compose.pip.rememberIsInPipMode import io.getstream.video.android.compose.theme.VideoTheme /** @@ -97,6 +99,8 @@ internal fun Avatar( modifier } + // The fade-in never finishes drawing in a Picture-in-Picture window and leaves the avatar empty. + val isInPictureInPicture = rememberIsInPipMode() CoilImage( modifier = clickableModifier.avatarBorder(shape).clip(shape), imageModel = { imageUrl }, @@ -106,10 +110,15 @@ internal fun Avatar( requestSize = imageRequestSize, ), previewPlaceholder = painterResource(id = previewModePlaceholder), - component = rememberImageComponent { - +CrossfadePlugin() - loadingPlaceholder?.let { - +PlaceholderPlugin.Loading(painterResource(id = it)) + // rememberImageComponent keeps its first instance, so the key rebuilds it when the mode changes. + component = key(isInPictureInPicture) { + rememberImageComponent { + if (!isInPictureInPicture) { + +CrossfadePlugin() + } + loadingPlaceholder?.let { + +PlaceholderPlugin.Loading(painterResource(id = it)) + } } }, failure = { diff --git a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/UserAvatarBackground.kt b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/UserAvatarBackground.kt index 57d9b0fa02a..b1c8b198ae3 100644 --- a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/UserAvatarBackground.kt +++ b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/avatar/UserAvatarBackground.kt @@ -18,6 +18,7 @@ package io.getstream.video.android.compose.ui.components.avatar import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape @@ -39,7 +40,8 @@ import io.getstream.video.android.model.User * @param userImage The URL of the image to be displayed. Usually [User.image]. * @param userName The name to be used for the initials fallback. Usually [User.name]. * @param shape The shape of the avatar. `CircleShape` by default. - * @param avatarSize The size of the avatar. + * @param avatarSize The size of the avatar. In a container smaller than twice this size, the avatar + * shrinks to half of the container's shorter side. * @param imageScale The scale rule used for the image. `Crop` by default. * @param imageDescription The image content description for accessibility. `Null` by default. * @param imageRequestSize The image size to be requested. Original size by default. @@ -63,10 +65,10 @@ public fun UserAvatarBackground( @DrawableRes previewModePlaceholder: Int = LocalAvatarPreviewProvider.getLocalAvatarPreviewPlaceholder(), textStyle: TextStyle? = null, ) { - Box(modifier = modifier.fillMaxSize()) { + BoxWithConstraints(modifier = modifier.fillMaxSize()) { Box( modifier = Modifier - .size(avatarSize) + .size(minOf(avatarSize, minOf(maxWidth, maxHeight) / 2)) .align(Alignment.Center), ) { UserAvatar( diff --git a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBar.kt b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBar.kt index 38716284e2d..c65e5dd97a4 100644 --- a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBar.kt +++ b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/CallAppBar.kt @@ -18,7 +18,6 @@ package io.getstream.video.android.compose.ui.components.call import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope @@ -35,6 +34,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -54,12 +54,14 @@ import io.getstream.video.android.core.Call import io.getstream.video.android.core.call.state.CallAction import io.getstream.video.android.core.recording.RecordingType import io.getstream.video.android.ui.common.R +import kotlin.math.max /** * Represents the default AppBar that's shown in calls. Exposes handlers for the two default slot * component implementations (leading and trailing). * - * Exposes slots required to customize the look and feel. + * Exposes slots required to customize the look and feel. The leading and trailing content keep + * their size, and the center content is centered to the bar in the space left between them. * * @param call The call that contains all the participants state and tracks. * @param modifier Modifier for styling. @@ -106,16 +108,39 @@ public fun CallAppBar( } }, ) { - Row( + Layout( + contents = listOf( + { Row(verticalAlignment = CenterVertically) { leadingContent?.invoke(this) } }, + { Row(verticalAlignment = CenterVertically) { centerContent?.invoke(this) } }, + { Row(verticalAlignment = CenterVertically) { trailingContent?.invoke(this) } }, + ), modifier = modifier .fillMaxWidth() .height(StreamTokens.size48), - verticalAlignment = CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - leadingContent?.invoke(this) - centerContent?.invoke(this) - trailingContent?.invoke(this) + ) { (leading, center, trailing), constraints -> + val width = constraints.maxWidth + val height = constraints.maxHeight + val slotConstraints = constraints.copy(minWidth = 0, minHeight = 0) + val leadingPlaceable = leading.single().measure(slotConstraints) + val trailingPlaceable = trailing.single().measure( + slotConstraints.copy(maxWidth = width - leadingPlaceable.width), + ) + // The side slots keep their size, and the center gets the space that keeps it centered to the bar. + val sideWidth = max(leadingPlaceable.width, trailingPlaceable.width) + val centerPlaceable = center.single().measure( + slotConstraints.copy(maxWidth = (width - 2 * sideWidth).coerceAtLeast(0)), + ) + layout(width, height) { + leadingPlaceable.placeRelative(0, (height - leadingPlaceable.height) / 2) + centerPlaceable.placeRelative( + (width - centerPlaceable.width) / 2, + (height - centerPlaceable.height) / 2, + ) + trailingPlaceable.placeRelative( + width - trailingPlaceable.width, + (height - trailingPlaceable.height) / 2, + ) + } } } diff --git a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/pinning/ParticipantActions.kt b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/pinning/ParticipantActions.kt index 3db2d5d7c42..e2d703afbbc 100644 --- a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/pinning/ParticipantActions.kt +++ b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/pinning/ParticipantActions.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.positionInParent +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.IntOffset @@ -46,6 +47,7 @@ import androidx.lifecycle.lifecycleScope import io.getstream.android.core.ui.design.StreamTokens import io.getstream.android.video.generated.models.OwnCapability import io.getstream.video.android.compose.R +import io.getstream.video.android.compose.pip.rememberIsInPipMode import io.getstream.video.android.compose.theme.VideoTheme import io.getstream.video.android.compose.ui.components.base.StreamListItem import io.getstream.video.android.compose.ui.components.indicator.GenericIndicator @@ -163,10 +165,10 @@ internal fun BoxScope.ParticipantActionsWithoutState( ) { val buttonPosition = remember { mutableStateOf(Offset.Zero) } val buttonSize = remember { mutableStateOf(IntSize.Zero) } - if (actions.any { - it.condition.invoke(call, participant) - } - ) { + val menuGap = with(LocalDensity.current) { StreamTokens.spacingXs.roundToPx() } + // A Picture-in-Picture window does not pass touches to the app, so the button could not be used. + val isInPictureInPicture = rememberIsInPipMode() + if (!isInPictureInPicture && actions.any { it.condition.invoke(call, participant) }) { GenericIndicator( backgroundColor = VideoTheme.colors.backgroundCoreApp, shape = CircleShape, @@ -188,7 +190,7 @@ internal fun BoxScope.ParticipantActionsWithoutState( ParticipantActionsDialog( offset = IntOffset( x = buttonPosition.value.x.toInt(), - y = (buttonPosition.value.y + buttonSize.value.height).toInt(), + y = (buttonPosition.value.y + buttonSize.value.height).toInt() + menuGap, ), call = call, participant = participant, diff --git a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/renderer/ParticipantVideo.kt b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/renderer/ParticipantVideo.kt index 681f9c2e199..c55f6108713 100644 --- a/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/renderer/ParticipantVideo.kt +++ b/stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/renderer/ParticipantVideo.kt @@ -55,6 +55,7 @@ import androidx.compose.ui.Alignment.Companion.Center import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.testTag @@ -64,6 +65,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle import io.getstream.android.core.ui.design.StreamTokens +import io.getstream.video.android.compose.pip.rememberIsInPipMode import io.getstream.video.android.compose.theme.ParticipantLabelSoundIndicatorContentParams import io.getstream.video.android.compose.theme.ParticipantVideoActionsContentParams import io.getstream.video.android.compose.theme.ParticipantVideoConnectionIndicatorContentParams @@ -152,7 +154,12 @@ public fun ParticipantVideo( } } - val containerShape = RoundedCornerShape(StreamTokens.radiusXl) + // The system clips a Picture-in-Picture window with its own corner radius, which differs per device. + val containerShape = if (rememberIsInPipMode()) { + RectangleShape + } else { + RoundedCornerShape(StreamTokens.radiusXl) + } val containerModifier = if (style.isFocused && participants.size > 1) { modifier.border( border = if (style.isScreenSharing) { diff --git a/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_long_title.png b/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_long_title.png new file mode 100644 index 00000000000..b67aae419dd Binary files /dev/null and b/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_long_title.png differ diff --git a/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_uneven_slots.png b/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_uneven_slots.png new file mode 100644 index 00000000000..42ae30f20ab Binary files /dev/null and b/stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_call_app_bar_with_uneven_slots.png differ diff --git a/stream-video-android-ui-compose/src/testDebug/kotlin/io/getstream/video/android/compose/CallComponentsPortraitTest.kt b/stream-video-android-ui-compose/src/testDebug/kotlin/io/getstream/video/android/compose/CallComponentsPortraitTest.kt index ef66b4c31bd..c46550e2ff3 100644 --- a/stream-video-android-ui-compose/src/testDebug/kotlin/io/getstream/video/android/compose/CallComponentsPortraitTest.kt +++ b/stream-video-android-ui-compose/src/testDebug/kotlin/io/getstream/video/android/compose/CallComponentsPortraitTest.kt @@ -20,7 +20,9 @@ import app.cash.paparazzi.Paparazzi import com.android.ide.common.rendering.api.SessionParams import io.getstream.video.android.compose.ui.PIXEL_4A_HDPI import io.getstream.video.android.compose.ui.PaparazziComposeTest +import io.getstream.video.android.compose.ui.components.call.CallAppBarLongTitlePreview import io.getstream.video.android.compose.ui.components.call.CallAppBarPreview +import io.getstream.video.android.compose.ui.components.call.CallAppBarUnevenSlotsPreview import org.junit.Rule import org.junit.Test @@ -38,4 +40,18 @@ internal class CallComponentsPortraitTest : PaparazziComposeTest { CallAppBarPreview() } } + + @Test + fun `call app bar with uneven slots`() { + snapshotWithDarkMode { + CallAppBarUnevenSlotsPreview() + } + } + + @Test + fun `call app bar with long title`() { + snapshotWithDarkMode { + CallAppBarLongTitlePreview() + } + } }