Skip to content

Commit

Permalink
Calling 2.1 Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholas-signal authored and cody-signal committed Dec 19, 2023
1 parent 52f3ff5 commit a53a5f4
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ data class CallParticipantsState(

val allRemoteParticipants: List<CallParticipant> = remoteParticipants.allParticipants
val isFolded: Boolean = foldableState.isFolded
val isLargeVideoGroup: Boolean = allRemoteParticipants.size > SMALL_GROUP_MAX
val isLargeVideoGroup: Boolean = allRemoteParticipants.size > SMALL_GROUP_MAX && !isInPipMode && !isFolded
val isIncomingRing: Boolean = callState == WebRtcViewModel.State.CALL_INCOMING

val raisedHands: List<GroupCallRaiseHandEvent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public class WebRtcCallView extends InsetAwareConstraintLayout {
private View errorButton;
private boolean controlsVisible = true;
private Guideline showParticipantsGuideline;
private Guideline aboveControlsGuideline;
private Guideline topFoldGuideline;
private Guideline callScreenTopFoldGuideline;
private AvatarImageView largeHeaderAvatar;
Expand Down Expand Up @@ -193,6 +194,7 @@ protected void onFinishInflate() {
groupCallSpeakerHint = new Stub<>(findViewById(R.id.call_screen_group_call_speaker_hint));
groupCallFullStub = new Stub<>(findViewById(R.id.group_call_call_full_view));
showParticipantsGuideline = findViewById(R.id.call_screen_show_participants_guideline);
aboveControlsGuideline = findViewById(R.id.call_screen_above_controls_guideline);
topFoldGuideline = findViewById(R.id.fold_top_guideline);
callScreenTopFoldGuideline = findViewById(R.id.fold_top_call_screen_guideline);
largeHeaderAvatar = findViewById(R.id.call_screen_header_avatar);
Expand Down Expand Up @@ -462,9 +464,11 @@ public void updateCallParticipants(@NonNull CallParticipantsViewState callPartic

updateLocalCallParticipant(state.getLocalRenderState(), state.getLocalParticipant(), displaySmallSelfPipInLandscape);

if (state.isLargeVideoGroup() && !state.isInPipMode() && !state.isFolded()) {
if (state.isLargeVideoGroup()) {
moveSnackbarAboveParticipantRail(true);
adjustLayoutForLargeCount();
} else {
moveSnackbarAboveParticipantRail(state.isViewingFocusedParticipant());
adjustLayoutForSmallCount();
}
}
Expand Down Expand Up @@ -836,11 +840,26 @@ private void adjustLayoutPositions(@NonNull LayoutPositions layoutPositions) {
ConstraintSet.TOP,
ViewUtil.dpToPx(layoutPositions.reactionBottomMargin));

constraintSet.applyTo(this);
}

private void moveSnackbarAboveParticipantRail(boolean aboveRail) {
if (aboveRail) {
updateSnackbarBottomConstraint(callParticipantsRecycler);
} else {
updateSnackbarBottomConstraint(aboveControlsGuideline);
}
}

private void updateSnackbarBottomConstraint(View anchor) {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(this);

constraintSet.connect(R.id.call_screen_raise_hand_view,
ConstraintSet.BOTTOM,
layoutPositions.reactionBottomViewId,
anchor.getId(),
ConstraintSet.TOP,
ViewUtil.dpToPx(layoutPositions.reactionBottomMargin));
ViewUtil.dpToPx(8));

constraintSet.applyTo(this);
}
Expand Down Expand Up @@ -913,8 +932,15 @@ public void enableRingGroup(boolean enabled) {
ringToggle.setActivated(enabled);
}

public void onControlTopChanged(int top) {
pictureInPictureGestureHelper.setBottomVerticalBoundary(top);
public void onControlTopChanged(int guidelineTop, int snackBarHeight) {
int offset = 0;
if (lastState != null) {
CallParticipantsState state = lastState.getCallParticipantsState();
if (!state.isViewingFocusedParticipant() && !state.isLargeVideoGroup()) {
offset = snackBarHeight;
}
pictureInPictureGestureHelper.setBottomVerticalBoundary(guidelineTop - offset);
}
}

public interface ControlsListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public boolean displayAudioToggle() {
}

public boolean displayCameraToggle() {
return (isPreJoin() || (isAtLeastOutgoing() && !hasAtLeastOneRemote)) && isLocalVideoEnabled && isMoreThanOneCameraAvailable;
return (isPreJoin() || (isAtLeastOutgoing() && !hasAtLeastOneRemote)) && isLocalVideoEnabled && isMoreThanOneCameraAvailable && !isInPipMode;
}

public boolean displayRemoteVideoRecycler() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,11 @@ class ControlsAndInfoController(
BottomSheetBehaviorHack.setNestedScrollingChild(behavior, callInfoComposeView)

coordinator.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
val guidelineTop = max(frame.top, coordinator.height - behavior.peekHeight)
webRtcCallView.post { onControlTopChanged(guidelineTop) }
webRtcCallView.post { onControlTopChanged() }
}

raiseHandComposeView.addOnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ ->
onControlTopChanged(guidelineTop = aboveControlsGuideline.top, composeViewSize = bottom - top)
onControlTopChanged(composeViewSize = bottom - top)
}

callControls.viewTreeObserver.addOnGlobalLayoutListener {
Expand All @@ -141,8 +140,7 @@ class ControlsAndInfoController(
frame.minimumHeight = coordinator.height / 2
behavior.maxHeight = (coordinator.height.toFloat() * 0.66f).toInt()

val guidelineTop = max(frame.top, coordinator.height - behavior.peekHeight)
webRtcCallView.post { onControlTopChanged(guidelineTop) }
webRtcCallView.post { onControlTopChanged() }
}
}

Expand All @@ -168,7 +166,7 @@ class ControlsAndInfoController(
callInfoComposeView.alpha = alphaCallInfo(slideOffset)
callInfoComposeView.translationY = infoTranslationDistance - (infoTranslationDistance * callInfoComposeView.alpha)

onControlTopChanged(max(frame.top, coordinator.height - behavior.peekHeight))
onControlTopChanged()
}
})

Expand All @@ -185,9 +183,10 @@ class ControlsAndInfoController(
}
}

fun onControlTopChanged(guidelineTop: Int, composeViewSize: Int = raiseHandComposeView.height) {
fun onControlTopChanged(composeViewSize: Int = raiseHandComposeView.height) {
val guidelineTop = max(frame.top, coordinator.height - behavior.peekHeight)
aboveControlsGuideline.setGuidelineBegin(guidelineTop)
webRtcCallView.onControlTopChanged(guidelineTop - composeViewSize)
webRtcCallView.onControlTopChanged(guidelineTop, composeViewSize)
}

fun addVisibilityListener(listener: BottomSheetVisibilityListener): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
Expand Down Expand Up @@ -67,31 +65,31 @@ object RaiseHandSnackbar {

@Composable
fun View(webRtcCallViewModel: WebRtcCallViewModel, showCallInfoListener: () -> Unit, modifier: Modifier = Modifier) {
var isExpanded by remember { mutableStateOf(ExpansionState(isExpanded = false, forced = false)) }
var expansionState by remember { mutableStateOf(ExpansionState(shouldExpand = false, forced = false)) }

val webRtcState by webRtcCallViewModel.callParticipantsState
.toFlowable(BackpressureStrategy.LATEST)
.map { state ->
val raisedHands = state.raisedHands.sortedByDescending { it.timestamp }
val shouldExpand = RaiseHandState.shouldExpand(raisedHands)
if (!isExpanded.forced) {
isExpanded = ExpansionState(shouldExpand, false)
if (!expansionState.forced) {
expansionState = ExpansionState(shouldExpand, false)
}
raisedHands
}.subscribeAsState(initial = emptyList())

val state by remember {
derivedStateOf {
RaiseHandState(raisedHands = webRtcState, expansionState = isExpanded)
RaiseHandState(raisedHands = webRtcState, expansionState = expansionState)
}
}

LaunchedEffect(isExpanded) {
LaunchedEffect(expansionState) {
delay(COLLAPSE_DELAY_MS)
isExpanded = ExpansionState(isExpanded = false, forced = false)
expansionState = ExpansionState(shouldExpand = false, forced = false)
}

RaiseHand(state, modifier, { isExpanded = ExpansionState(isExpanded = true, forced = true) }, showCallInfoListener = showCallInfoListener)
RaiseHand(state, modifier, { expansionState = ExpansionState(shouldExpand = true, forced = true) }, showCallInfoListener = showCallInfoListener)
}
}

Expand Down Expand Up @@ -123,20 +121,19 @@ private fun RaiseHand(
.padding(horizontal = 16.dp)
.clip(shape = RoundedCornerShape(16.dp, 16.dp, 16.dp, 16.dp))
.background(MaterialTheme.colorScheme.surface)
.height(48.dp)
.animateContentSize()
) {
val boxModifier = modifier
.padding(horizontal = 16.dp)
.clickable(
!state.expansionState.isExpanded,
!state.isExpanded,
stringResource(id = R.string.CallOverflowPopupWindow__expand_snackbar_accessibility_label),
Role.Button
) { setExpanded(true) }

Box(
contentAlignment = Alignment.CenterStart,
modifier = if (state.expansionState.isExpanded) {
modifier = if (state.isExpanded) {
boxModifier.fillMaxWidth()
} else {
boxModifier.wrapContentWidth()
Expand All @@ -146,27 +143,35 @@ private fun RaiseHand(
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.symbol_raise_hand_24),
contentDescription = null,
modifier = Modifier.align(Alignment.CenterVertically)
modifier = Modifier.align(Alignment.CenterVertically).padding(vertical = 8.dp)
)

Text(
text = getSnackbarText(state),
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(start = 16.dp)
modifier = Modifier
.padding(start = 16.dp)
.weight(1f, fill = state.isExpanded)
.wrapContentWidth(Alignment.Start)
.padding(vertical = 16.dp)
)
if (state.expansionState.isExpanded && state.raisedHands.isNotEmpty()) {
Spacer(modifier = Modifier.weight(1f))

if (state.isExpanded) {
if (state.raisedHands.first().sender.isSelf) {
val context = LocalContext.current
TextButton(onClick = {
showLowerHandDialog(context)
}) {
Text(text = stringResource(id = R.string.CallOverflowPopupWindow__lower_hand))
TextButton(
onClick = {
showLowerHandDialog(context)
},
modifier = Modifier.wrapContentWidth(Alignment.End)
) {
Text(text = stringResource(id = R.string.CallOverflowPopupWindow__lower_hand), maxLines = 1)
}
} else {
TextButton(onClick = showCallInfoListener) {
Text(text = stringResource(id = R.string.CallOverflowPopupWindow__view))
TextButton(
onClick = showCallInfoListener,
modifier = Modifier.wrapContentWidth(Alignment.End)
) {
Text(text = stringResource(id = R.string.CallOverflowPopupWindow__view), maxLines = 1)
}
}
}
Expand All @@ -189,10 +194,10 @@ private fun showLowerHandDialog(context: Context) {

@Composable
private fun getSnackbarText(state: RaiseHandState): String {
if (state.isEmpty()) {
if (state.isEmpty) {
return ""
}
return if (!state.expansionState.isExpanded) {
return if (!state.isExpanded) {
pluralStringResource(id = R.plurals.CallRaiseHandSnackbar_raised_hands, count = state.raisedHands.size, getShortDisplayName(state.raisedHands), state.raisedHands.size - 1)
} else {
if (state.raisedHands.size == 1 && state.raisedHands.first().sender.isSelf) {
Expand All @@ -215,12 +220,11 @@ private fun getShortDisplayName(raisedHands: List<GroupCallRaiseHandEvent>): Str

private data class RaiseHandState(
val raisedHands: List<GroupCallRaiseHandEvent> = emptyList(),
val expansionState: ExpansionState = ExpansionState(isExpanded = false, forced = false)
val expansionState: ExpansionState = ExpansionState(shouldExpand = false, forced = false)
) {
val isExpanded = expansionState.shouldExpand && raisedHands.isNotEmpty()

fun isEmpty(): Boolean {
return raisedHands.isEmpty()
}
val isEmpty = raisedHands.isEmpty()

companion object {
@JvmStatic
Expand All @@ -232,6 +236,6 @@ private data class RaiseHandState(
}

private data class ExpansionState(
val isExpanded: Boolean,
val shouldExpand: Boolean,
val forced: Boolean
)
1 change: 0 additions & 1 deletion app/src/main/res/layout/webrtc_call_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
android:orientation="horizontal"
tools:layout_constraintGuide_end="200dp" />


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/call_screen_participants_parent"
android:layout_width="0dp"
Expand Down

0 comments on commit a53a5f4

Please sign in to comment.