Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add singleton image loader, remove unused libs, increase disk & decrease memory cache #1396

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 13 additions & 22 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import java.io.ByteArrayOutputStream

plugins {
id("com.android.application")
id("com.google.devtools.ksp")
id("kotlin-android")
id("org.jetbrains.dokka")
}
Expand Down Expand Up @@ -84,11 +83,6 @@ android {
"\"" + (System.getenv("SIMKL_CLIENT_SECRET") ?: localProperties["simkl.secret"]) + "\""
)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("exportSchema", "true")
}
}

buildTypes {
Expand Down Expand Up @@ -160,25 +154,22 @@ dependencies {
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")

// Android Core & Lifecycle
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.core:core-ktx:1.13.1") // need sdk 35 and agp 8.2 for 1.15
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.3")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.8.3")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
implementation("androidx.navigation:navigation-fragment-ktx:2.8.3")

// Design & UI
implementation("jp.wasabeef:glide-transformations:4.3.0")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("io.coil-kt:coil:2.7.0") // Coil Image Loading

// For KSP -> Official Annotation Processors are Not Yet Supported for KSP
ksp("dev.zacsweers.autoservice:auto-service-ksp:1.2.0")
implementation("com.google.guava:guava:33.2.1-android")
implementation("dev.zacsweers.autoservice:auto-service-ksp:1.2.0")
// Coil Image Loading
implementation("io.coil-kt.coil3:coil:3.0.3")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.3")

// Media 3 (ExoPlayer)
implementation("androidx.media3:media3-ui:1.4.1")
Expand All @@ -194,7 +185,7 @@ dependencies {
// PlayBack
implementation("com.jaredrummler:colorpicker:1.1.0") // Subtitle Color Picker
implementation("com.github.recloudstream:media-ffmpeg:1.1.0") // Custom FF-MPEG Lib for Audio Codecs
implementation("com.github.teamnewpipe:NewPipeExtractor:v0.24.2") /* For Trailers
implementation("com.github.teamnewpipe:NewPipeExtractor:abba78c") /* For Trailers
^ Update to Latest Commits if Trailers Misbehave, github.com/TeamNewPipe/NewPipeExtractor/commits/dev */
implementation("com.github.albfernandez:juniversalchardet:2.5.0") // Subtitle Decoding

Expand All @@ -217,14 +208,14 @@ dependencies {
implementation("com.github.LagradOst:SafeFile:0.0.6") // To Prevent the URI File Fu*kery
implementation("org.conscrypt:conscrypt-android:2.5.2") // To Fix SSL Fu*kery on Android 9
implementation("com.uwetrottmann.tmdb2:tmdb-java:2.11.0") // TMDB API v3 Wrapper Made with RetroFit
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs_nio:2.0.4") //nio flavor needed for NewPipeExtractor
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs_nio:2.1.2") //nio flavor needed for NewPipeExtractor
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1") /* JSON Parser
^ Don't Bump Jackson above 2.13.1 , Crashes on Android TV's and FireSticks that have Min API
Level 25 or Less. */

// Downloading & Networking
implementation("androidx.work:work-runtime:2.9.0")
implementation("androidx.work:work-runtime-ktx:2.9.0")
implementation("androidx.work:work-runtime:2.9.1") // need sdk 35 and agp 8.2 for 1.15
implementation("androidx.work:work-runtime-ktx:2.9.1") // need sdk 35 and agp 8.2 for 1.15
implementation("com.github.Blatzar:NiceHttp:0.4.11") // HTTP Lib

implementation(project(":library") {
Expand Down
13 changes: 11 additions & 2 deletions app/src/main/java/com/lagradost/cloudstream3/AcraApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import android.content.Intent
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import coil3.PlatformContext
import coil3.SingletonImageLoader
import com.lagradost.api.setContext
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
Expand Down Expand Up @@ -98,11 +100,13 @@ class ExceptionHandler(val errorFile: File, val onError: (() -> Unit)) :

}

class AcraApplication : Application() {
class AcraApplication : Application(), SingletonImageLoader.Factory {

override fun onCreate() {
super.onCreate()
ImageLoader.initializeCoilImageLoader(this)
// if we want to initialise coil at earliest
// (maybe when loading an image or gif using in splash screen activity)
//ImageLoader.buildImageLoader(applicationContext)

ExceptionHandler(filesDir.resolve("last_error")) {
val intent = context!!.packageManager.getLaunchIntentForPackage(context!!.packageName)
Expand Down Expand Up @@ -137,6 +141,11 @@ class AcraApplication : Application() {
}
}

override fun newImageLoader(context: PlatformContext): coil3.ImageLoader {
// Coil Module will be initialized & setSafe globally when first loadImage() is invoked
return ImageLoader.buildImageLoader(applicationContext)
}

companion object {
var exceptionHandler: ExceptionHandler? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ import java.security.Security

fun Requests.initClient(context: Context): OkHttpClient {
normalSafeApiCall { Security.insertProviderAt(Conscrypt.newProvider(), 1) }
return buildDefaultClient(context)
}

fun buildDefaultClient(context: Context): OkHttpClient {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(context)
val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0)
baseClient = OkHttpClient.Builder()
val baseClient = OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.ignoreAllSSLErrors()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import coil.transform.RoundedCornersTransformation
import coil3.transform.RoundedCornersTransformation
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AccountListItemAddBinding
import com.lagradost.cloudstream3.databinding.AccountListItemBinding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
import com.lagradost.cloudstream3.MainActivity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.isVisible
import androidx.palette.graphics.Palette
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.PlayerQualityProfileItemBinding
import com.lagradost.cloudstream3.utils.AppContextUtils
import com.lagradost.cloudstream3.utils.ImageLoader.loadImage
import com.lagradost.cloudstream3.utils.drawableToBitmap

class ProfilesAdapter(
override val items: MutableList<QualityDataHelper.QualityProfile>,
Expand Down Expand Up @@ -81,21 +81,24 @@ class ProfilesAdapter(
}

outline.isVisible = currentItem?.second?.id == item.id

profileBg.loadImage(art[index % art.size]) {
target { drawable ->
// Convert drawable to bitmap to extract palette colors
val bitmap = drawable.toBitmap()

val drawableResId = art[index % art.size]
profileBg.loadImage(drawableResId)

val drawable = ContextCompat.getDrawable(itemView.context, drawableResId)
if (drawable != null) {
// Convert Drawable to Bitmap
val bitmap = drawableToBitmap(drawable)
if (bitmap != null) {
// Use Palette to extract colors from the bitmap
Palette.from(bitmap).generate { palette ->
palette?.let {
val color = it.getDarkVibrantColor(
ContextCompat.getColor(
itemView.context,
R.color.dubColorBg
)
val color = palette?.getDarkVibrantColor(
ContextCompat.getColor(
itemView.context,
R.color.dubColorBg
)
)

if (color != null) {
wifiText.backgroundTintList = ColorStateList.valueOf(color)
dataText.backgroundTintList = ColorStateList.valueOf(color)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
import com.lagradost.cloudstream3.utils.UIHelper.populateChips
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.cloudstream3.utils.getImageFromDrawable
import com.lagradost.cloudstream3.utils.setText
import com.lagradost.cloudstream3.utils.setTextHtml

Expand Down Expand Up @@ -706,10 +707,10 @@ open class ResultFragmentPhone : FullScreenPlayer() {
resultNextAiring.setText(d.nextAiringEpisode)
resultNextAiringTime.setText(d.nextAiringDate)
resultPoster.loadImage(d.posterImage, headers = d.posterHeaders) {
error(R.drawable.default_cover)
error{ getImageFromDrawable(context?: return@error null, R.drawable.default_cover) }
}
resultPosterBackground.loadImage(d.posterBackgroundImage, headers = d.posterHeaders) {
error(R.drawable.default_cover)
error{ getImageFromDrawable(context?: return@error null, R.drawable.default_cover) }
}

var isExpanded = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.getImageFromDrawable
import com.lagradost.cloudstream3.utils.setText
import com.lagradost.cloudstream3.utils.setTextHtml

Expand Down Expand Up @@ -886,9 +887,9 @@ class ResultFragmentTv : Fragment() {
//Change poster crop area to 20% from Top
backgroundPoster.cropYCenterOffsetPct = 0.20F

backgroundPoster.loadImage(
d.posterBackgroundImage
) { error(error) }
backgroundPoster.loadImage(d.posterBackgroundImage) {
error { getImageFromDrawable(context ?: return@error null, error) }
}
comingSoon = d.comingSoon
resultTvComingSoon.isVisible = d.comingSoon

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.cardview.widget.CardView
import androidx.core.view.isVisible
import androidx.palette.graphics.Palette
import androidx.preference.PreferenceManager
import coil3.request.error
import com.lagradost.cloudstream3.AnimeSearchResponse
import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.LiveSearchResponse
Expand All @@ -25,6 +26,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual
import com.lagradost.cloudstream3.utils.ImageLoader.loadImage
import com.lagradost.cloudstream3.utils.SubtitleHelper
import com.lagradost.cloudstream3.utils.getImageFromDrawable

object SearchResultBuilder {
private val showCache: MutableMap<String, Boolean> = mutableMapOf()
Expand Down Expand Up @@ -120,7 +122,7 @@ object SearchResultBuilder {
cardText?.text = card.name
cardText?.isVisible = showTitle
cardView.isVisible = true
cardView.loadImage(card.posterUrl) { error(R.drawable.default_cover) }
cardView.loadImage(card.posterUrl) { error { getImageFromDrawable(itemView.context, R.drawable.default_cover) } }

fun click(view: View?) {
clickCallback.invoke(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.lagradost.cloudstream3.utils.UIHelper
import com.lagradost.cloudstream3.utils.UIHelper.clipboardHelper
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.getImageFromDrawable
import java.io.File
import java.text.DateFormat
import java.text.SimpleDateFormat
Expand Down Expand Up @@ -186,8 +187,8 @@ class SettingsFragment : Fragment() {

binding?.settingsProfilePic?.let { imageView ->
imageView.loadImage(pic) {
crossfade(true) // Optional: for a fade-in animation
error(errorProfilePic) // Fallback to random error drawable
// Fallback to random error drawable
error { getImageFromDrawable(context ?: return@error null, errorProfilePic) }
}
}
return true // sync profile exists
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.lagradost.cloudstream3.utils.ImageLoader.loadImage
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.getImageFromDrawable
import org.junit.Assert
import org.junit.Test
import java.text.DecimalFormat
Expand Down Expand Up @@ -205,7 +206,7 @@ class PluginAdapter(
"%exact_size%",
"$iconSizeExact"
)
) { error(R.drawable.ic_baseline_extension_24) }
) { error(getImageFromDrawable(itemView.context, R.drawable.ic_baseline_extension_24)) }

binding.extVersion.isVisible = true
binding.extVersion.text = "v${metadata.version}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.getImageFromDrawable


class PluginDetailsFragment(val data: PluginViewData) : BottomSheetDialogFragment() {
Expand Down Expand Up @@ -63,7 +64,7 @@ class PluginDetailsFragment(val data: PluginViewData) : BottomSheetDialogFragmen
binding?.apply {
pluginIcon.loadImage(metadata.iconUrl?.replace("%size%", "$iconSize")
?.replace("%exact_size%", "$iconSizeExact")) {
error(R.drawable.ic_baseline_extension_24)
error { getImageFromDrawable(context ?: return@error null , R.drawable.ic_baseline_extension_24) }
}
pluginName.text = metadata.name.removeSuffix("Provider")
pluginVersion.text = metadata.version.toString()
Expand Down
Loading