[Media upload] Upload image, video and files (#411)

* Add media upload

* Display media upload error messages using a Snackbar.
This commit is contained in:
Jorge Martin Espinosa 2023-05-11 17:56:13 +02:00 committed by GitHub
parent 1765398eb1
commit 89b9db3be6
24 changed files with 373 additions and 77 deletions

View file

@ -18,5 +18,6 @@ package io.element.android.libraries.matrix.api.media
data class AudioInfo(
val duration: Long?,
val size: Long?
val size: Long?,
val mimeType: String?,
)

View file

@ -20,10 +20,15 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
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.VideoInfo
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import java.io.Closeable
import java.io.File
interface MatrixRoom : Closeable {
val sessionId: SessionId
@ -67,6 +72,14 @@ interface MatrixRoom : Closeable {
suspend fun redactEvent(eventId: EventId, reason: String? = null): Result<Unit>
suspend fun sendImage(file: File, thumbnailFile: File, imageInfo: ImageInfo): Result<Unit>
suspend fun sendVideo(file: File, thumbnailFile: File, videoInfo: VideoInfo): Result<Unit>
suspend fun sendAudio(file: File, audioInfo: AudioInfo): Result<Unit>
suspend fun sendFile(file: File, fileInfo: FileInfo): Result<Unit>
suspend fun leave(): Result<Unit>
suspend fun acceptInvitation(): Result<Unit>

View file

@ -21,5 +21,12 @@ import org.matrix.rustcomponents.sdk.AudioInfo as RustAudioInfo
fun RustAudioInfo.map(): AudioInfo = AudioInfo(
duration = duration?.toLong(),
size = size?.toLong()
size = size?.toLong(),
mimeType = mimetype
)
fun AudioInfo.map(): RustAudioInfo = RustAudioInfo(
duration = duration?.toULong(),
size = size?.toULong(),
mimetype = mimeType,
)

View file

@ -27,3 +27,10 @@ fun RustFileInfo.map(): FileInfo = FileInfo(
thumbnailInfo = thumbnailInfo?.map(),
thumbnailUrl = thumbnailSource?.useUrl()
)
fun FileInfo.map(): RustFileInfo = RustFileInfo(
mimetype = mimetype,
size = size?.toULong(),
thumbnailInfo = thumbnailInfo?.map(),
thumbnailSource = null
)

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.media
import io.element.android.libraries.matrix.api.media.ImageInfo
import org.matrix.rustcomponents.sdk.MediaSource
import org.matrix.rustcomponents.sdk.ImageInfo as RustImageInfo
fun RustImageInfo.map(): ImageInfo = ImageInfo(
@ -28,3 +29,13 @@ fun RustImageInfo.map(): ImageInfo = ImageInfo(
thumbnailUrl = thumbnailSource?.useUrl(),
blurhash = blurhash
)
fun ImageInfo.map(): RustImageInfo = RustImageInfo(
height = height?.toULong(),
width = width?.toULong(),
mimetype = mimetype,
size = size?.toULong(),
thumbnailInfo = thumbnailInfo?.map(),
thumbnailSource = null,
blurhash = blurhash,
)

View file

@ -25,3 +25,10 @@ fun RustThumbnailInfo.map(): ThumbnailInfo = ThumbnailInfo(
mimetype = mimetype,
size = size?.toLong()
)
fun ThumbnailInfo.map(): RustThumbnailInfo = RustThumbnailInfo(
height = height?.toULong(),
width = width?.toULong(),
mimetype = mimetype,
size = size?.toULong()
)

View file

@ -29,3 +29,14 @@ fun RustVideoInfo.map(): VideoInfo = VideoInfo(
thumbnailUrl = thumbnailSource?.useUrl(),
blurhash = blurhash
)
fun VideoInfo.map(): RustVideoInfo = RustVideoInfo(
duration = duration?.toULong(),
height = height?.toULong(),
width = width?.toULong(),
mimetype = mimetype,
size = size?.toULong(),
thumbnailInfo = thumbnailInfo?.map(),
thumbnailSource = null,
blurhash = blurhash
)

View file

@ -21,10 +21,15 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
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.VideoInfo
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import io.element.android.libraries.matrix.impl.media.map
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@ -39,6 +44,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncRoom
import org.matrix.rustcomponents.sdk.UpdateSummary
import org.matrix.rustcomponents.sdk.genTransactionId
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
import java.io.File
class RustMatrixRoom(
override val sessionId: SessionId,
@ -202,4 +208,28 @@ class RustMatrixRoom(
}
}
override suspend fun sendImage(file: File, thumbnailFile: File, imageInfo: ImageInfo): Result<Unit> {
return runCatching {
innerRoom.sendImage(file.path, thumbnailFile.path, imageInfo.map())
}
}
override suspend fun sendVideo(file: File, thumbnailFile: File, videoInfo: VideoInfo): Result<Unit> {
return runCatching {
innerRoom.sendVideo(file.path, thumbnailFile.path, videoInfo.map())
}
}
override suspend fun sendAudio(file: File, audioInfo: AudioInfo): Result<Unit> {
return runCatching {
innerRoom.sendAudio(file.path, audioInfo.map())
}
}
override suspend fun sendFile(file: File, fileInfo: FileInfo): Result<Unit> {
return runCatching {
innerRoom.sendFile(file.path, fileInfo.map())
}
}
}

View file

@ -20,6 +20,10 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
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.VideoInfo
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
@ -30,6 +34,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
import java.io.File
class FakeMatrixRoom(
override val sessionId: SessionId = A_SESSION_ID,
@ -54,6 +59,9 @@ class FakeMatrixRoom(
private var updateMembersResult: Result<Unit> = Result.success(Unit)
private var acceptInviteResult = Result.success(Unit)
private var rejectInviteResult = Result.success(Unit)
private var sendMediaResult = Result.success(Unit)
var sendMediaCount = 0
private set
var isInviteAccepted: Boolean = false
private set
@ -128,6 +136,14 @@ class FakeMatrixRoom(
return rejectInviteResult
}
override suspend fun sendImage(file: File, thumbnailFile: File, imageInfo: ImageInfo): Result<Unit> = sendMediaResult.also { sendMediaCount++ }
override suspend fun sendVideo(file: File, thumbnailFile: File, videoInfo: VideoInfo): Result<Unit> = sendMediaResult.also { sendMediaCount++ }
override suspend fun sendAudio(file: File, audioInfo: AudioInfo): Result<Unit> = sendMediaResult.also { sendMediaCount++ }
override suspend fun sendFile(file: File, fileInfo: FileInfo): Result<Unit> = sendMediaResult.also { sendMediaCount++ }
override fun close() = Unit
fun givenLeaveRoomError(throwable: Throwable?) {
@ -165,4 +181,8 @@ class FakeMatrixRoom(
fun givenUnIgnoreResult(result: Result<Unit>) {
unignoreResult = result
}
fun givenSendMediaResult(result: Result<Unit>) {
sendMediaResult = result
}
}