Merge pull request #1774 from vector-im/feature/bma/imageThumbnail
Improve rendering of `AttachmentThumbnail` when thumbnailSource is not provided
This commit is contained in:
@@ -311,7 +311,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||
val textContent = messageSummaryFormatter.format(targetEvent)
|
||||
val attachmentThumbnailInfo = when (targetEvent.content) {
|
||||
is TimelineItemImageContent -> AttachmentThumbnailInfo(
|
||||
thumbnailSource = targetEvent.content.thumbnailSource,
|
||||
thumbnailSource = targetEvent.content.thumbnailSource ?: targetEvent.content.mediaSource,
|
||||
textContent = targetEvent.content.body,
|
||||
type = AttachmentThumbnailType.Image,
|
||||
blurHash = targetEvent.content.blurhash,
|
||||
|
||||
@@ -260,7 +260,7 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif
|
||||
AttachmentThumbnail(
|
||||
modifier = imageModifier,
|
||||
info = AttachmentThumbnailInfo(
|
||||
thumbnailSource = event.content.mediaSource,
|
||||
thumbnailSource = event.content.thumbnailSource ?: event.content.mediaSource,
|
||||
textContent = textContent,
|
||||
type = AttachmentThumbnailType.Image,
|
||||
blurHash = event.content.blurhash,
|
||||
|
||||
@@ -595,7 +595,7 @@ private fun attachmentThumbnailInfoForInReplyTo(inReplyTo: InReplyTo.Ready): Att
|
||||
val messageContent = inReplyTo.content as? MessageContent ?: return null
|
||||
return when (val type = messageContent.type) {
|
||||
is ImageMessageType -> AttachmentThumbnailInfo(
|
||||
thumbnailSource = type.info?.thumbnailSource,
|
||||
thumbnailSource = type.info?.thumbnailSource ?: type.source,
|
||||
textContent = messageContent.body,
|
||||
type = AttachmentThumbnailType.Image,
|
||||
blurHash = type.info?.blurhash,
|
||||
|
||||
@@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.media3.common.MimeTypes
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||
|
||||
open class TimelineItemImageContentProvider : PreviewParameterProvider<TimelineItemImageContent> {
|
||||
override val values: Sequence<TimelineItemImageContent>
|
||||
@@ -34,7 +35,7 @@ fun aTimelineItemImageContent() = TimelineItemImageContent(
|
||||
mediaSource = MediaSource(""),
|
||||
thumbnailSource = null,
|
||||
mimeType = MimeTypes.IMAGE_JPEG,
|
||||
blurhash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr",
|
||||
blurhash = A_BLUR_HASH,
|
||||
width = null,
|
||||
height = 300,
|
||||
aspectRatio = 0.5f,
|
||||
|
||||
@@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||
|
||||
open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineItemVideoContent> {
|
||||
override val values: Sequence<TimelineItemVideoContent>
|
||||
@@ -32,7 +33,7 @@ open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineI
|
||||
fun aTimelineItemVideoContent() = TimelineItemVideoContent(
|
||||
body = "Video.mp4",
|
||||
thumbnailSource = null,
|
||||
blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr",
|
||||
blurHash = A_BLUR_HASH,
|
||||
aspectRatio = 0.5f,
|
||||
duration = 100,
|
||||
videoSource = MediaSource(""),
|
||||
|
||||
@@ -20,18 +20,26 @@ import android.os.Parcelable
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.GraphicEq
|
||||
import androidx.compose.material.icons.outlined.Image
|
||||
import androidx.compose.material.icons.outlined.VideoCameraBack
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.components.BlurHashAsyncImage
|
||||
import io.element.android.libraries.designsystem.components.PinIcon
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
@@ -57,12 +65,26 @@ fun AttachmentThumbnail(
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = modifier,
|
||||
)
|
||||
} else if (info.blurHash != null) {
|
||||
BlurHashAsyncImage(
|
||||
model = null,
|
||||
blurHash = info.blurHash,
|
||||
contentDescription = info.textContent,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = modifier,
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = modifier.background(backgroundColor),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
when (info.type) {
|
||||
AttachmentThumbnailType.Image -> {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Image,
|
||||
contentDescription = info.textContent,
|
||||
)
|
||||
}
|
||||
AttachmentThumbnailType.Video -> {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.VideoCameraBack,
|
||||
@@ -92,8 +114,14 @@ fun AttachmentThumbnail(
|
||||
PinIcon(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
/*
|
||||
// For coherency across the app, we should us this instead. Waiting for design decision.
|
||||
Icon(
|
||||
resourceId = R.drawable.ic_september_location,
|
||||
contentDescription = info.textContent,
|
||||
)
|
||||
*/
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,3 +139,14 @@ data class AttachmentThumbnailInfo(
|
||||
val textContent: String? = null,
|
||||
val blurHash: String? = null,
|
||||
) : Parcelable
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun AttachmentThumbnailPreview(@PreviewParameter(AttachmentThumbnailInfoProvider::class) data: AttachmentThumbnailInfo) = ElementPreview {
|
||||
AttachmentThumbnail(
|
||||
data,
|
||||
modifier = Modifier
|
||||
.size(36.dp)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.ui.components
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
|
||||
open class AttachmentThumbnailInfoProvider : PreviewParameterProvider<AttachmentThumbnailInfo> {
|
||||
override val values: Sequence<AttachmentThumbnailInfo>
|
||||
get() = sequenceOf(
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Image),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Image, blurHash = A_BLUR_HASH),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Video),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Video, blurHash = A_BLUR_HASH),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Audio),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.File),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Location),
|
||||
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Voice),
|
||||
)
|
||||
}
|
||||
|
||||
fun anAttachmentThumbnailInfo(
|
||||
type: AttachmentThumbnailType,
|
||||
thumbnailSource: MediaSource? = null,
|
||||
textContent: String? = null,
|
||||
blurHash: String? = null,
|
||||
) =
|
||||
AttachmentThumbnailInfo(
|
||||
type = type,
|
||||
thumbnailSource = thumbnailSource,
|
||||
textContent = textContent,
|
||||
blurHash = blurHash,
|
||||
)
|
||||
|
||||
const val A_BLUR_HASH = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr"
|
||||
@@ -58,6 +58,7 @@ import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnail
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
|
||||
@@ -720,7 +721,7 @@ internal fun TextComposerReplyPreview() = ElementPreview {
|
||||
thumbnailSource = MediaSource("https://domain.com/image.jpg"),
|
||||
textContent = "image.jpg",
|
||||
type = AttachmentThumbnailType.Image,
|
||||
blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr",
|
||||
blurHash = A_BLUR_HASH,
|
||||
),
|
||||
defaultContent = "image.jpg"
|
||||
),
|
||||
@@ -741,7 +742,7 @@ internal fun TextComposerReplyPreview() = ElementPreview {
|
||||
thumbnailSource = MediaSource("https://domain.com/video.mp4"),
|
||||
textContent = "video.mp4",
|
||||
type = AttachmentThumbnailType.Video,
|
||||
blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr",
|
||||
blurHash = A_BLUR_HASH,
|
||||
),
|
||||
defaultContent = "video.mp4"
|
||||
),
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user