Skip to content

Commit

Permalink
Upgrade to Coil 3
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsvanvelzen committed Nov 10, 2024
1 parent 91a27ee commit 9acf4e3
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package org.jellyfin.androidtv.data.service
import android.content.Context
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.core.graphics.drawable.toBitmap
import coil.ImageLoader
import coil.request.ImageRequest
import coil3.ImageLoader
import coil3.request.ImageRequest
import coil3.toBitmap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
Expand Down Expand Up @@ -124,7 +124,7 @@ class BackgroundService(
_backgrounds = backdropUrls.mapNotNull { url ->
imageLoader.execute(
request = ImageRequest.Builder(context).data(url).build()
).drawable?.toBitmap()?.asImageBitmap()
).image?.toBitmap()?.asImageBitmap()
}

// Go to first background
Expand Down
14 changes: 9 additions & 5 deletions app/src/main/java/org/jellyfin/androidtv/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package org.jellyfin.androidtv.di

import android.content.Context
import android.os.Build
import coil.ImageLoader
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import coil3.ImageLoader
import coil3.gif.AnimatedImageDecoder
import coil3.gif.GifDecoder
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import coil3.serviceLoaderEnabled
import coil3.svg.SvgDecoder
import org.jellyfin.androidtv.BuildConfig
import org.jellyfin.androidtv.auth.repository.ServerRepository
import org.jellyfin.androidtv.auth.repository.UserRepository
Expand Down Expand Up @@ -103,8 +105,10 @@ val appModule = module {
// Coil (images)
single {
ImageLoader.Builder(androidContext()).apply {
serviceLoaderEnabled(false)
components {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) add(ImageDecoderDecoder.Factory())
add(OkHttpNetworkFetcherFactory())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) add(AnimatedImageDecoder.Factory())
else add(GifDecoder.Factory())
add(SvgDecoder.Factory())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package org.jellyfin.androidtv.integration.dream

import android.annotation.SuppressLint
import android.content.Context
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import coil.ImageLoader
import coil.request.ImageRequest
import coil3.ImageLoader
import coil3.request.ImageRequest
import coil3.toBitmap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
Expand Down Expand Up @@ -123,13 +123,13 @@ class DreamViewModel(
val logoDeferred = async {
imageLoader.execute(
request = ImageRequest.Builder(context).data(logoUrl).build()
).drawable?.toBitmap()
).image?.toBitmap()
}

val backdropDeferred = async {
imageLoader.execute(
request = ImageRequest.Builder(context).data(backdropUrl).build()
).drawable?.toBitmap()
).image?.toBitmap()
}

awaitAll(logoDeferred, backdropDeferred)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import android.os.Build
import android.os.ParcelFileDescriptor
import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import coil.ImageLoader
import coil.request.ImageRequest
import coil3.ImageLoader
import coil3.asDrawable
import coil3.request.ImageRequest
import org.jellyfin.androidtv.BuildConfig
import org.jellyfin.androidtv.R
import org.koin.android.ext.android.inject
Expand All @@ -37,8 +38,8 @@ class ImageProvider : ContentProvider() {
data(src)
error(R.drawable.placeholder_icon)
target(
onSuccess = { drawable -> writeDrawable(drawable, outputStream) },
onError = { drawable -> writeDrawable(requireNotNull(drawable), outputStream) }
onSuccess = { image -> writeDrawable(image.asDrawable(context!!.resources), outputStream) },
onError = { image -> writeDrawable(requireNotNull(image?.asDrawable(context!!.resources)), outputStream) }
)
}.build())

Expand Down
14 changes: 9 additions & 5 deletions app/src/main/java/org/jellyfin/androidtv/ui/AsyncImageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.doOnAttach
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.lifecycleScope
import coil.ImageLoader
import coil.request.ImageRequest
import coil.transform.CircleCropTransformation
import coil3.ImageLoader
import coil3.asImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import coil3.request.target
import coil3.request.transformations
import coil3.transform.CircleCropTransformation
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -88,9 +92,9 @@ class AsyncImageView @JvmOverloads constructor(

target(this@AsyncImageView)
data(url)
placeholder(placeholderOrBlurHash)
placeholder(placeholderOrBlurHash?.asImage())
if (circleCrop) transformations(CircleCropTransformation())
error(placeholder)
error(placeholder?.asImage())
}.build())
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package org.jellyfin.androidtv.ui.playback.overlay

