mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-14 23:18:43 +00:00
Display self-pip above raise hands bar if it is present.
This commit is contained in:
@@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.SubcomposeLayout
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
@@ -69,25 +70,62 @@ fun CallElementsLayout(
|
||||
bottomSheetWidth.roundToPx()
|
||||
}
|
||||
|
||||
Box(modifier = modifier) {
|
||||
BlurrableContentLayer(
|
||||
isFocused = isFocused,
|
||||
isPortrait = isPortrait,
|
||||
bottomInsetPx = bottomInsetPx,
|
||||
bottomSheetWidthPx = bottomSheetWidthPx,
|
||||
barsSlot = { Bars() },
|
||||
callGridSlot = callGridSlot,
|
||||
reactionsSlot = reactionsSlot,
|
||||
callOverflowSlot = callOverflowSlot
|
||||
)
|
||||
SubcomposeLayout(modifier = modifier) { constraints ->
|
||||
// First, measure the bars to get their height
|
||||
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
|
||||
|
||||
PipLayer(
|
||||
pictureInPictureSlot = pictureInPictureSlot,
|
||||
localRenderState = localRenderState,
|
||||
bottomInsetPx = bottomInsetPx,
|
||||
pipSizePx = pipSizePx,
|
||||
bottomSheetWidthPx = bottomSheetWidthPx
|
||||
)
|
||||
// Measure overflow to determine constraints for bars
|
||||
val overflowPlaceables = subcompose("overflow_measure", callOverflowSlot).map { it.measure(looseConstraints) }
|
||||
val constrainedHeightOffset = if (isPortrait) overflowPlaceables.maxOfOrNull { it.height } ?: 0 else 0
|
||||
val constrainedWidthOffset = if (isPortrait) { 0 } else overflowPlaceables.maxOfOrNull { it.width } ?: 0
|
||||
|
||||
val nonOverflowConstraints = looseConstraints.offset(horizontal = -constrainedWidthOffset, vertical = -constrainedHeightOffset)
|
||||
|
||||
val barConstraints = if (bottomInsetPx > constrainedHeightOffset) {
|
||||
looseConstraints.offset(-constrainedWidthOffset, -bottomInsetPx)
|
||||
} else {
|
||||
nonOverflowConstraints
|
||||
}
|
||||
|
||||
val barsMaxWidth = minOf(barConstraints.maxWidth, bottomSheetWidthPx)
|
||||
val barsConstrainedToSheet = barConstraints.copy(maxWidth = barsMaxWidth)
|
||||
|
||||
val barsPlaceables = subcompose("bars_measure") { Bars() }.map { it.measure(barsConstrainedToSheet) }
|
||||
val barsHeightPx = barsPlaceables.sumOf { it.height }
|
||||
val barsWidthPx = barsPlaceables.maxOfOrNull { it.width } ?: 0
|
||||
|
||||
// Now compose and measure the actual layers with the bars height available
|
||||
val blurrableLayerPlaceable = subcompose("blurrable") {
|
||||
BlurrableContentLayer(
|
||||
isFocused = isFocused,
|
||||
isPortrait = isPortrait,
|
||||
bottomInsetPx = bottomInsetPx,
|
||||
bottomSheetWidthPx = bottomSheetWidthPx,
|
||||
barsSlot = { Bars() },
|
||||
callGridSlot = callGridSlot,
|
||||
reactionsSlot = reactionsSlot,
|
||||
callOverflowSlot = callOverflowSlot
|
||||
)
|
||||
}.map { it.measure(constraints) }
|
||||
|
||||
// Use the wider of bars or bottom sheet for space calculation
|
||||
val centeredContentWidthPx = maxOf(barsWidthPx, bottomSheetWidthPx)
|
||||
|
||||
val pipLayerPlaceable = subcompose("pip") {
|
||||
PipLayer(
|
||||
pictureInPictureSlot = pictureInPictureSlot,
|
||||
localRenderState = localRenderState,
|
||||
bottomInsetPx = bottomInsetPx,
|
||||
barsHeightPx = barsHeightPx,
|
||||
pipSizePx = pipSizePx,
|
||||
centeredContentWidthPx = centeredContentWidthPx
|
||||
)
|
||||
}.map { it.measure(constraints) }
|
||||
|
||||
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||
blurrableLayerPlaceable.forEach { it.place(0, 0) }
|
||||
pipLayerPlaceable.forEach { it.place(0, 0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,8 +203,9 @@ private fun PipLayer(
|
||||
pictureInPictureSlot: @Composable () -> Unit,
|
||||
localRenderState: WebRtcLocalRenderState,
|
||||
bottomInsetPx: Int,
|
||||
barsHeightPx: Int,
|
||||
pipSizePx: Size,
|
||||
bottomSheetWidthPx: Int
|
||||
centeredContentWidthPx: Int
|
||||
) {
|
||||
Layout(
|
||||
content = pictureInPictureSlot,
|
||||
@@ -177,8 +216,11 @@ private fun PipLayer(
|
||||
val pictureInPictureConstraints: Constraints = when (localRenderState) {
|
||||
WebRtcLocalRenderState.GONE, WebRtcLocalRenderState.SMALLER_RECTANGLE, WebRtcLocalRenderState.LARGE, WebRtcLocalRenderState.LARGE_NO_VIDEO, WebRtcLocalRenderState.FOCUSED -> constraints
|
||||
WebRtcLocalRenderState.SMALL_RECTANGLE, WebRtcLocalRenderState.EXPANDED -> {
|
||||
val shouldOffset = bottomInsetPx > 0 && looseConstraints.maxWidth - pipSizePx.width - pipSizePx.width - bottomSheetWidthPx < 0
|
||||
looseConstraints.offset(vertical = if (shouldOffset) -bottomInsetPx else 0)
|
||||
// Check if there's enough space on either side of the centered content (bars/sheet)
|
||||
val spaceOnEachSide = (looseConstraints.maxWidth - centeredContentWidthPx) / 2
|
||||
val shouldOffset = centeredContentWidthPx > 0 && spaceOnEachSide < pipSizePx.width
|
||||
val offsetAmount = bottomInsetPx + barsHeightPx
|
||||
looseConstraints.offset(vertical = if (shouldOffset) -offsetAmount else 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user