Merge pull request #1774 from vector-im/feature/bma/imageThumbnail

Improve rendering of `AttachmentThumbnail` when thumbnailSource is not provided
This commit is contained in:
Benoit Marty
2023-11-09 14:30:29 +01:00
committed by GitHub
50 changed files with 151 additions and 12 deletions

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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(""),

View File

@@ -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))
)
}

View File

@@ -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"

View File

@@ -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"
),