Fix crash when starting a DM (#6419)

`AnchoredDraggable.requireOffset` was called before it was populated when displaying  `CreateDmConfirmationBottomSheet`, because the keyboard and the bottom sheet were causing conflicting animations related to the insets.

Hiding the keyboard before displaying the bottom sheet seems to fix the issue, and `skipPartiallyExpanded` results in a better UX (and also worked around the issue by itself).
This commit is contained in:
Jorge Martin Espinosa
2026-03-23 16:00:04 +01:00
committed by GitHub
parent 93ab9f43dc
commit 9074692189
3 changed files with 44 additions and 4 deletions

View File

@@ -9,12 +9,15 @@
package io.element.android.libraries.androidutils.ui
import android.os.Build
import android.os.Bundle
import android.os.ResultReceiver
import android.view.View
import android.view.ViewTreeObserver
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager
import androidx.core.content.getSystemService
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlin.coroutines.resume
fun View.hideKeyboard() {
@@ -22,6 +25,32 @@ fun View.hideKeyboard() {
imm?.hideSoftInputFromWindow(windowToken, 0)
}
suspend fun View.hideKeyboardAndAwaitAnimation() {
val imm = context?.getSystemService<InputMethodManager>()
val mutex = Mutex()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
setOnApplyWindowInsetsListener { view, insets ->
if (!insets.isVisible(WindowInsets.Type.ime())) {
mutex.unlock()
}
insets
}
imm?.hideSoftInputFromWindow(windowToken, 0)
} else {
@Suppress("DEPRECATION")
imm?.hideSoftInputFromWindow(windowToken, 0, object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
if (resultCode == InputMethodManager.RESULT_UNCHANGED_HIDDEN ||
resultCode == InputMethodManager.RESULT_HIDDEN) {
mutex.unlock()
}
}
})
}
mutex.lock()
}
fun View.showKeyboard(andRequestFocus: Boolean = false) {
if (andRequestFocus) {
requestFocus()

View File

@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -54,14 +55,14 @@ fun CreateDmConfirmationBottomSheet(
ModalBottomSheet(
modifier = modifier,
onDismissRequest = onDismiss,
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
.padding(top = 24.dp, bottom = 16.dp, start = 16.dp, end = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.height(24.dp))
Avatar(
avatarData = matrixUser.getAvatarData(AvatarSize.DmCreationConfirmation),
avatarType = AvatarType.User,
@@ -93,7 +94,6 @@ fun CreateDmConfirmationBottomSheet(
onClick = onDismiss,
text = stringResource(CommonStrings.action_cancel),
)
Spacer(modifier = Modifier.height(16.dp))
}
}
}