mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 06:55:41 +00:00
Render media captions formatting in the media viewer (#6729)
* Render media captions formatting in the media viewer * Update screenshots * Trigger actions * Remove unused imports and reformat code --------- Co-authored-by: ElementBot <android@element.io> Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
+1
@@ -646,6 +646,7 @@ class MessagesFlowNode(
|
|||||||
filename = content.filename,
|
filename = content.filename,
|
||||||
fileSize = content.fileSize,
|
fileSize = content.fileSize,
|
||||||
caption = content.caption,
|
caption = content.caption,
|
||||||
|
formattedCaption = content.formattedCaption,
|
||||||
mimeType = content.mimeType,
|
mimeType = content.mimeType,
|
||||||
formattedFileSize = content.formattedFileSize,
|
formattedFileSize = content.formattedFileSize,
|
||||||
fileExtension = content.fileExtension,
|
fileExtension = content.fileExtension,
|
||||||
|
|||||||
+14
@@ -17,6 +17,7 @@ import kotlinx.parcelize.Parcelize
|
|||||||
data class MediaInfo(
|
data class MediaInfo(
|
||||||
val filename: String,
|
val filename: String,
|
||||||
val caption: String?,
|
val caption: String?,
|
||||||
|
val formattedCaption: CharSequence? = null,
|
||||||
val mimeType: String,
|
val mimeType: String,
|
||||||
val fileSize: Long?,
|
val fileSize: Long?,
|
||||||
val formattedFileSize: String,
|
val formattedFileSize: String,
|
||||||
@@ -33,6 +34,7 @@ data class MediaInfo(
|
|||||||
fun anImageMediaInfo(
|
fun anImageMediaInfo(
|
||||||
senderId: UserId? = UserId("@alice:server.org"),
|
senderId: UserId? = UserId("@alice:server.org"),
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -40,6 +42,7 @@ fun anImageMediaInfo(
|
|||||||
filename = "an image file.jpg",
|
filename = "an image file.jpg",
|
||||||
fileSize = 4 * 1024 * 1024,
|
fileSize = 4 * 1024 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.Jpeg,
|
mimeType = MimeTypes.Jpeg,
|
||||||
formattedFileSize = "4MB",
|
formattedFileSize = "4MB",
|
||||||
fileExtension = "jpg",
|
fileExtension = "jpg",
|
||||||
@@ -54,6 +57,7 @@ fun anImageMediaInfo(
|
|||||||
|
|
||||||
fun aVideoMediaInfo(
|
fun aVideoMediaInfo(
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -62,6 +66,7 @@ fun aVideoMediaInfo(
|
|||||||
filename = "a video file.mp4",
|
filename = "a video file.mp4",
|
||||||
fileSize = 14 * 1024 * 1024,
|
fileSize = 14 * 1024 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.Mp4,
|
mimeType = MimeTypes.Mp4,
|
||||||
formattedFileSize = "14MB",
|
formattedFileSize = "14MB",
|
||||||
fileExtension = "mp4",
|
fileExtension = "mp4",
|
||||||
@@ -77,6 +82,7 @@ fun aVideoMediaInfo(
|
|||||||
fun aPdfMediaInfo(
|
fun aPdfMediaInfo(
|
||||||
filename: String = "a pdf file.pdf",
|
filename: String = "a pdf file.pdf",
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -84,6 +90,7 @@ fun aPdfMediaInfo(
|
|||||||
filename = filename,
|
filename = filename,
|
||||||
fileSize = 23 * 1024 * 1024,
|
fileSize = 23 * 1024 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.Pdf,
|
mimeType = MimeTypes.Pdf,
|
||||||
formattedFileSize = "23MB",
|
formattedFileSize = "23MB",
|
||||||
fileExtension = "pdf",
|
fileExtension = "pdf",
|
||||||
@@ -105,6 +112,7 @@ fun anApkMediaInfo(
|
|||||||
filename = "an apk file.apk",
|
filename = "an apk file.apk",
|
||||||
fileSize = 50 * 1024 * 1024,
|
fileSize = 50 * 1024 * 1024,
|
||||||
caption = null,
|
caption = null,
|
||||||
|
formattedCaption = null,
|
||||||
mimeType = MimeTypes.Apk,
|
mimeType = MimeTypes.Apk,
|
||||||
formattedFileSize = "50MB",
|
formattedFileSize = "50MB",
|
||||||
fileExtension = "apk",
|
fileExtension = "apk",
|
||||||
@@ -120,6 +128,7 @@ fun anApkMediaInfo(
|
|||||||
fun anAudioMediaInfo(
|
fun anAudioMediaInfo(
|
||||||
filename: String = "an audio file.mp3",
|
filename: String = "an audio file.mp3",
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -129,6 +138,7 @@ fun anAudioMediaInfo(
|
|||||||
filename = filename,
|
filename = filename,
|
||||||
fileSize = 7 * 1024 * 1024,
|
fileSize = 7 * 1024 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.Mp3,
|
mimeType = MimeTypes.Mp3,
|
||||||
formattedFileSize = "7MB",
|
formattedFileSize = "7MB",
|
||||||
fileExtension = "mp3",
|
fileExtension = "mp3",
|
||||||
@@ -144,6 +154,7 @@ fun anAudioMediaInfo(
|
|||||||
fun aVoiceMediaInfo(
|
fun aVoiceMediaInfo(
|
||||||
filename: String = "a voice file.ogg",
|
filename: String = "a voice file.ogg",
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -153,6 +164,7 @@ fun aVoiceMediaInfo(
|
|||||||
filename = filename,
|
filename = filename,
|
||||||
fileSize = 3 * 1024 * 1024,
|
fileSize = 3 * 1024 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.Ogg,
|
mimeType = MimeTypes.Ogg,
|
||||||
formattedFileSize = "3MB",
|
formattedFileSize = "3MB",
|
||||||
fileExtension = "ogg",
|
fileExtension = "ogg",
|
||||||
@@ -168,6 +180,7 @@ fun aVoiceMediaInfo(
|
|||||||
fun aTxtMediaInfo(
|
fun aTxtMediaInfo(
|
||||||
filename: String = "a text file.txt",
|
filename: String = "a text file.txt",
|
||||||
caption: String? = null,
|
caption: String? = null,
|
||||||
|
formattedCaption: CharSequence? = null,
|
||||||
senderName: String? = null,
|
senderName: String? = null,
|
||||||
dateSent: String? = null,
|
dateSent: String? = null,
|
||||||
dateSentFull: String? = null,
|
dateSentFull: String? = null,
|
||||||
@@ -175,6 +188,7 @@ fun aTxtMediaInfo(
|
|||||||
filename = filename,
|
filename = filename,
|
||||||
fileSize = 2 * 1024,
|
fileSize = 2 * 1024,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = formattedCaption,
|
||||||
mimeType = MimeTypes.PlainText,
|
mimeType = MimeTypes.PlainText,
|
||||||
formattedFileSize = "2kB",
|
formattedFileSize = "2kB",
|
||||||
fileExtension = "txt",
|
fileExtension = "txt",
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ android {
|
|||||||
setupDependencyInjection()
|
setupDependencyInjection()
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(libs.matrix.richtexteditor.compose)
|
||||||
|
implementation(libs.matrix.richtexteditor)
|
||||||
|
implementation(projects.libraries.textcomposer.impl)
|
||||||
implementation(libs.coroutines.core)
|
implementation(libs.coroutines.core)
|
||||||
implementation(libs.coil.compose)
|
implementation(libs.coil.compose)
|
||||||
implementation(libs.androidx.media3.exoplayer)
|
implementation(libs.androidx.media3.exoplayer)
|
||||||
|
|||||||
+1
@@ -32,6 +32,7 @@ class DefaultMediaViewerEntryPoint : MediaViewerEntryPoint {
|
|||||||
filename = filename,
|
filename = filename,
|
||||||
fileSize = null,
|
fileSize = null,
|
||||||
caption = null,
|
caption = null,
|
||||||
|
formattedCaption = null,
|
||||||
mimeType = mimeType,
|
mimeType = mimeType,
|
||||||
formattedFileSize = "",
|
formattedFileSize = "",
|
||||||
fileExtension = "",
|
fileExtension = "",
|
||||||
|
|||||||
+6
@@ -98,6 +98,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
@@ -118,6 +119,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
@@ -139,6 +141,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
@@ -160,6 +163,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
@@ -181,6 +185,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
@@ -202,6 +207,7 @@ class EventItemFactory(
|
|||||||
filename = type.filename,
|
filename = type.filename,
|
||||||
fileSize = type.info?.size,
|
fileSize = type.info?.size,
|
||||||
caption = type.caption,
|
caption = type.caption,
|
||||||
|
formattedCaption = type.formattedCaption?.body,
|
||||||
mimeType = type.info?.mimetype.orEmpty(),
|
mimeType = type.info?.mimetype.orEmpty(),
|
||||||
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
formattedFileSize = type.info?.size?.let { fileSizeFormatter.format(it) }.orEmpty(),
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
fileExtension = fileExtensionExtractor.extractFromName(type.filename),
|
||||||
|
|||||||
+1
@@ -97,6 +97,7 @@ class AndroidLocalMediaFactory(
|
|||||||
filename = fileName,
|
filename = fileName,
|
||||||
fileSize = fileSize,
|
fileSize = fileSize,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
formattedCaption = null,
|
||||||
formattedFileSize = calculatedFormattedFileSize,
|
formattedFileSize = calculatedFormattedFileSize,
|
||||||
fileExtension = fileExtension,
|
fileExtension = fileExtension,
|
||||||
senderId = senderId,
|
senderId = senderId,
|
||||||
|
|||||||
+80
@@ -195,6 +195,86 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
anImageMediaInfo(
|
||||||
|
senderName = "Bob",
|
||||||
|
dateSent = "22 NOV, 2024",
|
||||||
|
formattedCaption = "This is a <strong>bold</strong> caption",
|
||||||
|
).let {
|
||||||
|
aMediaViewerState(
|
||||||
|
listOf(
|
||||||
|
aMediaViewerPageData(
|
||||||
|
downloadedMedia = AsyncData.Success(
|
||||||
|
LocalMedia(Uri.EMPTY, it)
|
||||||
|
),
|
||||||
|
mediaInfo = it,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
anImageMediaInfo(
|
||||||
|
senderName = "Charlie",
|
||||||
|
dateSent = "23 NOV, 2024",
|
||||||
|
formattedCaption = "This is an <em>italic</em> caption",
|
||||||
|
).let {
|
||||||
|
aMediaViewerState(
|
||||||
|
listOf(
|
||||||
|
aMediaViewerPageData(
|
||||||
|
downloadedMedia = AsyncData.Success(
|
||||||
|
LocalMedia(Uri.EMPTY, it)
|
||||||
|
),
|
||||||
|
mediaInfo = it,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
anImageMediaInfo(
|
||||||
|
senderName = "Diana",
|
||||||
|
dateSent = "24 NOV, 2024",
|
||||||
|
formattedCaption = "This is a <code>code</code> caption",
|
||||||
|
).let {
|
||||||
|
aMediaViewerState(
|
||||||
|
listOf(
|
||||||
|
aMediaViewerPageData(
|
||||||
|
downloadedMedia = AsyncData.Success(
|
||||||
|
LocalMedia(Uri.EMPTY, it)
|
||||||
|
),
|
||||||
|
mediaInfo = it,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
anImageMediaInfo(
|
||||||
|
senderName = "Eve",
|
||||||
|
dateSent = "25 NOV, 2024",
|
||||||
|
formattedCaption = "<blockquote>This is a quote caption</blockquote>",
|
||||||
|
).let {
|
||||||
|
aMediaViewerState(
|
||||||
|
listOf(
|
||||||
|
aMediaViewerPageData(
|
||||||
|
downloadedMedia = AsyncData.Success(
|
||||||
|
LocalMedia(Uri.EMPTY, it)
|
||||||
|
),
|
||||||
|
mediaInfo = it,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
anImageMediaInfo(
|
||||||
|
senderName = "Frank",
|
||||||
|
dateSent = "26 NOV, 2024",
|
||||||
|
formattedCaption = "This caption has <strong>bold</strong>, <em>italic</em>, and <code>code</code> formatting.",
|
||||||
|
).let {
|
||||||
|
aMediaViewerState(
|
||||||
|
listOf(
|
||||||
|
aMediaViewerPageData(
|
||||||
|
downloadedMedia = AsyncData.Success(
|
||||||
|
LocalMedia(Uri.EMPTY, it)
|
||||||
|
),
|
||||||
|
mediaInfo = it,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-10
@@ -31,8 +31,11 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.LinearProgressIndicator
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -59,10 +62,12 @@ import androidx.compose.ui.tooling.preview.Devices
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.text.toSpannable
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
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
|
||||||
import io.element.android.features.viewfolder.api.TextFileViewer
|
import io.element.android.features.viewfolder.api.TextFileViewer
|
||||||
|
import io.element.android.libraries.androidutils.text.safeLinkify
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.audio.api.AudioFocus
|
import io.element.android.libraries.audio.api.AudioFocus
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo
|
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo
|
||||||
@@ -91,7 +96,9 @@ import io.element.android.libraries.mediaviewer.impl.local.LocalMediaView
|
|||||||
import io.element.android.libraries.mediaviewer.impl.local.PlayableState
|
import io.element.android.libraries.mediaviewer.impl.local.PlayableState
|
||||||
import io.element.android.libraries.mediaviewer.impl.local.rememberLocalMediaViewState
|
import io.element.android.libraries.mediaviewer.impl.local.rememberLocalMediaViewState
|
||||||
import io.element.android.libraries.mediaviewer.impl.util.bgCanvasWithTransparency
|
import io.element.android.libraries.mediaviewer.impl.util.bgCanvasWithTransparency
|
||||||
|
import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
import io.element.android.wysiwyg.compose.EditorStyledText
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import me.saket.telephoto.zoomable.OverzoomEffect
|
import me.saket.telephoto.zoomable.OverzoomEffect
|
||||||
import me.saket.telephoto.zoomable.ZoomSpec
|
import me.saket.telephoto.zoomable.ZoomSpec
|
||||||
@@ -242,6 +249,7 @@ fun MediaViewerView(
|
|||||||
MediaViewerBottomBar(
|
MediaViewerBottomBar(
|
||||||
showDivider = dataForPage.mediaInfo.mimeType.isMimeTypeVideo(),
|
showDivider = dataForPage.mediaInfo.mimeType.isMimeTypeVideo(),
|
||||||
caption = dataForPage.mediaInfo.caption,
|
caption = dataForPage.mediaInfo.caption,
|
||||||
|
formattedCaption = dataForPage.mediaInfo.formattedCaption,
|
||||||
onHeightChange = { bottomPaddingInPixels = it },
|
onHeightChange = { bottomPaddingInPixels = it },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -545,6 +553,7 @@ private fun MediaViewerTopBar(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun MediaViewerBottomBar(
|
private fun MediaViewerBottomBar(
|
||||||
caption: String?,
|
caption: String?,
|
||||||
|
formattedCaption: CharSequence?,
|
||||||
showDivider: Boolean,
|
showDivider: Boolean,
|
||||||
onHeightChange: (Int) -> Unit,
|
onHeightChange: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@@ -557,7 +566,7 @@ private fun MediaViewerBottomBar(
|
|||||||
onHeightChange(it.height)
|
onHeightChange(it.height)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (caption != null) {
|
if (caption != null || formattedCaption != null) {
|
||||||
if (showDivider) {
|
if (showDivider) {
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
}
|
}
|
||||||
@@ -568,15 +577,28 @@ private fun MediaViewerBottomBar(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.heightIn(max = if (hasCompactHeightWindowSize()) maxCaptionHeightLandscape else maxCaptionHeightPortrait),
|
.heightIn(max = if (hasCompactHeightWindowSize()) maxCaptionHeightLandscape else maxCaptionHeightPortrait),
|
||||||
) {
|
) {
|
||||||
Text(
|
val textToRender = when {
|
||||||
modifier = Modifier
|
formattedCaption != null -> formattedCaption
|
||||||
.fillMaxWidth()
|
caption != null -> caption.safeLinkify().toSpannable()
|
||||||
.padding(16.dp)
|
else -> null
|
||||||
.verticalScroll(scrollState)
|
}
|
||||||
.navigationBarsPadding(),
|
if (textToRender != null) {
|
||||||
text = caption,
|
CompositionLocalProvider(
|
||||||
style = ElementTheme.typography.fontBodyLgRegular,
|
LocalContentColor provides ElementTheme.colors.textPrimary,
|
||||||
)
|
LocalTextStyle provides ElementTheme.typography.fontBodyLgRegular
|
||||||
|
) {
|
||||||
|
EditorStyledText(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(scrollState)
|
||||||
|
.navigationBarsPadding(),
|
||||||
|
text = textToRender,
|
||||||
|
style = ElementRichTextEditorStyle.textStyle(),
|
||||||
|
releaseOnDetach = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (showBottomShadow) {
|
if (showBottomShadow) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
+1
@@ -235,6 +235,7 @@ class TimelineMediaGalleryDataSourceTest {
|
|||||||
filename = "body.jpg",
|
filename = "body.jpg",
|
||||||
fileSize = 888L,
|
fileSize = 888L,
|
||||||
caption = "body.jpg caption",
|
caption = "body.jpg caption",
|
||||||
|
formattedCaption = "formatted",
|
||||||
mimeType = MimeTypes.Jpeg,
|
mimeType = MimeTypes.Jpeg,
|
||||||
formattedFileSize = "888 Bytes",
|
formattedFileSize = "888 Bytes",
|
||||||
fileExtension = "jpg",
|
fileExtension = "jpg",
|
||||||
|
|||||||
+1
@@ -41,6 +41,7 @@ class FakeLocalMediaFactory(
|
|||||||
filename = safeName,
|
filename = safeName,
|
||||||
fileSize = null,
|
fileSize = null,
|
||||||
caption = null,
|
caption = null,
|
||||||
|
formattedCaption = null,
|
||||||
mimeType = mimeType ?: fallbackMimeType,
|
mimeType = mimeType ?: fallbackMimeType,
|
||||||
formattedFileSize = formattedFileSize ?: fallbackFileSize,
|
formattedFileSize = formattedFileSize ?: fallbackFileSize,
|
||||||
fileExtension = fileExtensionExtractor.extractFromName(safeName),
|
fileExtension = fileExtensionExtractor.extractFromName(safeName),
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:178de2176a3932665897486ecbee622083af2d5939f4f1f7f0bdc4667a61e36a
|
||||||
|
size 668061
|
||||||
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:e7ac632f2062aa4a13ee46fd2fef6d9e6be25270f4790247131231163670cbe6
|
||||||
|
size 670668
|
||||||
BIN
Binary file not shown.
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f6870b9c1a5aad4257aa4bd7b13d0be5bea281778061d71c711495aadfaafdb8
|
oid sha256:f72964447f2fa66e8df38fcff4a84ada1cf62e1646a2e8a00c61f8f151abfa8c
|
||||||
size 206057
|
size 206507
|
||||||
|
|||||||
LFS
BIN
Binary file not shown.
LFS
BIN
Binary file not shown.
LFS
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b544362587868c37edc424b675c6758e7ffcff359fa12c1cfcb874a0502e25de
|
||||||
|
size 397284
|
||||||
LFS
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7b6623e0e784a93d6a3aa220b620efe7d1f9e040aedac7f34d01b24262fe101b
|
||||||
|
size 401770
|
||||||
LFS
BIN
Binary file not shown.
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c0249f33aca3e50713c87a3826e71985991f0996998132c42a374c6169800023
|
oid sha256:e3a148746b4f7428688a634f2b1299f0393bf669a665c94fa9af12d7839e72a0
|
||||||
size 130728
|
size 130834
|
||||||
|
|||||||
Reference in New Issue
Block a user