diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt index a6b906d6fb..c8e35ccbe8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt @@ -40,7 +40,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import kotlinx.android.parcel.Parcelize import kotlinx.collections.immutable.ImmutableList @@ -64,7 +64,7 @@ class MessagesFlowNode @AssistedInject constructor( @Parcelize data class MediaViewer( val title: String, - val mediaSource: MatrixMediaSource, + val mediaSource: MediaSource, val mimeType: String? ) : NavTarget diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerNode.kt index 7f52e7e07a..fe2167c786 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerNode.kt @@ -27,7 +27,7 @@ import io.element.android.anvilannotations.ContributesNode import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource @ContributesNode(RoomScope::class) class MediaViewerNode @AssistedInject constructor( @@ -38,7 +38,7 @@ class MediaViewerNode @AssistedInject constructor( data class Inputs( val name: String, - val mediaSource: MatrixMediaSource, + val mediaSource: MediaSource, val mimeType: String? ) : NodeInputs diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt index 0d136a3144..850dc9782c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt @@ -16,11 +16,11 @@ package io.element.android.features.messages.impl.timeline.model.event -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource data class TimelineItemImageContent( val body: String, - val mediaSource: MatrixMediaSource, + val mediaSource: MediaSource, val mimeType: String?, val blurhash: String?, val width: Int?, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt index 0a3c339fdd..0bedfd8991 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt @@ -17,8 +17,7 @@ package io.element.android.features.messages.impl.timeline.model.event import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.matrix.api.media.MatrixMediaSource -import io.element.android.libraries.matrix.ui.media.MediaRequestData +import io.element.android.libraries.matrix.api.media.MediaSource open class TimelineItemImageContentProvider : PreviewParameterProvider { override val values: Sequence @@ -31,7 +30,7 @@ open class TimelineItemImageContentProvider : PreviewParameterProvider { override val values: Sequence @@ -30,11 +30,11 @@ open class TimelineItemVideoContentProvider : PreviewParameterProvider + suspend fun loadMediaContent(source: MediaSource): Result /** * @param url to fetch the data for. @@ -29,12 +29,12 @@ interface MatrixMediaLoader { * @param height: the desired height for rescaling the media as thumbnail * @return a [Result] of ByteArray. It contains the binary data for the media. */ - suspend fun loadMediaThumbnail(source: MatrixMediaSource, width: Long, height: Long): Result + suspend fun loadMediaThumbnail(source: MediaSource, width: Long, height: Long): Result /** * @param url to fetch the data for. * @param mimeType: optional mime type * @return a [Result] of [MediaFile] */ - suspend fun loadMediaFile(source: MatrixMediaSource, mimeType: String?): Result + suspend fun loadMediaFile(source: MediaSource, mimeType: String?): Result } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MatrixMediaSource.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MediaSource.kt similarity index 80% rename from libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MatrixMediaSource.kt rename to libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MediaSource.kt index 22092c1afd..fe5217c2c2 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MatrixMediaSource.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MediaSource.kt @@ -20,6 +20,13 @@ import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize -data class MatrixMediaSource( - val url: String +data class MediaSource( + /** + * Url of the media + */ + val url: String, + /** + * This is used to hold data for encrypted media + */ + val json: String? = null, ) : Parcelable diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/VideoInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/VideoInfo.kt index ca24a3303f..aa291bd653 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/VideoInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/VideoInfo.kt @@ -23,6 +23,6 @@ data class VideoInfo( val mimetype: String?, val size: Long?, val thumbnailInfo: ThumbnailInfo?, - val thumbnailSource: MatrixMediaSource?, + val thumbnailSource: MediaSource?, val blurhash: String? ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index 31bdfee4fa..dafaa95936 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -21,7 +21,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.media.AudioInfo import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.VideoInfo sealed interface EventContent @@ -107,25 +107,25 @@ data class EmoteMessageType( data class ImageMessageType( val body: String, - val source: MatrixMediaSource, + val source: MediaSource, val info: ImageInfo? ) : MessageType data class AudioMessageType( val body: String, - val source: MatrixMediaSource, + val source: MediaSource, val info: AudioInfo? ) : MessageType data class VideoMessageType( val body: String, - val source: MatrixMediaSource, + val source: MediaSource, val info: VideoInfo? ) : MessageType data class FileMessageType( val body: String, - val source: MatrixMediaSource, + val source: MediaSource, val info: FileInfo? ) : MessageType diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/MediaSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/MediaSource.kt index 4d3dc6603f..c70bd0640f 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/MediaSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/MediaSource.kt @@ -16,8 +16,10 @@ package io.element.android.libraries.matrix.impl.media -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.MediaSource as RustMediaSource -fun RustMediaSource.map(): MatrixMediaSource = use { MatrixMediaSource(it.url()) } +fun RustMediaSource.map(): MediaSource = use { + MediaSource(it.url(), it.toJson()) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt index b7e69226c0..5e9c26d6c6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt @@ -18,12 +18,13 @@ package io.element.android.libraries.matrix.impl.media import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.media.MatrixMediaLoader -import io.element.android.libraries.matrix.api.media.MatrixMediaSource import io.element.android.libraries.matrix.api.media.MediaFile +import io.element.android.libraries.matrix.api.media.MediaSource import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.mediaSourceFromUrl import org.matrix.rustcomponents.sdk.use +import org.matrix.rustcomponents.sdk.MediaSource as RustMediaSource class RustMediaLoader( private val dispatchers: CoroutineDispatchers, @@ -31,10 +32,10 @@ class RustMediaLoader( ) : MatrixMediaLoader { @OptIn(ExperimentalUnsignedTypes::class) - override suspend fun loadMediaContent(source: MatrixMediaSource): Result = + override suspend fun loadMediaContent(source: MediaSource): Result = withContext(dispatchers.io) { runCatching { - mediaSourceFromUrl(source.url).use { source -> + source.toRustMediaSource().use { source -> innerClient.getMediaContent(source).toUByteArray().toByteArray() } } @@ -42,13 +43,13 @@ class RustMediaLoader( @OptIn(ExperimentalUnsignedTypes::class) override suspend fun loadMediaThumbnail( - source: MatrixMediaSource, + source: MediaSource, width: Long, height: Long ): Result = withContext(dispatchers.io) { runCatching { - mediaSourceFromUrl(source.url).use { mediaSource -> + source.toRustMediaSource().use { mediaSource -> innerClient.getMediaThumbnail( mediaSource = mediaSource, width = width.toULong(), @@ -58,10 +59,10 @@ class RustMediaLoader( } } - override suspend fun loadMediaFile(source: MatrixMediaSource, mimeType: String?): Result = + override suspend fun loadMediaFile(source: MediaSource, mimeType: String?): Result = withContext(dispatchers.io) { runCatching { - mediaSourceFromUrl(source.url).use { mediaSource -> + source.toRustMediaSource().use { mediaSource -> val mediaFile = innerClient.getMediaFile( mediaSource = mediaSource, body = null, @@ -71,4 +72,13 @@ class RustMediaLoader( } } } + + private fun MediaSource.toRustMediaSource(): RustMediaSource { + val json = this.json + return if (json != null) { + RustMediaSource.fromJson(json) + } else { + mediaSourceFromUrl(url) + } + } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMediaLoader.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMediaLoader.kt index 8369c309cc..ebc823f6d1 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMediaLoader.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMediaLoader.kt @@ -17,14 +17,14 @@ package io.element.android.libraries.matrix.test.media import io.element.android.libraries.matrix.api.media.MatrixMediaLoader -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.MediaFile class FakeMediaLoader : MatrixMediaLoader { var shouldFail = false - override suspend fun loadMediaContent(source: MatrixMediaSource): Result { + override suspend fun loadMediaContent(source: MediaSource): Result { return if (shouldFail) { Result.failure(RuntimeException()) } else { @@ -32,7 +32,7 @@ class FakeMediaLoader : MatrixMediaLoader { } } - override suspend fun loadMediaThumbnail(source: MatrixMediaSource, width: Long, height: Long): Result { + override suspend fun loadMediaThumbnail(source: MediaSource, width: Long, height: Long): Result { return if (shouldFail) { Result.failure(RuntimeException()) } else { @@ -40,7 +40,7 @@ class FakeMediaLoader : MatrixMediaLoader { } } - override suspend fun loadMediaFile(source: MatrixMediaSource, mimeType: String?): Result { + override suspend fun loadMediaFile(source: MediaSource, mimeType: String?): Result { return if (shouldFail) { Result.failure(RuntimeException()) } else { diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt index aa06e960c4..39912cb443 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt @@ -17,12 +17,12 @@ package io.element.android.libraries.matrix.ui.media import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import kotlin.math.roundToLong fun AvatarData.toMediaRequestData(): MediaRequestData { return MediaRequestData( - source = url?.let { MatrixMediaSource(it) }, + source = url?.let { MediaSource(it) }, kind = MediaRequestData.Kind.Thumbnail(size.dp.value.roundToLong()) ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestData.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestData.kt index f3049ab4af..02a7ed4e8c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestData.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestData.kt @@ -16,10 +16,10 @@ package io.element.android.libraries.matrix.ui.media -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource data class MediaRequestData( - val source: MatrixMediaSource?, + val source: MediaSource?, val kind: Kind ) { diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/MediaPreProcessorImpl.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/MediaPreProcessorImpl.kt index 6831cad565..799191251c 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/MediaPreProcessorImpl.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/MediaPreProcessorImpl.kt @@ -33,7 +33,7 @@ import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.media.AudioInfo import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo -import io.element.android.libraries.matrix.api.media.MatrixMediaSource +import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.ThumbnailInfo import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.mediaupload.api.MediaPreProcessor @@ -217,7 +217,7 @@ class MediaPreProcessorImpl @Inject constructor( mimetype = mimeType, size = file.length(), thumbnailInfo = thumbnailInfo?.info, - thumbnailSource = thumbnailUrl?.let { MatrixMediaSource(it) }, + thumbnailSource = thumbnailUrl?.let { MediaSource(it) }, blurhash = thumbnailInfo?.blurhash, ) } @@ -251,7 +251,7 @@ fun ImageCompressionResult.toImageInfo(mimeType: String, thumbnailUrl: String?, mimetype = mimeType, size = size, thumbnailInfo = thumbnailInfo, - thumbnailSource = thumbnailUrl?.let { MatrixMediaSource(it) }, + thumbnailSource = thumbnailUrl?.let { MediaSource(it) }, blurhash = blurhash, ) diff --git a/libraries/mediaupload/test/src/main/kotlin/io/element/android/libraries/mediaupload/test/FakeMediaPreProcessor.kt b/libraries/mediaupload/test/src/main/kotlin/io/element/android/libraries/mediaupload/test/FakeMediaPreProcessor.kt index 08a284af6c..e96bc08fd1 100644 --- a/libraries/mediaupload/test/src/main/kotlin/io/element/android/libraries/mediaupload/test/FakeMediaPreProcessor.kt +++ b/libraries/mediaupload/test/src/main/kotlin/io/element/android/libraries/mediaupload/test/FakeMediaPreProcessor.kt @@ -32,10 +32,11 @@ class FakeMediaPreProcessor : MediaPreProcessor { mimetype = "*/*", size = 999L, thumbnailInfo = null, - thumbnailUrl = null, + thumbnailSource = null, ) ) ) + override suspend fun process(uri: Uri, mediaType: MediaType, deleteOriginal: Boolean): Result = result fun givenResult(value: Result) {