Fix ContentErrorView not calculating its text size synchronously (#7281)

It was using a `LaunchedEffect` instead of relying on the `Text(onTextLayout)` parameter.
This commit is contained in:
Jorge Martin Espinosa
2026-07-27 18:15:33 +02:00
committed by GitHub
parent bbb83c2ff0
commit d8b01cf3e7
@@ -9,26 +9,17 @@ package io.element.android.libraries.matrix.ui.media.contentvalidation
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
@@ -41,7 +32,6 @@ internal fun ContentErrorView(
contentPadding: PaddingValues = PaddingValues.Zero, contentPadding: PaddingValues = PaddingValues.Zero,
onTextLayout: ((TextLayoutResult) -> Unit)? = null, onTextLayout: ((TextLayoutResult) -> Unit)? = null,
) { ) {
val updatedOnTextLayout by rememberUpdatedState(onTextLayout)
Row( Row(
modifier = modifier modifier = modifier
.background(color = ElementTheme.colors.bgCriticalSubtle) .background(color = ElementTheme.colors.bgCriticalSubtle)
@@ -61,33 +51,12 @@ internal fun ContentErrorView(
color = ElementTheme.colors.textCriticalPrimary, color = ElementTheme.colors.textCriticalPrimary,
style = ElementTheme.typography.fontBodyMdMedium, style = ElementTheme.typography.fontBodyMdMedium,
) )
val textMeasurer = rememberTextMeasurer() Text(
val textContent = remember(message) { text = message,
movableContentOf( color = ElementTheme.colors.textSecondary,
@Composable { style = ElementTheme.typography.fontBodySmRegular,
Text( onTextLayout = onTextLayout,
text = message, )
color = ElementTheme.colors.textSecondary,
style = ElementTheme.typography.fontBodySmRegular,
)
}
)
}
// BoxWithConstraints is needed to be able to calculate the text layout in the current constraints, so we can pass it to the onTextLayout callback.
// However, this can't be used inside a SubComposeLayout (like the one in the text composer), so we only use it when the onTextLayout callback
// is provided.
if (updatedOnTextLayout != null) {
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
LaunchedEffect(message) {
updatedOnTextLayout?.invoke(textMeasurer.measure(message, overflow = TextOverflow.Visible, constraints = constraints))
}
textContent()
}
} else {
textContent()
}
} }
} }
} }