android, desktop: fix video preview expanding into empty black area (#7286)

* android, desktop: fix video preview expanding into empty black area

The video message box (CHAT_IMAGE_LAYOUT_ID) never gave itself a definite
height - it took the height of its tallest child. That child is the player
surface, which has no stable intrinsic height until playback starts: on
Android an unprepared StyledPlayerView reports no video size, so its
AspectRatioFrameLayout (RESIZE_MODE_FIXED_WIDTH, aspect 0) does not shrink.

Before #6726 this was masked: the box was measured with unbounded height, so
the surface collapsed to 0. #6726 bounded the box to 2.33x width to constrain
tall images, and the unprepared surface then expanded to fill that height,
showing as a long empty black strip below the preview once a video downloads.

Give the box a definite size from the preview aspect ratio, mirroring
CIImageView. Height follows the measured (clamped) width via Modifier.layout
so wide videos on narrow screens don't leave an empty strip (the #7223 fix).

* plans: justify video preview black-area fix
This commit is contained in:
Narasimha-sc
2026-07-22 13:11:54 +01:00
committed by GitHub
parent ab691a4f82
commit 8de39c25de
2 changed files with 85 additions and 1 deletions
@@ -25,6 +25,7 @@ import chat.simplex.common.views.chat.chatViewScrollState
import dev.icerock.moko.resources.StringResource
import java.io.File
import java.net.URI
import kotlin.math.roundToInt
@Composable
fun CIVideoView(
@@ -38,12 +39,25 @@ fun CIVideoView(
receiveFile: (Long) -> Unit
) {
val blurred = remember { mutableStateOf(appPrefs.privacyMediaBlurRadius.get() > 0) }
val preview = remember(image) { base64ToBitmap(image) }
Box(
Modifier.layoutId(CHAT_IMAGE_LAYOUT_ID)
.then(
if (!smallView) {
val w = if (preview.width * 0.97 <= preview.height) videoViewFullWidth(LocalWindowWidth()) * 0.75f else DEFAULT_MAX_IMAGE_WIDTH
// Size the media box from the preview aspect ratio (as CIImageView does), else the unprepared player surface
// expands to PriorityLayout's max height and shows as a black strip; height tracks the clamped width (#7223).
Modifier.width(w).layout { measurable, constraints ->
val width = constraints.maxWidth.coerceAtMost(w.roundToPx().coerceAtLeast(0))
val height = (width * (preview.height.toFloat() / preview.width.toFloat()).coerceAtMost(2.33f)).roundToInt().coerceAtMost(constraints.maxHeight)
val placeable = measurable.measure(Constraints.fixed(width, height))
layout(width, height) { placeable.place(0, 0) }
}
} else Modifier
)
.desktopModifyBlurredState(!smallView, blurred, showMenu),
contentAlignment = Alignment.TopEnd
) {
val preview = remember(image) { base64ToBitmap(image) }
val filePath = remember(file, CIFile.cachedRemoteFileRequests.toList()) { mutableStateOf(getLoadedFilePath(file)) }
val sizeMultiplier = if (smallView) 0.38f else 1f
if (chatModel.connectedToRemote()) {