Merge pull request #5835 from element-hq/feature/bma/limitComposerHeight

Limit composer height dynamically
This commit is contained in:
Benoit Marty
2025-12-04 09:49:19 +01:00
committed by GitHub
3 changed files with 16 additions and 36 deletions

View File

@@ -29,10 +29,15 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
@@ -82,6 +87,7 @@ import io.element.android.libraries.designsystem.components.rememberExpandableBo
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toAnnotatedString
import io.element.android.libraries.designsystem.text.toDp
import io.element.android.libraries.designsystem.theme.components.BottomSheetDragHandle
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
@@ -129,6 +135,8 @@ fun MessagesView(
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
var maxComposerHeightPx by remember { mutableIntStateOf(120) }
// This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose
val localView = LocalView.current
@@ -179,7 +187,13 @@ fun MessagesView(
modifier = modifier
.fillMaxSize()
.imePadding()
.systemBarsPadding(),
.systemBarsPadding()
.onSizeChanged { size ->
// Let the composer takes at max half of the available height.
// The value will be different if the soft keyboard is displayed
// or not.
maxComposerHeightPx = (size.height * 0.5f).toInt()
},
content = {
Scaffold(
contentWindowInsets = WindowInsets.statusBars,
@@ -313,7 +327,7 @@ fun MessagesView(
} else {
RectangleShape
},
maxBottomSheetContentHeight = 360.dp,
maxBottomSheetContentHeight = maxComposerHeightPx.toDp(),
)
ActionListView(

View File

@@ -77,28 +77,9 @@ fun ExpandableBottomSheetLayout(
var calculatedMaxBottomContentHeightPx by remember(maxBottomContentHeightPx) { mutableIntStateOf(maxBottomContentHeightPx) }
val animatable = remember { Animatable(0f) }
fun calculatePercentage(currentPos: Int, minPos: Int, maxPos: Int): Float {
val currentProgress = currentPos - minPos
if (currentProgress < 0) {
Timber.e("Invalid current progress: $currentProgress, minPos: $minPos, maxPos: $maxPos")
return 0f
}
val total = (maxPos - minPos).toFloat()
if (total <= 0) {
Timber.e("Invalid total space: $total, minPos: $minPos, maxPos: $maxPos")
return 0f
}
return currentProgress / total
}
LaunchedEffect(animatable.value) {
if (animatable.isRunning && animatable.value != animatable.targetValue) {
currentBottomContentHeightPx = animatable.value.roundToInt()
state.internalDraggingPercentage = calculatePercentage(
currentPos = currentBottomContentHeightPx,
minPos = minBottomContentHeightPx,
maxPos = calculatedMaxBottomContentHeightPx,
)
}
}
@@ -122,11 +103,6 @@ fun ExpandableBottomSheetLayout(
minBottomContentHeightPx -> ExpandableBottomSheetLayoutState.Position.COLLAPSED
else -> ExpandableBottomSheetLayoutState.Position.DRAGGING
}
state.internalDraggingPercentage = calculatePercentage(
currentPos = newHeight,
minPos = minBottomContentHeightPx,
maxPos = calculatedMaxBottomContentHeightPx,
)
currentBottomContentHeightPx = newHeight
},
onDragEnd = {

View File

@@ -11,7 +11,6 @@ package io.element.android.libraries.designsystem.components
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -32,21 +31,12 @@ fun rememberExpandableBottomSheetLayoutState(): ExpandableBottomSheetLayoutState
@Stable
class ExpandableBottomSheetLayoutState {
internal var internalPosition: Position by mutableStateOf(Position.COLLAPSED)
internal var internalDraggingPercentage: Float by mutableFloatStateOf(
if (internalPosition == Position.EXPANDED) 1f else 0f
)
/**
* The current position of the bottom sheet layout.
*/
val position get() = internalPosition
/**
* The percentage of the bottom sheet layout that is currently being dragged.
* This value ranges from `0f` for [Position.COLLAPSED] to `1f` for [Position.EXPANDED].
*/
val draggingPercentage = internalDraggingPercentage
/**
* The position of the bottom sheet layout.
*/