Browse Source

Media: improve creation of LocalMedia

feature/fga/small_timeline_improvements
ganfra 1 year ago
parent
commit
7386936217
  1. 16
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/AndroidLocalMediaFactory.kt
  2. 23
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaFactory.kt
  3. 9
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt
  4. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt
  5. 6
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/FakeLocalMediaFactory.kt
  6. 13
      libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/file/Context.kt

16
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/AndroidLocalMediaFactory.kt

@ -18,15 +18,13 @@ package io.element.android.features.messages.impl.media.local @@ -18,15 +18,13 @@ package io.element.android.features.messages.impl.media.local
import android.content.Context
import android.net.Uri
import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.androidutils.file.getFileName
import io.element.android.libraries.androidutils.file.getFileSize
import io.element.android.libraries.androidutils.file.getMimeType
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.media.MediaFile
import io.element.android.libraries.matrix.api.media.toFile
import javax.inject.Inject
@ContributesBinding(AppScope::class)
@ -34,14 +32,9 @@ class AndroidLocalMediaFactory @Inject constructor( @@ -34,14 +32,9 @@ class AndroidLocalMediaFactory @Inject constructor(
@ApplicationContext private val context: Context
) : LocalMediaFactory {
override fun createFromMediaFile(mediaFile: MediaFile, mimeType: String?): LocalMedia {
val uri = mediaFile.toFile().toUri()
return createFromUri(uri, mimeType)
}
override fun createFromUri(uri: Uri, mimeType: String?): LocalMedia {
val resolvedMimeType = mimeType ?: context.contentResolver.getType(uri) ?: MimeTypes.OctetStream
val fileName = context.getFileName(uri)
override fun createFromUri(uri: Uri, mimeType: String?, name: String?): LocalMedia {
val resolvedMimeType = mimeType ?: context.getMimeType(uri) ?: MimeTypes.OctetStream
val fileName = name ?: context.getFileName(uri)
val fileSize = context.getFileSize(uri)
return LocalMedia(
uri = uri,
@ -51,3 +44,4 @@ class AndroidLocalMediaFactory @Inject constructor( @@ -51,3 +44,4 @@ class AndroidLocalMediaFactory @Inject constructor(
)
}
}

23
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaFactory.kt

@ -17,18 +17,29 @@ @@ -17,18 +17,29 @@
package io.element.android.features.messages.impl.media.local
import android.net.Uri
import androidx.core.net.toUri
import io.element.android.libraries.matrix.api.media.MediaFile
import io.element.android.libraries.matrix.api.media.toFile
interface LocalMediaFactory {
/**
* This method will create a [LocalMedia] with the given [MediaFile] and [mimeType].
*/
fun createFromMediaFile(mediaFile: MediaFile, mimeType: String?): LocalMedia
/**
* This method will create a [LocalMedia] with the given [uri] and [mimeType]
* If the [mimeType] is null, it'll try to read it from the content.
* If the [name] is null, it'll try to read it from the content.
*/
fun createFromUri(uri: Uri, mimeType: String?): LocalMedia
fun createFromUri(
uri: Uri,
mimeType: String?,
name: String?,
): LocalMedia
}
fun LocalMediaFactory.createFromMediaFile(
mediaFile: MediaFile,
mimeType: String?,
name: String?
): LocalMedia {
val uri = mediaFile.toFile().toUri()
return createFromUri(uri = uri, mimeType = mimeType, name = name)
}

9
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt

@ -30,6 +30,7 @@ import dagger.assisted.AssistedInject @@ -30,6 +30,7 @@ import dagger.assisted.AssistedInject
import io.element.android.features.messages.impl.media.local.LocalMedia
import io.element.android.features.messages.impl.media.local.LocalMediaActionsHandler
import io.element.android.features.messages.impl.media.local.LocalMediaFactory
import io.element.android.features.messages.impl.media.local.createFromMediaFile
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
@ -88,8 +89,12 @@ class MediaViewerPresenter @AssistedInject constructor( @@ -88,8 +89,12 @@ class MediaViewerPresenter @AssistedInject constructor(
mediaLoader.downloadMediaFile(inputs.mediaSource, inputs.mimeType)
.onSuccess {
mediaFile.value = it
}.mapCatching {
localMediaFactory.createFromMediaFile(it, inputs.mimeType)
}.mapCatching { mediaFile ->
localMediaFactory.createFromMediaFile(
mediaFile = mediaFile,
mimeType = inputs.mimeType,
name = inputs.name
)
}.onSuccess {
localMedia.value = Async.Success(it)
}.onFailure {

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt

@ -210,7 +210,7 @@ class MessageComposerPresenter @Inject constructor( @@ -210,7 +210,7 @@ class MessageComposerPresenter @Inject constructor(
attachmentsState.value = AttachmentsState.None
return
}
val localMedia = localMediaFactory.createFromUri(uri, mimeType)
val localMedia = localMediaFactory.createFromUri(uri, mimeType, null)
val mediaAttachment = Attachment.Media(localMedia, compressIfPossible)
val isPreviewable = when {
MimeTypes.isImage(localMedia.mimeType) -> true

6
features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/FakeLocalMediaFactory.kt

@ -27,11 +27,7 @@ class FakeLocalMediaFactory(private val localMediaUri: Uri) : LocalMediaFactory @@ -27,11 +27,7 @@ class FakeLocalMediaFactory(private val localMediaUri: Uri) : LocalMediaFactory
var fallbackMimeType: String = MimeTypes.OctetStream
override fun createFromMediaFile(mediaFile: MediaFile, mimeType: String?): LocalMedia {
return aLocalMedia(uri = localMediaUri, mimeType = mimeType ?: fallbackMimeType)
}
override fun createFromUri(uri: Uri, mimeType: String?): LocalMedia {
override fun createFromUri(uri: Uri, mimeType: String?, name: String?): LocalMedia {
return aLocalMedia(uri, mimeType ?: fallbackMimeType)
}
}

13
libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/file/Context.kt

@ -20,17 +20,24 @@ import android.content.ContentResolver @@ -20,17 +20,24 @@ import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import java.io.File
import androidx.core.net.toFile
fun Context.getMimeType(uri: Uri): String? = when (uri.scheme) {
ContentResolver.SCHEME_CONTENT -> contentResolver.getType(uri)
else -> null
}
fun Context.getFileName(uri: Uri): String? = when (uri.scheme) {
ContentResolver.SCHEME_CONTENT -> getContentFileName(uri)
else -> uri.path?.let(::File)?.name
ContentResolver.SCHEME_FILE -> uri.toFile().name
else -> null
}
fun Context.getFileSize(uri: Uri): Long {
return when (uri.scheme) {
ContentResolver.SCHEME_CONTENT -> getContentFileSize(uri)
else -> uri.path?.let(::File)?.length()
ContentResolver.SCHEME_FILE -> uri.toFile().length()
else -> 0
} ?: 0
}

Loading…
Cancel
Save