import android.content.Context
import androidx.core.graphics.drawable.toBitmap
import androidx.leanback.widget.PlaybackSeekDataProvider
import coil.ImageLoader
import coil.request.Disposable
import coil.request.ImageRequest
import coil.size.Size
import coil3.ImageLoader
import coil3.network.NetworkHeaders
import coil3.network.httpHeaders
import coil3.request.Disposable
import coil3.request.ImageRequest
import coil3.request.transformations
import coil3.size.Size
import coil3.toBitmap
import org.jellyfin.androidtv.util.coil.SubsetTransformation
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.trickplayApi
Expand Down Expand Up @@ -70,22 +73,24 @@ class CustomSeekProvider(
imageRequests[index] = imageLoader.enqueue(ImageRequest.Builder(context).apply {
data(url)
size(Size.ORIGINAL)
addHeader(
"Authorization",
AuthorizationHeaderBuilder.buildHeader(
api.clientInfo.name,
api.clientInfo.version,
api.deviceInfo.id,
api.deviceInfo.name,
api.accessToken
httpHeaders(NetworkHeaders.Builder().apply {
set(
key = "Authorization",
value = AuthorizationHeaderBuilder.buildHeader(
api.clientInfo.name,
api.clientInfo.version,
api.deviceInfo.id,
api.deviceInfo.name,
api.accessToken
)
)
)
}.build())

transformations(SubsetTransformation(offsetX, offsetY, trickPlayInfo.width, trickPlayInfo.height))

target(
onSuccess = { result ->
val bitmap = result.current.toBitmap()
onSuccess = { image ->
val bitmap = image.toBitmap()
callback.onThumbnailLoaded(bitmap, index)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import org.jellyfin.androidtv.ui.playback.PlaybackControllerContainer;
import org.jellyfin.sdk.api.client.ApiClient;

import coil.ImageLoader;
import coil3.ImageLoader;
import kotlin.Lazy;
import timber.log.Timber;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.jellyfin.androidtv.ui.preference.screen

import android.text.format.Formatter
import coil.ImageLoader
import coil.annotation.ExperimentalCoilApi
import coil3.ImageLoader
import coil3.annotation.ExperimentalCoilApi
import org.jellyfin.androidtv.BuildConfig
import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.preference.SystemPreferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.jellyfin.androidtv.util.coil

import android.graphics.Bitmap
import coil.size.Size
import coil.transform.Transformation
import coil3.size.Size
import coil3.transform.Transformation

class SubsetTransformation(
private val x: Int,
private val y: Int,
private val width: Int,
private val height: Int,
) : Transformation {
) : Transformation() {
override val cacheKey: String = "$x,$y,$width,$height"

override suspend fun transform(
Expand Down
12 changes: 7 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ androidx-tv = "1.0.0"
androidx-tvprovider = "1.1.0-alpha01"
androidx-window = "1.3.0"
androidx-work = "2.9.1"
coil = "2.7.0"
coil = "3.0.2"
detekt = "1.23.7"
java-jdk = "21"
jellyfin-androidx-media = "1.3.1+2"
Expand Down Expand Up @@ -101,9 +101,10 @@ markwon-core = { module = "io.noties.markwon:core", version.ref = "markwon" }
markwon-html = { module = "io.noties.markwon:html", version.ref = "markwon" }

# Image utility
coil-base = { module = "io.coil-kt:coil-base", version.ref = "coil" }
coil-gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" }
coil-svg = { module = "io.coil-kt:coil-svg", version.ref = "coil" }
coil-core = { module = "io.coil-kt.coil3:coil-core", version.ref = "coil" }
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" }
coil-svg = { module = "io.coil-kt.coil3:coil-svg", version.ref = "coil" }

# Crash Reporting
acra-core = { module = "ch.acra:acra-core", version.ref = "acra" }
Expand Down Expand Up @@ -141,7 +142,8 @@ androidx-lifecycle = [
"androidx-lifecycle-viewmodel",
]
coil = [
"coil-base",
"coil-core",
"coil-network-okhttp",
"coil-gif",
"coil-svg",
]
Expand Down

0 comments on commit 9acf4e3

Please sign in to comment.