refactor: switch to coil for image loading (#388)
This commit is contained in:
parent
3fc72bf8b3
commit
1399c77b5d
7 changed files with 44 additions and 75 deletions
|
@ -108,7 +108,8 @@ dependencies {
|
|||
implementation(libs.androidx.room.ktx)
|
||||
implementation(libs.androidx.swiperefreshlayout)
|
||||
implementation(libs.androidx.work)
|
||||
implementation(libs.glide)
|
||||
implementation(libs.coil)
|
||||
implementation(libs.coil.svg)
|
||||
implementation(libs.hilt.android)
|
||||
kapt(libs.hilt.compiler)
|
||||
implementation(libs.jellyfin.core)
|
||||
|
|
|
@ -4,13 +4,18 @@ import android.app.Application
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import coil.decode.SvgDecoder
|
||||
import coil.disk.DiskCache
|
||||
import coil.request.CachePolicy
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
@HiltAndroidApp
|
||||
class BaseApplication : Application(), Configuration.Provider {
|
||||
class BaseApplication : Application(), Configuration.Provider, ImageLoaderFactory {
|
||||
@Inject
|
||||
lateinit var appPreferences: AppPreferences
|
||||
|
||||
|
@ -37,4 +42,19 @@ class BaseApplication : Application(), Configuration.Provider {
|
|||
|
||||
if (appPreferences.dynamicColors) DynamicColors.applyToActivitiesIfAvailable(this)
|
||||
}
|
||||
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
return ImageLoader.Builder(this)
|
||||
.components {
|
||||
add(SvgDecoder.Factory())
|
||||
}
|
||||
.diskCachePolicy(if (appPreferences.imageCache) CachePolicy.ENABLED else CachePolicy.DISABLED)
|
||||
.diskCache {
|
||||
DiskCache.Builder()
|
||||
.directory(this.cacheDir.resolve("image_cache"))
|
||||
.maxSizeBytes(appPreferences.imageCacheSize * 1024L * 1024)
|
||||
.build()
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ import android.widget.ImageView
|
|||
import androidx.annotation.DrawableRes
|
||||
import androidx.databinding.BindingAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import coil.load
|
||||
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
|
||||
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||
|
@ -49,7 +48,6 @@ fun bindItemImage(imageView: ImageView, item: BaseItemDto) {
|
|||
fun bindItemImage(imageView: ImageView, item: FindroidItem) {
|
||||
val itemId = when (item) {
|
||||
is FindroidEpisode -> item.seriesId
|
||||
// is JellyfinSeasonItem && item.imageTags.isNullOrEmpty() -> item.seriesId
|
||||
else -> item.id
|
||||
}
|
||||
|
||||
|
@ -111,18 +109,15 @@ fun bindUserImage(imageView: ImageView, user: User) {
|
|||
|
||||
private fun ImageView.loadImage(
|
||||
url: String,
|
||||
@DrawableRes placeholderId: Int = CoreR.color.neutral_800,
|
||||
@DrawableRes errorPlaceHolderId: Int? = null
|
||||
@DrawableRes placeholderId: Int = CoreR.color.neutral_800
|
||||
): View {
|
||||
val api = JellyfinApi.getInstance(context.applicationContext)
|
||||
|
||||
Glide
|
||||
.with(context)
|
||||
.load("${api.api.baseUrl}$url")
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.placeholder(placeholderId)
|
||||
.error(errorPlaceHolderId)
|
||||
.into(this)
|
||||
this.load("${api.api.baseUrl}$url") {
|
||||
crossfade(true)
|
||||
placeholder(placeholderId)
|
||||
error(placeholderId)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package dev.jdtech.jellyfin.utils
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.ui.TimeBar
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import dev.jdtech.jellyfin.utils.bif.BifData
|
||||
import dev.jdtech.jellyfin.utils.bif.BifUtil
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -19,7 +20,8 @@ class PreviewScrubListener(
|
|||
private val currentTrickPlay: StateFlow<BifData?>
|
||||
) : TimeBar.OnScrubListener {
|
||||
|
||||
private val roundedCorners = RoundedCorners(10)
|
||||
private val roundedCorners = RoundedCornersTransformation(10f)
|
||||
private var currentBitMap: Bitmap? = null
|
||||
|
||||
override fun onScrubStart(timeBar: TimeBar, position: Long) {
|
||||
Timber.d("Scrubbing started at $position")
|
||||
|
@ -54,10 +56,12 @@ class PreviewScrubListener(
|
|||
|
||||
scrubbingPreview.x = layoutX
|
||||
|
||||
Glide.with(scrubbingPreview)
|
||||
.load(image)
|
||||
.transform(roundedCorners)
|
||||
.into(scrubbingPreview)
|
||||
if (currentBitMap != image) {
|
||||
scrubbingPreview.load(image) {
|
||||
transformations(roundedCorners)
|
||||
}
|
||||
currentBitMap = image
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScrubStop(timeBar: TimeBar, position: Long, canceled: Boolean) {
|
||||
|
|
|
@ -62,8 +62,6 @@ dependencies {
|
|||
kapt(libs.androidx.room.compiler)
|
||||
implementation(libs.androidx.room.ktx)
|
||||
implementation(libs.androidx.work)
|
||||
implementation(libs.glide)
|
||||
kapt(libs.glide.compiler)
|
||||
implementation(libs.hilt.android)
|
||||
kapt(libs.hilt.compiler)
|
||||
implementation(libs.jellyfin.core)
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package dev.jdtech.jellyfin.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.bumptech.glide.GlideBuilder
|
||||
import com.bumptech.glide.annotation.GlideModule
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy.NONE
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy.RESOURCE
|
||||
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
||||
import com.bumptech.glide.module.AppGlideModule
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@GlideModule
|
||||
class GlideModule : AppGlideModule() {
|
||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||
val preferences = AppPreferences(PreferenceManager.getDefaultSharedPreferences(context))
|
||||
val use = preferences.imageCache
|
||||
|
||||
if (use) {
|
||||
val sizeMb = preferences.imageCacheSize
|
||||
val sizeB = 1024L * 1024 * sizeMb
|
||||
Timber.d("Setting image cache to use $sizeMb MB of disk space")
|
||||
|
||||
builder.setDiskCache(InternalCacheDiskCacheFactory(context, sizeB))
|
||||
builder.caching(enabled = true)
|
||||
} else {
|
||||
builder.caching(enabled = false)
|
||||
Timber.d("Image cache disabled. Clearing all persisted data.")
|
||||
|
||||
MainScope().launch {
|
||||
GlideApp.getPhotoCacheDir(context)?.also {
|
||||
if (it.exists()) it.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun GlideBuilder.caching(enabled: Boolean) {
|
||||
setDefaultRequestOptions(
|
||||
RequestOptions().diskCacheStrategy(
|
||||
if (enabled) RESOURCE else NONE
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ androidx-recyclerview-selection = "1.1.0"
|
|||
androidx-room = "2.5.1"
|
||||
androidx-swiperefreshlayout = "1.1.0"
|
||||
androidx-work = "2.8.1"
|
||||
glide = "4.15.1"
|
||||
coil = "2.4.0"
|
||||
hilt = "2.46.1"
|
||||
jellyfin = "1.4.2"
|
||||
kotlin = "1.8.21"
|
||||
|
@ -55,8 +55,8 @@ androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref =
|
|||
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "androidx-room" }
|
||||
androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" }
|
||||
androidx-work = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work" }
|
||||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||
glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" }
|
||||
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
|
||||
coil-svg = { module = "io.coil-kt:coil-svg", version.ref = "coil" }
|
||||
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
|
||||
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
||||
jellyfin-core = { module = "org.jellyfin.sdk:jellyfin-core", version.ref = "jellyfin" }
|
||||
|
|
Loading…
Reference in a new issue