Media: change the API
This commit is contained in:
parent
c920dfb97a
commit
4b5ca3acdd
18 changed files with 242 additions and 212 deletions
|
|
@ -17,9 +17,13 @@
|
|||
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.MediaResolver
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
fun AvatarData.toMetadata(): MediaResolver.Meta {
|
||||
return MediaResolver.Meta(url = url, kind = MediaResolver.Kind.Thumbnail(size.dp.value.roundToInt()))
|
||||
fun AvatarData.toMediaRequestData(): MediaRequestData? {
|
||||
return url?.let {
|
||||
MediaRequestData(
|
||||
url = it,
|
||||
kind = MediaRequestData.Kind.Thumbnail(size.dp.value.roundToLong())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -22,20 +22,20 @@ import coil.fetch.Fetcher
|
|||
import coil.request.Options
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.media.MediaResolver
|
||||
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
internal class MediaFetcher(
|
||||
private val mediaResolver: MediaResolver,
|
||||
private val meta: MediaResolver.Meta,
|
||||
internal class CoilMediaFetcher(
|
||||
private val mediaLoader: MatrixMediaLoader,
|
||||
private val mediaData: MediaRequestData?,
|
||||
private val options: Options,
|
||||
private val imageLoader: ImageLoader
|
||||
) : Fetcher {
|
||||
|
||||
override suspend fun fetch(): FetchResult? {
|
||||
return mediaResolver.resolve(meta.url, meta.kind)
|
||||
.map { byteArray ->
|
||||
ByteBuffer.wrap(byteArray)
|
||||
return loadMedia()
|
||||
.map { data ->
|
||||
ByteBuffer.wrap(data)
|
||||
}.map { byteBuffer ->
|
||||
imageLoader.components.newFetcher(byteBuffer, options, imageLoader)?.first?.fetch()
|
||||
}
|
||||
|
|
@ -45,16 +45,28 @@ internal class MediaFetcher(
|
|||
)
|
||||
}
|
||||
|
||||
class MetaFactory(private val client: MatrixClient) :
|
||||
Fetcher.Factory<MediaResolver.Meta> {
|
||||
private suspend fun loadMedia(): Result<ByteArray> {
|
||||
if (mediaData == null) return Result.failure(IllegalStateException("No media data to fetch."))
|
||||
return when (mediaData.kind) {
|
||||
is MediaRequestData.Kind.Content -> mediaLoader.loadMediaContent(url = mediaData.url)
|
||||
is MediaRequestData.Kind.Thumbnail -> mediaLoader.loadMediaThumbnail(
|
||||
url = mediaData.url,
|
||||
width = mediaData.kind.width,
|
||||
height = mediaData.kind.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MediaRequestDataFactory(private val client: MatrixClient) :
|
||||
Fetcher.Factory<MediaRequestData> {
|
||||
override fun create(
|
||||
data: MediaResolver.Meta,
|
||||
data: MediaRequestData,
|
||||
options: Options,
|
||||
imageLoader: ImageLoader
|
||||
): Fetcher {
|
||||
return MediaFetcher(
|
||||
mediaResolver = client.mediaResolver(),
|
||||
meta = data,
|
||||
return CoilMediaFetcher(
|
||||
mediaLoader = client.mediaLoader,
|
||||
mediaData = data,
|
||||
options = options,
|
||||
imageLoader = imageLoader
|
||||
)
|
||||
|
|
@ -63,14 +75,15 @@ internal class MediaFetcher(
|
|||
|
||||
class AvatarFactory(private val client: MatrixClient) :
|
||||
Fetcher.Factory<AvatarData> {
|
||||
|
||||
override fun create(
|
||||
data: AvatarData,
|
||||
options: Options,
|
||||
imageLoader: ImageLoader
|
||||
): Fetcher {
|
||||
return MediaFetcher(
|
||||
mediaResolver = client.mediaResolver(),
|
||||
meta = data.toMetadata(),
|
||||
return CoilMediaFetcher(
|
||||
mediaLoader = client.mediaLoader,
|
||||
mediaData = data.toMediaRequestData(),
|
||||
options = options,
|
||||
imageLoader = imageLoader
|
||||
)
|
||||
|
|
@ -34,10 +34,10 @@ class LoggedInImageLoaderFactory @Inject constructor(
|
|||
.Builder(context)
|
||||
.okHttpClient(okHttpClient)
|
||||
.components {
|
||||
add(AvatarKeyer())
|
||||
add(MediaKeyer())
|
||||
add(MediaFetcher.AvatarFactory(matrixClient))
|
||||
add(MediaFetcher.MetaFactory(matrixClient))
|
||||
add(AvatarDataKeyer())
|
||||
add(MediaRequestDataKeyer())
|
||||
add(CoilMediaFetcher.AvatarFactory(matrixClient))
|
||||
add(CoilMediaFetcher.MediaRequestDataFactory(matrixClient))
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.matrix.ui.media
|
||||
|
||||
data class MediaRequestData(
|
||||
val url: String,
|
||||
val kind: Kind
|
||||
) {
|
||||
|
||||
sealed interface Kind {
|
||||
data class Thumbnail(val width: Long, val height: Long) : Kind {
|
||||
constructor(size: Long) : this(size, size)
|
||||
}
|
||||
|
||||
object Content : Kind
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -19,18 +19,17 @@ package io.element.android.libraries.matrix.ui.media
|
|||
import coil.key.Keyer
|
||||
import coil.request.Options
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.media.MediaResolver
|
||||
|
||||
internal class AvatarKeyer : Keyer<AvatarData> {
|
||||
internal class AvatarDataKeyer : Keyer<AvatarData> {
|
||||
override fun key(data: AvatarData, options: Options): String? {
|
||||
return data.toMetadata().toKey()
|
||||
return data.toMediaRequestData()?.toKey()
|
||||
}
|
||||
}
|
||||
|
||||
internal class MediaKeyer : Keyer<MediaResolver.Meta> {
|
||||
override fun key(data: MediaResolver.Meta, options: Options): String? {
|
||||
internal class MediaRequestDataKeyer : Keyer<MediaRequestData> {
|
||||
override fun key(data: MediaRequestData, options: Options): String? {
|
||||
return data.toKey()
|
||||
}
|
||||
}
|
||||
|
||||
private fun MediaResolver.Meta.toKey() = "${url}_${kind}"
|
||||
private fun MediaRequestData.toKey() = "${url}_${kind}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue