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 @@ -48,6 +48,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.filled.SignalWifiBad
import androidx.compose.material.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -62,19 +63,23 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.getstream.android.video.generated.models.TranscriptionSettingsResponse
Expand Down Expand Up @@ -123,11 +128,15 @@ import io.getstream.video.android.ui.menu.SettingsMenu
import io.getstream.video.android.ui.menu.VideoFilter
import io.getstream.video.android.ui.menu.availableVideoFilters
import io.getstream.video.android.util.config.AppConfig
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch

@OptIn(FlowPreview::class)
@Composable
fun CallScreen(
call: Call,
Expand Down Expand Up @@ -174,6 +183,23 @@ fun CallScreen(

val connection by call.state.connection.collectAsStateWithLifecycle()
val me by call.state.me.collectAsStateWithLifecycle()
var anyPausedVideos by remember { mutableStateOf(false) }

LaunchedEffect(key1 = call) {
while (true) {
delay(2000)
Comment thread
aleksandar-apostolov marked this conversation as resolved.
call.state.participants
.sample(2000L)
.map { participants ->
// Compute only paused videos
participants.filter { it.videoPaused.value }
}
.distinctUntilChanged() // Only emit if the filtered list actually changes
.collect { pausedVideos ->
anyPausedVideos = pausedVideos.isNotEmpty()
}
}
}

LaunchedEffect(key1 = connection) {
if (connection == RealtimeConnection.Disconnected) {
Expand Down Expand Up @@ -567,7 +593,8 @@ fun CallScreen(
val isPortrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT

val popupYOffset = if (isPortrait) {
-(VideoTheme.dimens.componentHeightL + VideoTheme.dimens.spacingS).toPx().toInt()
-(VideoTheme.dimens.componentHeightL + VideoTheme.dimens.spacingS).toPx()
.toInt()
} else {
0
}
Expand Down Expand Up @@ -610,6 +637,10 @@ fun CallScreen(
SpeakingWhileMuted()
}

if (anyPausedVideos) {
BadNetworkLabel()
}

if (showingLandscapeControls && orientation == Configuration.ORIENTATION_LANDSCAPE) {
LandscapeControls(call, onChat = {
showingLandscapeControls = false
Expand Down Expand Up @@ -800,6 +831,44 @@ private fun SpeakingWhileMuted() {
}
}

@Composable
private fun BadNetworkLabel(
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.fillMaxSize()) {
Row(
modifier = modifier
.align(Alignment.BottomCenter)
.padding(vertical = 90.dp, horizontal = 16.dp)
.background(
color = VideoTheme.colors.baseSheetQuarternary,
shape = VideoTheme.shapes.sheet,
)
.testTag("video_renderer_fallback_bad_network"),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier
.padding(12.dp)
.align(CenterVertically),
imageVector = Icons.Default.SignalWifiBad,
contentDescription = null,
tint = VideoTheme.colors.basePrimary,
)
Text(
modifier = Modifier.padding(12.dp),
text = stringResource(
id = io.getstream.video.android.ui.common.R.string.stream_video_call_bad_network,
),
color = VideoTheme.colors.basePrimary,
textAlign = TextAlign.Center,
fontSize = 14.sp,
)
}
}
}

@Composable
fun isTablet(): Boolean {
val configuration = LocalConfiguration.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import io.getstream.video.android.core.StreamVideoBuilder
import io.getstream.video.android.core.logging.LoggingLevel
import io.getstream.video.android.core.notifications.NotificationConfig
import io.getstream.video.android.core.notifications.internal.service.CallServiceConfigRegistry
import io.getstream.video.android.core.notifications.internal.service.DefaultCallConfigurations
import io.getstream.video.android.core.socket.common.token.TokenProvider
import io.getstream.video.android.data.services.stream.GetAuthDataResponse
import io.getstream.video.android.data.services.stream.StreamService
Expand Down Expand Up @@ -191,13 +192,18 @@ object StreamVideoInitHelper {
token: String,
loggingLevel: LoggingLevel,
): StreamVideo {
val callServiceConfigRegistry = CallServiceConfigRegistry()
callServiceConfigRegistry.register(
DefaultCallConfigurations.getLivestreamGuestCallServiceConfig(),
)
return StreamVideoBuilder(
context = context,
apiKey = apiKey,
user = user,
token = token,
loggingLevel = loggingLevel,
ensureSingleInstance = false,
callServiceConfigRegistry = callServiceConfigRegistry,
notificationConfig = testNotificationConfig ?: NotificationConfig(
pushDeviceGenerators = listOf(
FirebasePushDeviceGenerator(
Expand All @@ -220,7 +226,6 @@ object StreamVideoInitHelper {
callUpdatesAfterLeave = true,
appName = "Stream Video Demo App",
audioProcessing = NoiseCancellation(context),
callServiceConfigRegistry = CallServiceConfigRegistry(),
).build()
}
}
Loading