From f389eae8684e334c7faddf86467245ca56398eea Mon Sep 17 00:00:00 2001 From: bxdxnn <267911624+bxdxnn@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:46:18 +0300 Subject: [PATCH] Make media captions scrollable (#6498) --- .../impl/viewer/MediaViewerStateProvider.kt | 24 +++++++++++ .../impl/viewer/MediaViewerView.kt | 43 ++++++++++++++++--- ...ewer.impl.viewer_MediaViewerView_17_en.png | 3 ++ 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.viewer_MediaViewerView_17_en.png diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerStateProvider.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerStateProvider.kt index 85aecc41a8..b1a2bde350 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerStateProvider.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerStateProvider.kt @@ -29,6 +29,14 @@ import io.element.android.libraries.mediaviewer.impl.details.aMediaDeleteConfirm import io.element.android.libraries.mediaviewer.impl.details.aMediaDetailsBottomSheetState import kotlinx.collections.immutable.toImmutableList +private const val LONG_CAPTION = "This is a very long caption that should be scrollable in the media viewer. " + + "It contains multiple lines of text to demonstrate the scrolling behavior. " + + "Line 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Line 2: Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Line 3: Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. " + + "Line 4: Duis aute irure dolor in reprehenderit in voluptate velit esse cillum. " + + "Line 5: Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia." + open class MediaViewerStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( @@ -170,6 +178,22 @@ open class MediaViewerStateProvider : PreviewParameterProvider ) ) ), + anImageMediaInfo( + senderName = "Alice", + dateSent = "21 NOV, 2024", + caption = LONG_CAPTION, + ).let { + aMediaViewerState( + listOf( + aMediaViewerPageData( + downloadedMedia = AsyncData.Success( + LocalMedia(Uri.EMPTY, it) + ), + mediaInfo = it, + ) + ) + ) + }, ) } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt index 7439909330..e5bed86eee 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt @@ -20,10 +20,13 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.TopAppBarDefaults @@ -39,6 +42,7 @@ import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.onSizeChanged @@ -538,19 +542,44 @@ private fun MediaViewerBottomBar( if (showDivider) { HorizontalDivider() } - Text( + val scrollState = rememberScrollState() + val showBottomShadow = scrollState.value < scrollState.maxValue + Box( modifier = Modifier .fillMaxWidth() - .padding(16.dp), - text = caption, - maxLines = 5, - overflow = TextOverflow.Ellipsis, - style = ElementTheme.typography.fontBodyLgRegular, - ) + .heightIn(max = maxCaptionHeight), + ) { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + .verticalScroll(scrollState), + text = caption, + style = ElementTheme.typography.fontBodyLgRegular, + ) + if (showBottomShadow) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + .align(Alignment.BottomCenter) + .background( + brush = Brush.verticalGradient( + colors = listOf( + Color.Transparent, + bgCanvasWithTransparency, + ), + ), + ), + ) + } + } } } } +private val maxCaptionHeight = 200.dp + @Composable private fun ThumbnailView( thumbnailSource: MediaSource?, diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.viewer_MediaViewerView_17_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.viewer_MediaViewerView_17_en.png new file mode 100644 index 0000000000..dc06b5afc9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.viewer_MediaViewerView_17_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e353d24c2b9b49abaa11e064b1581215ad65154d0e67372fe24684ba2695a0e +size 442063