diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 841ccb8faa..ddc9f17262 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -43,6 +43,7 @@ import io.element.android.features.messages.impl.timeline.TimelinePresenter import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuPresenter import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent @@ -108,10 +109,10 @@ class MessagesPresenter @AssistedInject constructor( val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val userHasPermissionToSendMessage by room.canSendEventAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value) - val roomName by produceState(initialValue = room.displayName, key1 = syncUpdateFlow.value){ + val roomName by produceState(initialValue = room.displayName, key1 = syncUpdateFlow.value) { value = room.displayName } - val roomAvatar by produceState(initialValue = room.avatarData(), key1 = syncUpdateFlow.value){ + val roomAvatar by produceState(initialValue = room.avatarData(), key1 = syncUpdateFlow.value) { value = room.avatarData() } var hasDismissedInviteDialog by rememberSaveable { @@ -250,28 +251,28 @@ class MessagesPresenter @AssistedInject constructor( val textContent = messageSummaryFormatter.format(targetEvent) val attachmentThumbnailInfo = when (targetEvent.content) { is TimelineItemImageContent -> AttachmentThumbnailInfo( - mediaSource = targetEvent.content.mediaSource, + thumbnailSource = targetEvent.content.thumbnailSource, textContent = targetEvent.content.body, type = AttachmentThumbnailType.Image, blurHash = targetEvent.content.blurhash, ) is TimelineItemVideoContent -> AttachmentThumbnailInfo( - mediaSource = targetEvent.content.thumbnailSource, + thumbnailSource = targetEvent.content.thumbnailSource, textContent = targetEvent.content.body, type = AttachmentThumbnailType.Video, blurHash = targetEvent.content.blurHash, ) is TimelineItemFileContent -> AttachmentThumbnailInfo( - mediaSource = targetEvent.content.thumbnailSource, + thumbnailSource = targetEvent.content.thumbnailSource, textContent = targetEvent.content.body, type = AttachmentThumbnailType.File, - blurHash = null, + ) + is TimelineItemAudioContent -> AttachmentThumbnailInfo( + textContent = targetEvent.content.body, + type = AttachmentThumbnailType.Audio, ) is TimelineItemLocationContent -> AttachmentThumbnailInfo( - mediaSource = null, - textContent = null, type = AttachmentThumbnailType.Location, - blurHash = null, ) is TimelineItemTextBasedContent, is TimelineItemRedactedContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index bb1f2a7ac8..c41f1006c8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -56,6 +56,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent @@ -246,7 +247,7 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif info = AttachmentThumbnailInfo( type = AttachmentThumbnailType.Location, textContent = stringResource(CommonStrings.common_shared_location), - mediaSource = null, + thumbnailSource = null, blurHash = null, ) ) @@ -258,7 +259,7 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif AttachmentThumbnail( modifier = imageModifier, info = AttachmentThumbnailInfo( - mediaSource = event.content.mediaSource, + thumbnailSource = event.content.mediaSource, textContent = textContent, type = AttachmentThumbnailType.File, blurHash = event.content.blurhash, @@ -272,7 +273,7 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif AttachmentThumbnail( modifier = imageModifier, info = AttachmentThumbnailInfo( - mediaSource = event.content.thumbnailSource, + thumbnailSource = event.content.thumbnailSource, textContent = textContent, type = AttachmentThumbnailType.Video, blurHash = event.content.blurHash, @@ -286,7 +287,7 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif AttachmentThumbnail( modifier = imageModifier, info = AttachmentThumbnailInfo( - mediaSource = null, + thumbnailSource = event.content.thumbnailSource, textContent = textContent, type = AttachmentThumbnailType.File, blurHash = null @@ -295,6 +296,18 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif } content = { ContentForBody(event.content.body) } } + is TimelineItemAudioContent -> { + icon = { + AttachmentThumbnail( + modifier = imageModifier, + info = AttachmentThumbnailInfo( + textContent = textContent, + type = AttachmentThumbnailType.Audio, + ) + ) + } + content = { ContentForBody(event.content.body) } + } } Row(modifier = modifier) { icon() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 8d7ff263e8..fbb745c34e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -56,7 +56,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.zIndex import androidx.constraintlayout.compose.ConstrainScope import androidx.constraintlayout.compose.ConstraintLayout @@ -85,6 +84,7 @@ import io.element.android.libraries.designsystem.text.toPx import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo @@ -521,28 +521,29 @@ private fun ReplyToContent( private fun attachmentThumbnailInfoForInReplyTo(inReplyTo: InReplyTo.Ready) = when (val type = inReplyTo.content.type) { is ImageMessageType -> AttachmentThumbnailInfo( - mediaSource = type.info?.thumbnailSource, + thumbnailSource = type.info?.thumbnailSource, textContent = inReplyTo.content.body, type = AttachmentThumbnailType.Image, blurHash = type.info?.blurhash, ) is VideoMessageType -> AttachmentThumbnailInfo( - mediaSource = type.info?.thumbnailSource, + thumbnailSource = type.info?.thumbnailSource, textContent = inReplyTo.content.body, type = AttachmentThumbnailType.Video, blurHash = type.info?.blurhash, ) is FileMessageType -> AttachmentThumbnailInfo( - mediaSource = type.info?.thumbnailSource, + thumbnailSource = type.info?.thumbnailSource, textContent = inReplyTo.content.body, type = AttachmentThumbnailType.File, - blurHash = null, ) is LocationMessageType -> AttachmentThumbnailInfo( - mediaSource = null, textContent = inReplyTo.content.body, type = AttachmentThumbnailType.Location, - blurHash = null, + ) + is AudioMessageType -> AttachmentThumbnailInfo( + textContent = inReplyTo.content.body, + type = AttachmentThumbnailType.Audio, ) else -> null } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt new file mode 100644 index 0000000000..3cae19e237 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt @@ -0,0 +1,108 @@ +/* + * 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.features.messages.impl.timeline.components.event + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Attachment +import androidx.compose.material.icons.outlined.GraphicEq +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.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContentProvider +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.ElementTheme + +@Composable +fun TimelineItemAudioView( + content: TimelineItemAudioContent, + extraPadding: ExtraPadding, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier, + ) { + Box( + modifier = Modifier + .size(32.dp) + .clip(CircleShape) + .background(ElementTheme.materialColors.background), + contentAlignment = Alignment.Center, + ) { + Icon( + imageVector = Icons.Outlined.GraphicEq, + contentDescription = null, + tint = ElementTheme.materialColors.primary, + modifier = Modifier + .size(16.dp), + ) + } + Spacer(Modifier.width(8.dp)) + Column { + Text( + text = content.body, + color = ElementTheme.materialColors.primary, + maxLines = 2, + style = ElementTheme.typography.fontBodyLgRegular, + overflow = TextOverflow.Ellipsis + ) + Text( + text = content.fileExtensionAndSize + extraPadding.getStr(12.sp), + color = ElementTheme.materialColors.secondary, + style = ElementTheme.typography.fontBodySmRegular, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } +} + +@Preview +@Composable +internal fun TimelineItemAudioViewLightPreview(@PreviewParameter(TimelineItemAudioContentProvider::class) content: TimelineItemAudioContent) = + ElementPreviewLight { ContentToPreview(content) } + +@Preview +@Composable +internal fun TimelineItemAudioViewDarkPreview(@PreviewParameter(TimelineItemAudioContentProvider::class) content: TimelineItemAudioContent) = + ElementPreviewDark { ContentToPreview(content) } + +@Composable +private fun ContentToPreview(content: TimelineItemAudioContent) { + TimelineItemAudioView( + content, + extraPadding = noExtraPadding, + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemContentView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemContentView.kt index 7d3f8835ca..3df45eb760 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemContentView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemContentView.kt @@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent @@ -80,6 +81,11 @@ fun TimelineItemEventContentView( extraPadding = extraPadding, modifier = modifier ) + is TimelineItemAudioContent -> TimelineItemAudioView( + content = content, + extraPadding = extraPadding, + modifier = modifier + ) is TimelineItemStateContent -> TimelineItemStateView( content = content, modifier = modifier diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index 9d4304cec0..9da31ee6a7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -17,6 +17,7 @@ package io.element.android.features.messages.impl.timeline.factories.event import io.element.android.features.location.api.Location +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEmoteContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent @@ -30,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.util.FileExtensionExtr import io.element.android.features.messages.impl.timeline.util.toHtmlDocument import io.element.android.libraries.androidutils.filesize.FileSizeFormatter import io.element.android.libraries.core.mimetype.MimeTypes +import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType @@ -99,6 +101,14 @@ class TimelineItemContentMessageFactory @Inject constructor( fileExtension = fileExtensionExtractor.extractFromName(messageType.body) ) } + is AudioMessageType -> TimelineItemAudioContent( + body = messageType.body, + audioSource = messageType.source, + duration = messageType.info?.duration?.toMillis() ?: 0L, + mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, + formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0), + fileExtension = fileExtensionExtractor.extractFromName(messageType.body) + ) is FileMessageType -> TimelineItemFileContent( body = messageType.body, thumbnailSource = messageType.info?.thumbnailSource, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt index bf827a2b3d..0b8baf692a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt @@ -17,6 +17,7 @@ package io.element.android.features.messages.impl.timeline.groups import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent @@ -52,6 +53,7 @@ internal fun TimelineItem.Event.canBeGrouped(): Boolean { is TimelineItemImageContent, is TimelineItemFileContent, is TimelineItemVideoContent, + is TimelineItemAudioContent, is TimelineItemLocationContent, TimelineItemRedactedContent, TimelineItemUnknownContent -> false diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt new file mode 100644 index 0000000000..485b863170 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.features.messages.impl.timeline.model.event + +import io.element.android.features.messages.impl.media.helper.formatFileExtensionAndSize +import io.element.android.libraries.matrix.api.media.MediaSource + +data class TimelineItemAudioContent( + val body: String, + val duration: Long, + val audioSource: MediaSource, + val mimeType: String, + val formattedFileSize: String, + val fileExtension: String, +) : TimelineItemEventContent { + + val fileExtensionAndSize = formatFileExtensionAndSize(fileExtension, formattedFileSize) + override val type: String = "TimelineItemAudioContent" +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt new file mode 100644 index 0000000000..ed424781f8 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt @@ -0,0 +1,39 @@ +/* + * 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.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 + +open class TimelineItemAudioContentProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aTimelineItemAudioContent("A sound.mp3"), + aTimelineItemAudioContent("A bigger name sound.mp3"), + aTimelineItemAudioContent("An even bigger bigger bigger bigger bigger bigger bigger sound name which doesn't fit .mp3"), + ) +} + +fun aTimelineItemAudioContent(fileName: String = "A sound.mp3") = TimelineItemAudioContent( + body = fileName, + mimeType = MimeTypes.Pdf, + formattedFileSize = "100kB", + fileExtension = "mp3", + duration = 100, + audioSource = MediaSource(""), +) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/utils/messagesummary/MessageSummaryFormatterImpl.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/utils/messagesummary/MessageSummaryFormatterImpl.kt index e22aed6af9..42c50bbd9d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/utils/messagesummary/MessageSummaryFormatterImpl.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/utils/messagesummary/MessageSummaryFormatterImpl.kt @@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.utils.messagesummary import android.content.Context import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent @@ -50,6 +51,7 @@ class MessageSummaryFormatterImpl @Inject constructor( is TimelineItemImageContent -> context.getString(CommonStrings.common_image) is TimelineItemVideoContent -> context.getString(CommonStrings.common_video) is TimelineItemFileContent -> context.getString(CommonStrings.common_file) + is TimelineItemAudioContent -> context.getString(CommonStrings.common_audio) } } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/AudioInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/AudioInfo.kt index e9708a6926..bd4539bced 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/AudioInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/AudioInfo.kt @@ -21,5 +21,5 @@ import java.time.Duration data class AudioInfo( val duration: Duration?, val size: Long?, - val mimeType: String?, + val mimetype: String?, ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/AudioInfo.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/AudioInfo.kt index 2f0d6879a4..70c3bac6ed 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/AudioInfo.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/AudioInfo.kt @@ -22,11 +22,11 @@ import org.matrix.rustcomponents.sdk.AudioInfo as RustAudioInfo fun RustAudioInfo.map(): AudioInfo = AudioInfo( duration = duration, size = size?.toLong(), - mimeType = mimetype + mimetype = mimetype ) fun AudioInfo.map(): RustAudioInfo = RustAudioInfo( duration = duration, size = size?.toULong(), - mimetype = mimeType, + mimetype = mimetype, ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt index cac211bcb5..71883ebc20 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Attachment +import androidx.compose.material.icons.outlined.GraphicEq import androidx.compose.material.icons.outlined.VideoCameraBack import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -44,9 +45,9 @@ fun AttachmentThumbnail( thumbnailSize: Long = 32L, backgroundColor: Color = MaterialTheme.colorScheme.surface, ) { - if (info.mediaSource != null) { + if (info.thumbnailSource != null) { val mediaRequestData = MediaRequestData( - source = info.mediaSource, + source = info.thumbnailSource, kind = MediaRequestData.Kind.Thumbnail(thumbnailSize), ) BlurHashAsyncImage( @@ -68,6 +69,12 @@ fun AttachmentThumbnail( contentDescription = info.textContent, ) } + AttachmentThumbnailType.Audio -> { + Icon( + imageVector = Icons.Outlined.GraphicEq, + contentDescription = info.textContent, + ) + } AttachmentThumbnailType.File -> { Icon( imageVector = Icons.Outlined.Attachment, @@ -88,13 +95,13 @@ fun AttachmentThumbnail( @Parcelize enum class AttachmentThumbnailType: Parcelable { - Image, Video, File, Location + Image, Video, File, Audio, Location } @Parcelize data class AttachmentThumbnailInfo( - val mediaSource: MediaSource?, - val textContent: String?, - val type: AttachmentThumbnailType?, - val blurHash: String?, + val type: AttachmentThumbnailType, + val thumbnailSource: MediaSource? = null, + val textContent: String? = null, + val blurHash: String? = null, ): Parcelable diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt index 9482aecc13..f0cf6b9dcb 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/AndroidMediaPreProcessor.kt @@ -196,7 +196,7 @@ class AndroidMediaPreProcessor @Inject constructor( val info = AudioInfo( duration = extractDuration(), size = file.length(), - mimeType = mimeType, + mimetype = mimeType, ) MediaUploadInfo.Audio(file, info) diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index b757f69f03..3994d8f55c 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -482,7 +482,7 @@ fun TextComposerReplyPreview() = ElementPreview { senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( - mediaSource = MediaSource("https://domain.com/image.jpg"), + thumbnailSource = MediaSource("https://domain.com/image.jpg"), textContent = "image.jpg", type = AttachmentThumbnailType.Image, blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr", @@ -500,7 +500,7 @@ fun TextComposerReplyPreview() = ElementPreview { senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( - mediaSource = MediaSource("https://domain.com/video.mp4"), + thumbnailSource = MediaSource("https://domain.com/video.mp4"), textContent = "video.mp4", type = AttachmentThumbnailType.Video, blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr", @@ -518,7 +518,7 @@ fun TextComposerReplyPreview() = ElementPreview { senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( - mediaSource = null, + thumbnailSource = null, textContent = "logs.txt", type = AttachmentThumbnailType.File, blurHash = null, @@ -536,7 +536,7 @@ fun TextComposerReplyPreview() = ElementPreview { senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( - mediaSource = null, + thumbnailSource = null, textContent = null, type = AttachmentThumbnailType.Location, blurHash = null,