Merge pull request #5835 from element-hq/feature/bma/limitComposerHeight
Limit composer height dynamically
This commit is contained in:
commit
9e71e2283b
3 changed files with 16 additions and 36 deletions
|
|
@ -29,10 +29,15 @@ import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.Role
|
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.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.text.toAnnotatedString
|
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.BottomSheetDragHandle
|
||||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
|
@ -129,6 +135,8 @@ fun MessagesView(
|
||||||
|
|
||||||
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
|
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
|
// This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose
|
||||||
val localView = LocalView.current
|
val localView = LocalView.current
|
||||||
|
|
||||||
|
|
@ -179,7 +187,13 @@ fun MessagesView(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.imePadding()
|
.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 = {
|
content = {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
contentWindowInsets = WindowInsets.statusBars,
|
contentWindowInsets = WindowInsets.statusBars,
|
||||||
|
|
@ -313,7 +327,7 @@ fun MessagesView(
|
||||||
} else {
|
} else {
|
||||||
RectangleShape
|
RectangleShape
|
||||||
},
|
},
|
||||||
maxBottomSheetContentHeight = 360.dp,
|
maxBottomSheetContentHeight = maxComposerHeightPx.toDp(),
|
||||||
)
|
)
|
||||||
|
|
||||||
ActionListView(
|
ActionListView(
|
||||||
|
|
|
||||||
|
|
@ -77,28 +77,9 @@ fun ExpandableBottomSheetLayout(
|
||||||
var calculatedMaxBottomContentHeightPx by remember(maxBottomContentHeightPx) { mutableIntStateOf(maxBottomContentHeightPx) }
|
var calculatedMaxBottomContentHeightPx by remember(maxBottomContentHeightPx) { mutableIntStateOf(maxBottomContentHeightPx) }
|
||||||
val animatable = remember { Animatable(0f) }
|
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) {
|
LaunchedEffect(animatable.value) {
|
||||||
if (animatable.isRunning && animatable.value != animatable.targetValue) {
|
if (animatable.isRunning && animatable.value != animatable.targetValue) {
|
||||||
currentBottomContentHeightPx = animatable.value.roundToInt()
|
currentBottomContentHeightPx = animatable.value.roundToInt()
|
||||||
state.internalDraggingPercentage = calculatePercentage(
|
|
||||||
currentPos = currentBottomContentHeightPx,
|
|
||||||
minPos = minBottomContentHeightPx,
|
|
||||||
maxPos = calculatedMaxBottomContentHeightPx,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,11 +103,6 @@ fun ExpandableBottomSheetLayout(
|
||||||
minBottomContentHeightPx -> ExpandableBottomSheetLayoutState.Position.COLLAPSED
|
minBottomContentHeightPx -> ExpandableBottomSheetLayoutState.Position.COLLAPSED
|
||||||
else -> ExpandableBottomSheetLayoutState.Position.DRAGGING
|
else -> ExpandableBottomSheetLayoutState.Position.DRAGGING
|
||||||
}
|
}
|
||||||
state.internalDraggingPercentage = calculatePercentage(
|
|
||||||
currentPos = newHeight,
|
|
||||||
minPos = minBottomContentHeightPx,
|
|
||||||
maxPos = calculatedMaxBottomContentHeightPx,
|
|
||||||
)
|
|
||||||
currentBottomContentHeightPx = newHeight
|
currentBottomContentHeightPx = newHeight
|
||||||
},
|
},
|
||||||
onDragEnd = {
|
onDragEnd = {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ package io.element.android.libraries.designsystem.components
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
|
@ -32,21 +31,12 @@ fun rememberExpandableBottomSheetLayoutState(): ExpandableBottomSheetLayoutState
|
||||||
@Stable
|
@Stable
|
||||||
class ExpandableBottomSheetLayoutState {
|
class ExpandableBottomSheetLayoutState {
|
||||||
internal var internalPosition: Position by mutableStateOf(Position.COLLAPSED)
|
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.
|
* The current position of the bottom sheet layout.
|
||||||
*/
|
*/
|
||||||
val position get() = internalPosition
|
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.
|
* The position of the bottom sheet layout.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue