Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AND-393] Revert builder & ringing call UI component changes #1317

Merged
merged 10 commits into from
Mar 13, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.getstream.chat.android.client.ChatClient
import io.getstream.chat.android.models.Filters
import io.getstream.chat.android.models.querysort.QuerySortByField
import io.getstream.result.onSuccessSuspend
import io.getstream.video.android.compose.ui.ComposeStreamCallActivity
import io.getstream.video.android.compose.ui.StreamCallActivityComposeDelegate
import io.getstream.video.android.compose.ui.components.call.activecall.AudioOnlyCallContent
import io.getstream.video.android.core.Call
import io.getstream.video.android.core.StreamVideo
import io.getstream.video.android.core.notifications.NotificationHandler
Expand Down Expand Up @@ -125,6 +127,18 @@ class CallActivity : ComposeStreamCallActivity() {
}
}

@Composable
override fun StreamCallActivity.AudioCallContent(call: Call) {
val micEnabled by call.microphone.isEnabled.collectAsStateWithLifecycle()

AudioOnlyCallContent(
call = call,
isMicrophoneEnabled = micEnabled,
onCallAction = { onCallAction(call, it) },
onBackPressed = { onBackPressed(call) },
)
}

private fun StreamCallActivity.goBackToMainScreen() {
if (!isFinishing) {
val intent = Intent(this, MainActivity::class.java).apply {
Expand Down
38 changes: 20 additions & 18 deletions stream-video-android-core/api/stream-video-android-core.api

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ public class StreamVideoBuilder @JvmOverloads constructor(
private var ensureSingleInstance: Boolean = true,
private val videoDomain: String = "video.stream-io-api.com",
@Deprecated(
"Use 'callServiceConfigRegistry' instead",
"This property is ignored. Set runCallServiceInForeground in the callServiceConfigRegistry parameter instead.",
replaceWith = ReplaceWith("callServiceConfigRegistry"),
level = DeprecationLevel.WARNING,
)
private val runForegroundServiceForCalls: Boolean = true,
@Deprecated(
"Use callServiceConfigRegistry instead",
replaceWith = ReplaceWith("callServiceConfigRegistry"),
level = DeprecationLevel.WARNING,
)
Expand All @@ -119,6 +125,11 @@ public class StreamVideoBuilder @JvmOverloads constructor(
private val sounds: Sounds = defaultResourcesRingingConfig(context).toSounds(),
private val crashOnMissingPermission: Boolean = false,
private val permissionCheck: StreamPermissionCheck = DefaultStreamPermissionCheck(),
@Deprecated(
message = "This property is ignored. Set audioUsage in the callServiceConfigRegistry parameter instead.",
level = DeprecationLevel.WARNING,
)
private val audioUsage: Int = defaultAudioUsage,
private val appName: String? = null,
private val audioProcessing: ManagedAudioProcessingFactory? = null,
private val leaveAfterDisconnectSeconds: Long = 30,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ public sealed interface CallStatus {
public data object Outgoing : CallStatus

@Stable
public data class Ongoing(public val duration: String) : CallStatus
public data class Calling(public val duration: String) : CallStatus
}
Original file line number Diff line number Diff line change
Expand Up @@ -1041,9 +1041,10 @@ public final class io/getstream/video/android/compose/ui/components/call/Composa
}

public final class io/getstream/video/android/compose/ui/components/call/activecall/AudioCallContentKt {
public static final fun AudioCallContent (Landroidx/compose/ui/Modifier;Lio/getstream/video/android/core/Call;ZLio/getstream/video/android/compose/permission/VideoPermissionsState;ZLkotlin/jvm/functions/Function3;Ljava/lang/String;Lkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;III)V
public static final fun AudioCallControls (Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
public static final fun AudioCallDetails (Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/util/List;Landroidx/compose/runtime/Composer;II)V
public static final fun AudioCallContent (Landroidx/compose/ui/Modifier;Lio/getstream/video/android/core/Call;ZLio/getstream/video/android/compose/permission/VideoPermissionsState;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ZLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;III)V
public static final fun AudioOnlyCallContent (Landroidx/compose/ui/Modifier;Lio/getstream/video/android/core/Call;ZLio/getstream/video/android/compose/permission/VideoPermissionsState;ZLkotlin/jvm/functions/Function3;Ljava/lang/String;Lkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;III)V
public static final fun AudioOnlyCallControls (Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
public static final fun AudioOnlyCallDetails (Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/util/List;Landroidx/compose/runtime/Composer;II)V
}

public final class io/getstream/video/android/compose/ui/components/call/activecall/CallContentKt {
Expand All @@ -1053,8 +1054,10 @@ public final class io/getstream/video/android/compose/ui/components/call/activec
public final class io/getstream/video/android/compose/ui/components/call/activecall/ComposableSingletons$AudioCallContentKt {
public static final field INSTANCE Lio/getstream/video/android/compose/ui/components/call/activecall/ComposableSingletons$AudioCallContentKt;
public static field lambda-1 Lkotlin/jvm/functions/Function2;
public static field lambda-2 Lkotlin/jvm/functions/Function2;
public fun <init> ()V
public final fun getLambda-1$stream_video_android_ui_compose_release ()Lkotlin/jvm/functions/Function2;
public final fun getLambda-2$stream_video_android_ui_compose_release ()Lkotlin/jvm/functions/Function2;
}

public final class io/getstream/video/android/compose/ui/components/call/activecall/ComposableSingletons$CallContentKt {
Expand Down Expand Up @@ -1822,6 +1825,7 @@ public final class io/getstream/video/android/compose/ui/components/participants
}

public final class io/getstream/video/android/compose/ui/components/participants/ParticipantAvatarsKt {
public static final fun ParticipantAvatars (Ljava/util/List;Landroidx/compose/runtime/Composer;I)V
public static final fun ParticipantAvatars (Ljava/util/List;Ljava/util/List;Landroidx/compose/runtime/Composer;II)V
}

Expand Down Expand Up @@ -1866,6 +1870,7 @@ public final class io/getstream/video/android/compose/ui/components/participants

public final class io/getstream/video/android/compose/ui/components/participants/internal/ParticipantInformationKt {
public static final fun ParticipantInformation (Lio/getstream/video/android/core/model/CallStatus;Ljava/util/List;Ljava/util/List;ZLandroidx/compose/runtime/Composer;II)V
public static final fun ParticipantInformation (Lio/getstream/video/android/core/model/CallStatus;Ljava/util/List;ZLandroidx/compose/runtime/Composer;II)V
}

public final class io/getstream/video/android/compose/ui/components/video/ComposableSingletons$VideoRendererKt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
Expand All @@ -44,17 +45,107 @@ import io.getstream.video.android.compose.ui.components.call.activecall.internal
import io.getstream.video.android.compose.ui.components.call.controls.actions.DefaultOnCallActionHandler
import io.getstream.video.android.compose.ui.components.call.controls.actions.LeaveCallAction
import io.getstream.video.android.compose.ui.components.call.controls.actions.ToggleMicrophoneAction
import io.getstream.video.android.compose.ui.components.call.ringing.outgoingcall.OutgoingCallContent
import io.getstream.video.android.compose.ui.components.call.ringing.outgoingcall.OutgoingCallControls
import io.getstream.video.android.compose.ui.components.participants.ParticipantAvatars
import io.getstream.video.android.compose.ui.components.participants.internal.ParticipantInformation
import io.getstream.video.android.core.Call
import io.getstream.video.android.core.MemberState
import io.getstream.video.android.core.ParticipantState
import io.getstream.video.android.core.call.state.CallAction
import io.getstream.video.android.core.model.CallStatus
import io.getstream.video.android.mock.StreamPreviewDataUtils
import io.getstream.video.android.mock.previewCall

/**
* Represents the UI of an active audio only call.
* Audio call content represents the UI of an active audio only call.
*
* @param call The call includes states and will be rendered with participants.
* @param modifier Modifier for styling.
* @param isMicrophoneEnabled weather or not the microphone icon will be enabled or not
* @param permissions the permissions required for the call to work (e.g. manifest.RECORD_AUDIO)
* @param onBackPressed Handler when the user taps on the back button.
* @param permissions Android permissions that should be required to render a video call properly.
* @param onCallAction Handler when the user triggers a Call Control Action.
* @param controlsContent Content is shown that allows users to trigger different actions to control a joined call.
* @param durationPlaceholder Content (text) shown while the duration is not available yet
* @param isShowingHeader if true, header content is shown
* @param headerContent override the header content
* @param detailsContent override the details content (middle part of the screen)
*/
@Deprecated(
message = "AudioCallContent is deprecated. Use the new AudioOnlyCallContent instead.",
replaceWith = ReplaceWith("AudioOnlyCallContent"),
)
@Composable
public fun AudioCallContent(
modifier: Modifier = Modifier,
call: Call,
isMicrophoneEnabled: Boolean,
permissions: VideoPermissionsState = rememberCallPermissionsState(
call = call,
permissions = listOf(
android.Manifest.permission.RECORD_AUDIO,
),
),
onCallAction: (CallAction) -> Unit = { action: CallAction ->
DefaultOnCallActionHandler.onCallAction(call, action)
},
durationPlaceholder: String = "",
isShowingHeader: Boolean = true,
headerContent: (@Composable ColumnScope.() -> Unit)? = null,
detailsContent: (
@Composable ColumnScope.(
participants: List<MemberState>,
topPadding: Dp,
) -> Unit
)? = null,
controlsContent: (@Composable BoxScope.() -> Unit)? = null,
onBackPressed: () -> Unit = {},
) {
val duration by call.state.duration.collectAsStateWithLifecycle()
val durationText = duration?.toString() ?: durationPlaceholder

DefaultPermissionHandler(videoPermission = permissions)

OutgoingCallContent(
modifier = modifier,
isShowingHeader = isShowingHeader,
headerContent = headerContent,
call = call,
isVideoType = false,
detailsContent = detailsContent ?: { members, topPadding ->
Column(
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(top = topPadding),
) {
ParticipantInformation(
isVideoType = false,
callStatus = CallStatus.Calling(durationText),
participants = members,
)
Spacer(modifier = Modifier.size(16.dp))
ParticipantAvatars(participants = members)
}
},
onBackPressed = onBackPressed,
controlsContent = controlsContent ?: {
OutgoingCallControls(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(VideoTheme.dimens.spacingM),
isVideoCall = false,
isCameraEnabled = false,
isMicrophoneEnabled = isMicrophoneEnabled,
onCallAction = onCallAction,
)
},
)
}

/**
* Represents the UI for an active audio-only call. By default, it shows the current participants that are in the call.
*
* @param modifier Modifier for styling.
* @param call The call to be rendered.
Expand All @@ -69,7 +160,7 @@ import io.getstream.video.android.mock.previewCall
* @param onBackPressed Handler used when the user taps on the back button.
*/
@Composable
public fun AudioCallContent(
public fun AudioOnlyCallContent(
modifier: Modifier = Modifier,
call: Call,
isMicrophoneEnabled: Boolean,
Expand Down Expand Up @@ -108,7 +199,7 @@ public fun AudioCallContent(
Column {
if (isShowingHeader) headerContent?.invoke(this)

detailsContent?.invoke(this, remoteParticipants, VideoTheme.dimens.spacingM) ?: AudioCallDetails(
detailsContent?.invoke(this, remoteParticipants, VideoTheme.dimens.spacingM) ?: AudioOnlyCallDetails(
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(top = VideoTheme.dimens.spacingM),
Expand All @@ -117,7 +208,7 @@ public fun AudioCallContent(
)
}

controlsContent?.invoke(this) ?: AudioCallControls(
controlsContent?.invoke(this) ?: AudioOnlyCallControls(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = VideoTheme.dimens.componentHeightM),
Expand All @@ -127,8 +218,15 @@ public fun AudioCallContent(
}
}

/**
* Component that displays details for an active audio-only call.
*
* @param modifier Modifier for styling.
* @param duration The current duration of the call.
* @param participants A list of current call participants to be displayed.
*/
@Composable
public fun AudioCallDetails(
public fun AudioOnlyCallDetails(
modifier: Modifier = Modifier,
duration: String,
participants: List<ParticipantState>,
Expand All @@ -140,14 +238,21 @@ public fun AudioCallDetails(

ParticipantInformation(
isVideoType = false,
callStatus = CallStatus.Ongoing(duration),
callStatus = CallStatus.Calling(duration),
participants = participants,
)
}
}

/**
* Component that displays the call controls for an active audio-only call.
*
* @param modifier Modifier for styling.
* @param isMicrophoneEnabled Weather or not the microphone icon will show the mic as enabled or not.
* @param onCallAction Handler used when the user triggers a [CallAction].
*/
@Composable
public fun AudioCallControls(
public fun AudioOnlyCallControls(
modifier: Modifier,
isMicrophoneEnabled: Boolean,
onCallAction: (CallAction) -> Unit,
Expand Down Expand Up @@ -183,3 +288,16 @@ private fun AudioCallContentPreview() {
)
}
}

@Preview
@Composable
private fun AudioOnlyCallContentPreview() {
val context = LocalContext.current
StreamPreviewDataUtils.initializeStreamVideo(context)
VideoTheme {
AudioOnlyCallContent(
call = previewCall,
isMicrophoneEnabled = false,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public fun IncomingCallContent(
IncomingCallContent(
call = call,
isVideoType = isVideoType,
members = remoteMembers,
participants = remoteMembers,
isCameraEnabled = isCameraEnabled,
isShowingHeader = isShowingHeader,
modifier = modifier,
Expand All @@ -106,7 +106,7 @@ public fun IncomingCallContent(
*
* @param call The call contains states and will be rendered with participants.
* @param isVideoType The type of call, Audio or Video.
* @param members List of call members.
* @param participants List of call members.
* @param isCameraEnabled Whether the video should be enabled when entering the call or not.
* @param modifier Modifier for styling.
* @param isShowingHeader If the app bar header is shown or not.
Expand All @@ -119,7 +119,7 @@ public fun IncomingCallContent(
modifier: Modifier = Modifier,
call: Call,
isVideoType: Boolean = true,
members: List<MemberState>,
participants: List<MemberState>,
isCameraEnabled: Boolean,
isShowingHeader: Boolean = true,
backgroundContent: (@Composable BoxScope.() -> Unit)? = null,
Expand All @@ -143,17 +143,17 @@ public fun IncomingCallContent(
headerContent?.invoke(this)
}

val topPadding = if (members.size == 1) {
val topPadding = if (participants.size == 1) {
VideoTheme.dimens.spacingL
} else {
VideoTheme.dimens.spacingM
}
detailsContent?.invoke(this, members, topPadding) ?: IncomingCallDetails(
detailsContent?.invoke(this, participants, topPadding) ?: IncomingCallDetails(
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(top = topPadding),
isVideoType = isVideoType,
members = members,
participants = participants,
)
}

Expand All @@ -179,7 +179,7 @@ private fun IncomingCallPreview1() {
) {
IncomingCallContent(
call = previewCall,
members = previewMemberListState.takeLast(1),
participants = previewMemberListState.takeLast(1),
isVideoType = true,
isCameraEnabled = false,
onBackPressed = {},
Expand All @@ -199,7 +199,7 @@ private fun IncomingCallPreview2() {
) {
IncomingCallContent(
call = previewCall,
members = previewMemberListState,
participants = previewMemberListState,
isVideoType = true,
isCameraEnabled = false,
onBackPressed = {},
Expand Down
Loading
Loading