Media : branch upload to preview screen (need improvement)
This commit is contained in:
parent
c8ead4ab9f
commit
f51d6a3cfd
15 changed files with 237 additions and 92 deletions
|
|
@ -25,3 +25,16 @@ inline fun <R, T : R> Result<T>.mapFailure(transform: (exception: Throwable) ->
|
|||
else -> Result.failure(transform(exception))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to transform some Throwable into some other.
|
||||
*/
|
||||
inline fun <R, T> Result<R>.flatMap(transform: (R) -> Result<T>): Result<T> {
|
||||
return when (val exception = exceptionOrNull()) {
|
||||
null -> mapCatching(transform).fold(
|
||||
onSuccess = { it },
|
||||
onFailure = { Result.failure(it) }
|
||||
)
|
||||
else -> Result.failure(exception)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ import android.net.Uri
|
|||
|
||||
interface MediaPreProcessor {
|
||||
/**
|
||||
* Given a [uri] and [mediaType], pre-processes the media before it's uploaded, resizing, transcoding, and removing sensitive info from its metadata.
|
||||
* Given a [uri] and [mimeType], pre-processes the media before it's uploaded, resizing, transcoding, and removing sensitive info from its metadata.
|
||||
* If [deleteOriginal] is `true`, the file reference by the [uri] will be automatically deleted too when this process finishes.
|
||||
* @return a [Result] with the [MediaUploadInfo] containing all the info needed to begin the upload.
|
||||
*/
|
||||
suspend fun process(
|
||||
uri: Uri,
|
||||
mediaType: MediaType,
|
||||
mimeType: String,
|
||||
deleteOriginal: Boolean = false
|
||||
): Result<MediaUploadInfo>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* 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.mediaupload.api
|
||||
|
||||
sealed interface MediaType {
|
||||
object Image : MediaType
|
||||
object Video : MediaType
|
||||
object Audio : MediaType
|
||||
object File : MediaType
|
||||
}
|
||||
|
|
@ -27,7 +27,9 @@ import io.element.android.libraries.androidutils.media.runAndRelease
|
|||
import io.element.android.libraries.core.data.tryOrNull
|
||||
import io.element.android.libraries.core.extensions.mapFailure
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeAudio
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeImage
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||
|
|
@ -37,7 +39,6 @@ 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
|
||||
import io.element.android.libraries.mediaupload.api.MediaType
|
||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||
import io.element.android.libraries.mediaupload.api.ThumbnailProcessingInfo
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -53,7 +54,7 @@ import javax.inject.Inject
|
|||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class MediaPreProcessorImpl @Inject constructor(
|
||||
class AndroidMediaPreProcessor @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val imageCompressor: ImageCompressor,
|
||||
private val videoCompressor: VideoCompressor,
|
||||
|
|
@ -89,27 +90,18 @@ class MediaPreProcessorImpl @Inject constructor(
|
|||
|
||||
override suspend fun process(
|
||||
uri: Uri,
|
||||
mediaType: MediaType,
|
||||
mimeType: String,
|
||||
deleteOriginal: Boolean,
|
||||
): Result<MediaUploadInfo> = runCatching {
|
||||
// Camera returns an 'octet-stream' mimetype, so it needs to be overridden
|
||||
val mimeType = contentResolver.getType(uri)
|
||||
val mimeTypeOrDefault = if (mimeType == MimeTypes.OctetStream) {
|
||||
when (mediaType) {
|
||||
MediaType.Image -> MimeTypes.Jpeg
|
||||
MediaType.Video -> MimeTypes.Mp4
|
||||
MediaType.Audio -> MimeTypes.Ogg
|
||||
else -> mimeType
|
||||
}
|
||||
} else {
|
||||
mimeType
|
||||
}
|
||||
val compressBeforeSending = mediaType in sequenceOf(MediaType.Image, MediaType.Video)
|
||||
val result = if (compressBeforeSending && mimeType != MimeTypes.Gif) {
|
||||
when (mediaType) {
|
||||
MediaType.Image -> processImage(uri)
|
||||
MediaType.Video -> processVideo(uri, mimeTypeOrDefault)
|
||||
MediaType.Audio -> processAudio(uri, mimeTypeOrDefault)
|
||||
val compressBeforeSending = (
|
||||
mimeType.isMimeTypeImage() && mimeType != MimeTypes.Gif) ||
|
||||
mimeType.isMimeTypeVideo()
|
||||
|
||||
val result = if (compressBeforeSending) {
|
||||
when {
|
||||
mimeType.isMimeTypeImage() -> processImage(uri)
|
||||
mimeType.isMimeTypeVideo() -> processVideo(uri, mimeType)
|
||||
mimeType.isMimeTypeAudio() -> processAudio(uri, mimeType)
|
||||
else -> error("Cannot compress file of type: $mimeType")
|
||||
}
|
||||
} else {
|
||||
|
|
@ -19,7 +19,6 @@ package io.element.android.libraries.mediaupload.test
|
|||
import android.net.Uri
|
||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||
import io.element.android.libraries.mediaupload.api.MediaType
|
||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||
import java.io.File
|
||||
|
||||
|
|
@ -37,7 +36,7 @@ class FakeMediaPreProcessor : MediaPreProcessor {
|
|||
)
|
||||
)
|
||||
|
||||
override suspend fun process(uri: Uri, mediaType: MediaType, deleteOriginal: Boolean): Result<MediaUploadInfo> = result
|
||||
override suspend fun process(uri: Uri, mimeType: String, deleteOriginal: Boolean): Result<MediaUploadInfo> = result
|
||||
|
||||
fun givenResult(value: Result<MediaUploadInfo>) {
|
||||
this.result = value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue