Migrate to coil3
This commit is contained in:
parent
491bb1d8fe
commit
a70249769d
43 changed files with 148 additions and 117 deletions
|
|
@ -24,8 +24,8 @@ import androidx.compose.ui.graphics.painter.ColorPainter
|
|||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.request.ImageRequest
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.ImageLoader
|
||||
import coil.fetch.Fetcher
|
||||
import coil.request.Options
|
||||
import coil3.ImageLoader
|
||||
import coil3.fetch.Fetcher
|
||||
import coil3.request.Options
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
|
||||
|
|
@ -24,7 +24,6 @@ internal class AvatarDataFetcherFactory(
|
|||
return CoilMediaFetcher(
|
||||
mediaLoader = client.mediaLoader,
|
||||
mediaData = data.toMediaRequestData(),
|
||||
options = options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.decode.DataSource
|
||||
import coil.decode.ImageSource
|
||||
import coil.fetch.FetchResult
|
||||
import coil.fetch.Fetcher
|
||||
import coil.fetch.SourceResult
|
||||
import coil.request.Options
|
||||
import coil3.decode.DataSource
|
||||
import coil3.decode.ImageSource
|
||||
import coil3.fetch.FetchResult
|
||||
import coil3.fetch.Fetcher
|
||||
import coil3.fetch.SourceFetchResult
|
||||
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.matrix.api.media.toFile
|
||||
import okio.Buffer
|
||||
import okio.FileSystem
|
||||
import okio.Path.Companion.toOkioPath
|
||||
import timber.log.Timber
|
||||
import java.nio.ByteBuffer
|
||||
|
|
@ -24,7 +24,6 @@ import java.nio.ByteBuffer
|
|||
internal class CoilMediaFetcher(
|
||||
private val mediaLoader: MatrixMediaLoader,
|
||||
private val mediaData: MediaRequestData,
|
||||
private val options: Options
|
||||
) : Fetcher {
|
||||
override suspend fun fetch(): FetchResult? {
|
||||
if (mediaData.source == null) {
|
||||
|
|
@ -32,8 +31,8 @@ internal class CoilMediaFetcher(
|
|||
return null
|
||||
}
|
||||
return when (mediaData.kind) {
|
||||
is MediaRequestData.Kind.Content -> fetchContent(mediaData.source, options)
|
||||
is MediaRequestData.Kind.Thumbnail -> fetchThumbnail(mediaData.source, mediaData.kind, options)
|
||||
is MediaRequestData.Kind.Content -> fetchContent(mediaData.source)
|
||||
is MediaRequestData.Kind.Thumbnail -> fetchThumbnail(mediaData.source, mediaData.kind)
|
||||
is MediaRequestData.Kind.File -> fetchFile(mediaData.source, mediaData.kind)
|
||||
}
|
||||
}
|
||||
|
|
@ -47,8 +46,12 @@ internal class CoilMediaFetcher(
|
|||
return mediaLoader.downloadMediaFile(mediaSource, kind.mimeType, kind.fileName)
|
||||
.map { mediaFile ->
|
||||
val file = mediaFile.toFile()
|
||||
SourceResult(
|
||||
source = ImageSource(file = file.toOkioPath(), closeable = mediaFile),
|
||||
SourceFetchResult(
|
||||
source = ImageSource(
|
||||
file = file.toOkioPath(),
|
||||
fileSystem = FileSystem.SYSTEM,
|
||||
closeable = mediaFile,
|
||||
),
|
||||
mimeType = null,
|
||||
dataSource = DataSource.DISK
|
||||
)
|
||||
|
|
@ -59,37 +62,40 @@ internal class CoilMediaFetcher(
|
|||
.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun fetchContent(mediaSource: MediaSource, options: Options): FetchResult? {
|
||||
private suspend fun fetchContent(mediaSource: MediaSource): FetchResult? {
|
||||
return mediaLoader.loadMediaContent(
|
||||
source = mediaSource,
|
||||
).map { byteArray ->
|
||||
byteArray.asSourceResult(options)
|
||||
byteArray.asSourceResult()
|
||||
}.onFailure {
|
||||
Timber.e(it)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun fetchThumbnail(mediaSource: MediaSource, kind: MediaRequestData.Kind.Thumbnail, options: Options): FetchResult? {
|
||||
private suspend fun fetchThumbnail(mediaSource: MediaSource, kind: MediaRequestData.Kind.Thumbnail): FetchResult? {
|
||||
return mediaLoader.loadMediaThumbnail(
|
||||
source = mediaSource,
|
||||
width = kind.width,
|
||||
height = kind.height,
|
||||
).map { byteArray ->
|
||||
byteArray.asSourceResult(options)
|
||||
byteArray.asSourceResult()
|
||||
}.onFailure {
|
||||
Timber.e(it)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private fun ByteArray.asSourceResult(options: Options): SourceResult {
|
||||
private fun ByteArray.asSourceResult(): SourceFetchResult {
|
||||
val byteBuffer = ByteBuffer.wrap(this)
|
||||
val bufferedSource = try {
|
||||
Buffer().apply { write(byteBuffer) }
|
||||
} finally {
|
||||
byteBuffer.position(0)
|
||||
}
|
||||
return SourceResult(
|
||||
source = ImageSource(bufferedSource, options.context),
|
||||
return SourceFetchResult(
|
||||
source = ImageSource(
|
||||
source = bufferedSource,
|
||||
fileSystem = FileSystem.SYSTEM,
|
||||
),
|
||||
mimeType = null,
|
||||
dataSource = DataSource.MEMORY
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ package io.element.android.libraries.matrix.ui.media
|
|||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import coil.decode.GifDecoder
|
||||
import coil.decode.ImageDecoderDecoder
|
||||
import coil3.ImageLoader
|
||||
import coil3.gif.AnimatedImageDecoder
|
||||
import coil3.gif.GifDecoder
|
||||
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
|
|
@ -33,11 +33,17 @@ class DefaultLoggedInImageLoaderFactory @Inject constructor(
|
|||
override fun newImageLoader(matrixClient: MatrixClient): ImageLoader {
|
||||
return ImageLoader
|
||||
.Builder(context)
|
||||
.okHttpClient { okHttpClient.get() }
|
||||
.components {
|
||||
add(
|
||||
OkHttpNetworkFetcherFactory(
|
||||
callFactory = {
|
||||
okHttpClient.get()
|
||||
}
|
||||
)
|
||||
)
|
||||
// Add gif support
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
add(ImageDecoderDecoder.Factory())
|
||||
add(AnimatedImageDecoder.Factory())
|
||||
} else {
|
||||
add(GifDecoder.Factory())
|
||||
}
|
||||
|
|
@ -53,11 +59,19 @@ class DefaultLoggedInImageLoaderFactory @Inject constructor(
|
|||
class NotLoggedInImageLoaderFactory @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val okHttpClient: Provider<OkHttpClient>,
|
||||
) : ImageLoaderFactory {
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
) {
|
||||
fun newImageLoader(): ImageLoader {
|
||||
return ImageLoader
|
||||
.Builder(context)
|
||||
.okHttpClient { okHttpClient.get() }
|
||||
.components {
|
||||
add(
|
||||
OkHttpNetworkFetcherFactory(
|
||||
callFactory = {
|
||||
okHttpClient.get()
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.ImageLoader
|
||||
import coil3.ImageLoader
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.ui.media
|
|||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
|
||||
/**
|
||||
* Can be use with [coil.compose.AsyncImage] to load a [MediaSource].
|
||||
* Can be use with [coil3.compose.AsyncImage] to load a [MediaSource].
|
||||
* This will go internally through our [CoilMediaFetcher].
|
||||
*
|
||||
* Example of usage:
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.ImageLoader
|
||||
import coil.fetch.Fetcher
|
||||
import coil.request.Options
|
||||
import coil3.ImageLoader
|
||||
import coil3.fetch.Fetcher
|
||||
import coil3.request.Options
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
|
||||
internal class MediaRequestDataFetcherFactory(
|
||||
|
|
@ -23,7 +23,6 @@ internal class MediaRequestDataFetcherFactory(
|
|||
return CoilMediaFetcher(
|
||||
mediaLoader = client.mediaLoader,
|
||||
mediaData = data,
|
||||
options = options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.key.Keyer
|
||||
import coil.request.Options
|
||||
import coil3.key.Keyer
|
||||
import coil3.request.Options
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
|
||||
internal class AvatarDataKeyer : Keyer<AvatarData> {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import coil.ImageLoader
|
||||
import coil3.ImageLoader
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.media
|
||||
|
||||
import coil.ImageLoader
|
||||
import coil3.ImageLoader
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
|
||||
class FakeLoggedInImageLoaderFactory(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue