Skip to content

Commit

Permalink
feat(calling): Adapt the floating self user view in PiP mode (WPB-106…
Browse files Browse the repository at this point in the history
…52) - Part 3 (#3410)
  • Loading branch information
ohassine authored Sep 9, 2024
1 parent c2317fb commit 887c9b5
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,23 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.core.app.PictureInPictureModeChangedInfo
import androidx.core.util.Consumer
import com.wire.android.ui.calling.model.UICallParticipant
import com.wire.android.ui.calling.ongoing.OngoingCallActivity
import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.dimensions

Expand All @@ -48,7 +53,9 @@ private const val STIFFNESS_MEDIUM_LOW = 300f
private const val DEFAULT_OFFSETX_SELF_USER_TILE = -50f
private const val DEFAULT_OFFSETY_SELF_USER_TILE = 80F
private val SELF_VIDEO_TILE_HEIGHT = 250.dp
private val SELF_VIDEO_TILE_HEIGHT_IN_PIP = 60.dp
private val SELF_VIDEO_TILE_WIDTH = 150.dp
private val SELF_VIDEO_TILE_WIDTH_IN_PIP = 40.dp

@Composable
fun FloatingSelfUserTile(
Expand All @@ -59,9 +66,21 @@ fun FloatingSelfUserTile(
modifier: Modifier = Modifier,
onClearSelfUserVideoPreview: () -> Unit
) {
var selfVideoTileHeight by remember {
mutableStateOf(SELF_VIDEO_TILE_HEIGHT)
}
var selfVideoTileWidth by remember {
mutableStateOf(SELF_VIDEO_TILE_WIDTH)
}
val activity = LocalContext.current

val density = LocalDensity.current
val contentHeightPx = density.run { (contentHeight).toPx() }

var isOnPiPMode by remember {
mutableStateOf(false)
}

var selfUserTileOffsetX by remember {
mutableStateOf(DEFAULT_OFFSETX_SELF_USER_TILE)
}
Expand All @@ -77,12 +96,34 @@ fun FloatingSelfUserTile(
label = "selfUserTileOffset"
)

DisposableEffect(activity) {
val observer = Consumer<PictureInPictureModeChangedInfo> { info ->
if (info.isInPictureInPictureMode) {
selfVideoTileHeight = SELF_VIDEO_TILE_HEIGHT_IN_PIP
selfVideoTileWidth = SELF_VIDEO_TILE_WIDTH_IN_PIP
selfUserTileOffsetX = -10f
selfUserTileOffsetY = 10f
isOnPiPMode = true
} else {
selfVideoTileHeight = SELF_VIDEO_TILE_HEIGHT
selfVideoTileWidth = SELF_VIDEO_TILE_WIDTH
selfUserTileOffsetX = DEFAULT_OFFSETX_SELF_USER_TILE
selfUserTileOffsetY = DEFAULT_OFFSETY_SELF_USER_TILE
isOnPiPMode = false
}
}
(activity as OngoingCallActivity).addOnPictureInPictureModeChangedListener(
observer
)
onDispose { activity.removeOnPictureInPictureModeChangedListener(observer) }
}

Card(
border = BorderStroke(1.dp, colorsScheme().uncheckedColor),
shape = RoundedCornerShape(dimensions().corner6x),
modifier = modifier
.height(SELF_VIDEO_TILE_HEIGHT)
.width(SELF_VIDEO_TILE_WIDTH)
.height(selfVideoTileHeight)
.width(selfVideoTileWidth)
.offset { IntOffset(selfUserTileOffset.x.toInt(), selfUserTileOffset.y.toInt()) }
.pointerInput(Unit) {
detectDragGestures(
Expand All @@ -91,11 +132,11 @@ fun FloatingSelfUserTile(
if (selfUserTileOffsetX - 150f > -(contentWidth / 2)) {
DEFAULT_OFFSETX_SELF_USER_TILE
} else {
-contentWidth + SELF_VIDEO_TILE_WIDTH.toPx() - DEFAULT_OFFSETX_SELF_USER_TILE
-contentWidth + selfVideoTileWidth.toPx() - DEFAULT_OFFSETX_SELF_USER_TILE
}
selfUserTileOffsetY =
if (selfUserTileOffsetY + 250f > (contentHeightPx / 2)) {
contentHeightPx - SELF_VIDEO_TILE_HEIGHT.toPx() - DEFAULT_OFFSETY_SELF_USER_TILE
contentHeightPx - selfVideoTileHeight.toPx() - DEFAULT_OFFSETY_SELF_USER_TILE
} else {
DEFAULT_OFFSETY_SELF_USER_TILE
}
Expand All @@ -104,14 +145,14 @@ fun FloatingSelfUserTile(
change.consume()
val newOffsetX = (selfUserTileOffsetX + dragAmount.x)
.coerceAtLeast(
-contentHeightPx - SELF_VIDEO_TILE_WIDTH.toPx()
-contentHeightPx - selfVideoTileWidth.toPx()
)
.coerceAtMost(-50f)

val newOffsetY = (selfUserTileOffsetY + dragAmount.y)
.coerceAtLeast(50f)
.coerceAtMost(
contentHeightPx - SELF_VIDEO_TILE_HEIGHT.toPx()
contentHeightPx - selfVideoTileHeight.toPx()
)

selfUserTileOffsetX = newOffsetX
Expand All @@ -122,6 +163,7 @@ fun FloatingSelfUserTile(
ParticipantTile(
participantTitleState = participant,
isSelfUser = true,
isOnPiPMode = isOnPiPMode,
shouldFillSelfUserCameraPreview = true,
isSelfUserMuted = participant.isMuted,
isSelfUserCameraOn = participant.isCameraOn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ fun ParticipantTile(
isSelfUserCameraOn: Boolean,
onSelfUserVideoPreviewCreated: (view: View) -> Unit,
modifier: Modifier = Modifier,
isOnPiPMode: Boolean = false,
shouldFillSelfUserCameraPreview: Boolean = false,
shouldFillOthersVideoPreview: Boolean = true,
isZoomingEnabled: Boolean = false,
Expand All @@ -119,7 +120,11 @@ fun ParticipantTile(
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
bottom.linkTo(bottomRow.top)
if (isOnPiPMode) {
bottom.linkTo(parent.bottom)
} else {
bottom.linkTo(bottomRow.top)
}
width = Dimension.fillToConstraints.atMost(maxAvatarSize)
height =
Dimension.fillToConstraints.atMost(maxAvatarSize + activeSpeakerBorderPadding)
Expand All @@ -128,6 +133,7 @@ fun ParticipantTile(
asset = participantTitleState.avatar,
nameBasedAvatar = NameBasedAvatar(participantTitleState.name, participantTitleState.accentId)
),
isOnPiPMode = isOnPiPMode
)

if (isSelfUser) {
Expand All @@ -148,23 +154,25 @@ fun ParticipantTile(
)
}

BottomRow(
participantTitleState = participantTitleState,
isSelfUser = isSelfUser,
isSelfUserMuted = isSelfUserMuted,
modifier = Modifier
.padding(
// move by the size of the active speaker border
start = dimensions().spacing6x,
end = dimensions().spacing6x,
bottom = dimensions().spacing6x,
)
.constrainAs(bottomRow) {
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
)
if (!isOnPiPMode) {
BottomRow(
participantTitleState = participantTitleState,
isSelfUser = isSelfUser,
isSelfUserMuted = isSelfUserMuted,
modifier = Modifier
.padding(
// move by the size of the active speaker border
start = dimensions().spacing6x,
end = dimensions().spacing6x,
bottom = dimensions().spacing6x,
)
.constrainAs(bottomRow) {
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
)
}
}
}
}
Expand Down Expand Up @@ -359,12 +367,13 @@ private fun OthersVideoRenderer(
private fun AvatarTile(
avatar: UserAvatarData,
modifier: Modifier = Modifier,
isOnPiPMode: Boolean = false
) {
BoxWithConstraints(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
val size = min(maxWidth, maxHeight)
val size = if (isOnPiPMode) 20.dp else min(maxWidth, maxHeight)
UserProfileAvatar(
padding = dimensions().spacing0x,
size = size,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.wire.android.BuildConfig
import com.wire.android.ui.LocalActivity
import com.wire.android.ui.calling.model.UICallParticipant
import com.wire.android.ui.calling.ongoing.buildPreviewParticipantsList
import com.wire.android.ui.calling.ongoing.fullscreen.SelectedParticipant
Expand Down Expand Up @@ -68,6 +69,8 @@ fun VerticalCallingPager(
onDoubleTap: (selectedParticipant: SelectedParticipant) -> Unit,
modifier: Modifier = Modifier,
) {
val activity = LocalActivity.current

Column(
modifier = modifier
.fillMaxWidth()
Expand Down Expand Up @@ -128,8 +131,8 @@ fun VerticalCallingPager(
}
}
}
// we don't need to display the indicator if we have one page
if (pagesCount(participants.size) > 1) {
// we don't need to display the indicator if we have one page and when it's in PiP mode
if (pagesCount(participants.size) > 1 && !activity.isInPictureInPictureMode) {
Surface(
shape = RoundedCornerShape(dimensions().corner16x),
modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package com.wire.android.ui.calling.ongoing.participantsview.gridview

import android.view.View
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
Expand All @@ -36,6 +35,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.times
import com.wire.android.BuildConfig
import com.wire.android.ui.LocalActivity
import com.wire.android.ui.calling.model.UICallParticipant
import com.wire.android.ui.calling.ongoing.buildPreviewParticipantsList
import com.wire.android.ui.calling.ongoing.fullscreen.SelectedParticipant
Expand All @@ -44,7 +44,6 @@ import com.wire.android.ui.common.dimensions
import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.ui.PreviewMultipleThemes

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GroupCallGrid(
participants: List<UICallParticipant>,
Expand All @@ -59,6 +58,8 @@ fun GroupCallGrid(
contentPadding: Dp = dimensions().spacing4x,
spacedBy: Dp = dimensions().spacing2x,
) {
val activity = LocalActivity.current

// We need the number of tiles rows needed to calculate their height
val numberOfTilesRows = remember(participants.size) {
tilesRowsCount(participants.size)
Expand Down Expand Up @@ -105,6 +106,7 @@ fun GroupCallGrid(
.height(tileHeight)
.animateItem(),
participantTitleState = participant,
isOnPiPMode = activity.isInPictureInPictureMode,
isSelfUser = isSelfUser,
isSelfUserMuted = isSelfUserMuted,
isSelfUserCameraOn = isSelfUserCameraOn,
Expand Down

0 comments on commit 887c9b5

Please sign in to comment.