diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index ea6f61a8a9..d2ce34b726 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi import android.Manifest import android.annotation.SuppressLint +import android.app.ActivityManager import android.app.Application import android.app.PendingIntent import android.content.BroadcastReceiver @@ -15,6 +16,7 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.core.app.ActivityCompat import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat +import androidx.core.content.getSystemService import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner @@ -23,13 +25,24 @@ import androidx.multidex.MultiDex import coil3.ImageLoader import coil3.PlatformContext import coil3.SingletonImageLoader +import coil3.memory.MemoryCache +import coil3.network.okhttp.OkHttpNetworkFetcherFactory +import coil3.request.allowHardware +import coil3.request.allowRgb565 +import coil3.request.crossfade +import coil3.util.DebugLogger import dev.yokai.domain.AppState import eu.kanade.tachiyomi.appwidget.TachiyomiWidgetManager -import eu.kanade.tachiyomi.data.image.coil.CoilSetup +import eu.kanade.tachiyomi.data.image.coil.CoilDiskCache +import eu.kanade.tachiyomi.data.image.coil.InputStreamFetcher +import eu.kanade.tachiyomi.data.image.coil.MangaCoverFetcher +import eu.kanade.tachiyomi.data.image.coil.MangaCoverKeyer +import eu.kanade.tachiyomi.data.image.coil.TachiyomiImageDecoder import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.di.AppModule import eu.kanade.tachiyomi.di.PreferenceModule +import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.ui.library.LibraryPresenter import eu.kanade.tachiyomi.ui.recents.RecentsPresenter import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate @@ -44,6 +57,7 @@ import kotlinx.coroutines.flow.onEach import org.conscrypt.Conscrypt import timber.log.Timber import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import java.security.Security @@ -175,7 +189,25 @@ open class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.F } override fun newImageLoader(context: PlatformContext): ImageLoader { - return CoilSetup.setup(this@App) + return ImageLoader.Builder(this@App).apply { + val callFactoryLazy = lazy { Injekt.get().client } + val diskCacheLazy = lazy { CoilDiskCache.get(this@App) } + components { + add(OkHttpNetworkFetcherFactory(callFactoryLazy::value)) + add(TachiyomiImageDecoder.Factory()) + add(MangaCoverFetcher.Factory(callFactoryLazy, diskCacheLazy)) + add(MangaCoverKeyer()) + add(InputStreamFetcher.Factory()) + } + diskCache(diskCacheLazy::value) + memoryCache { MemoryCache.Builder().maxSizePercent(this@App, 0.40).build() } + crossfade(true) + allowRgb565(this@App.getSystemService()!!.isLowRamDevice) + allowHardware(true) + if (BuildConfig.DEBUG) { + logger(DebugLogger()) + } + }.build() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilDiskCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilDiskCache.kt new file mode 100644 index 0000000000..03541426e5 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilDiskCache.kt @@ -0,0 +1,26 @@ +package eu.kanade.tachiyomi.data.image.coil + +import android.content.Context +import coil3.disk.DiskCache +import coil3.disk.directory + +/** + * Direct copy of Coil's internal SingletonDiskCache so that [MangaCoverFetcher] can access it. + */ +object CoilDiskCache { + + private const val FOLDER_NAME = "image_cache" + private var instance: DiskCache? = null + + @Synchronized + fun get(context: Context): DiskCache { + return instance ?: run { + val safeCacheDir = context.cacheDir.apply { mkdirs() } + // Create the singleton disk cache instance. + DiskCache.Builder() + .directory(safeCacheDir.resolve(FOLDER_NAME)) + .build() + .also { instance = it } + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilSetup.kt b/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilSetup.kt deleted file mode 100644 index 4a7864cc89..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/data/image/coil/CoilSetup.kt +++ /dev/null @@ -1,65 +0,0 @@ -package eu.kanade.tachiyomi.data.image.coil - -import android.app.ActivityManager -import android.content.Context -import androidx.core.content.getSystemService -import coil3.ImageLoader -import coil3.disk.DiskCache -import coil3.disk.directory -import coil3.memory.MemoryCache -import coil3.network.okhttp.OkHttpNetworkFetcherFactory -import coil3.request.allowHardware -import coil3.request.allowRgb565 -import coil3.request.crossfade -import coil3.util.DebugLogger -import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.network.NetworkHelper -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get - -class CoilSetup { - companion object { - fun setup(context: Context): ImageLoader { - return ImageLoader.Builder(context).apply { - val callFactoryLazy = lazy { Injekt.get().client } - val diskCacheLazy = lazy { CoilDiskCache.get(context) } - components { - add(OkHttpNetworkFetcherFactory(callFactoryLazy::value)) - add(TachiyomiImageDecoder.Factory()) - add(MangaCoverFetcher.Factory(callFactoryLazy, diskCacheLazy)) - add(MangaCoverKeyer()) - add(InputStreamFetcher.Factory()) - } - diskCache(diskCacheLazy::value) - memoryCache { MemoryCache.Builder().maxSizePercent(context, 0.40).build() } - crossfade(true) - allowRgb565(context.getSystemService()!!.isLowRamDevice) - allowHardware(true) - if (BuildConfig.DEBUG) { - logger(DebugLogger()) - } - }.build() - } - } -} - -/** - * Direct copy of Coil's internal SingletonDiskCache so that [MangaCoverFetcher] can access it. - */ -internal object CoilDiskCache { - - private const val FOLDER_NAME = "image_cache" - private var instance: DiskCache? = null - - @Synchronized - fun get(context: Context): DiskCache { - return instance ?: run { - val safeCacheDir = context.cacheDir.apply { mkdirs() } - // Create the singleton disk cache instance. - DiskCache.Builder() - .directory(safeCacheDir.resolve(FOLDER_NAME)) - .build() - .also { instance = it } - } - } -}