diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f8e0091c..bcd158dc 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -220,6 +220,9 @@ dependencies { // Library/extensions searching with Levenshtein distance implementation("me.xdrop:fuzzywuzzy:1.4.0") + + // color pallette for images -> colors + implementation("androidx.palette:palette-ktx:1.0.0") } tasks.register("androidSourcesJar", Jar::class) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/library/PageAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/library/PageAdapter.kt index 57634a53..0909d845 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/library/PageAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/library/PageAdapter.kt @@ -1,12 +1,17 @@ package com.lagradost.cloudstream3.ui.library +import android.content.res.ColorStateList +import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView +import androidx.core.content.ContextCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView +import com.lagradost.cloudstream3.AcraApplication import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.ui.AutofitRecyclerView @@ -17,6 +22,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.toPx import kotlinx.android.synthetic.main.search_result_grid_expanded.view.* import kotlin.math.roundToInt + class PageAdapter( override val items: MutableList, private val resView: AutofitRecyclerView, @@ -39,6 +45,18 @@ class PageAdapter( } } + private fun isDark(color: Int): Boolean { + return ColorUtils.calculateLuminance(color) < 0.5 + } + + fun getDifferentColor(color: Int, ratio : Float = 0.7f) : Int { + return if(isDark(color)) { + ColorUtils.blendARGB(color, Color.WHITE, ratio) + } else{ + ColorUtils.blendARGB(color, Color.BLACK, ratio) + } + } + inner class LibraryItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val cardView: ImageView = itemView.imageView @@ -47,11 +65,35 @@ class PageAdapter( if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt() fun bind(item: SyncAPI.LibraryItem, position: Int) { + /** https://stackoverflow.com/questions/8817522/how-to-get-color-code-of-image-view */ + SearchResultBuilder.bind( this@PageAdapter.clickCallback, item, position, itemView, + colorCallback = { palette -> + AcraApplication.context?.let { ctx -> + val defColor = ContextCompat.getColor(ctx,R.color.ratingColorBg) + var bg = palette.getDarkVibrantColor(defColor) + if (bg == defColor) { + bg = palette.getDarkMutedColor(defColor) + } + if (bg == defColor) { + bg = palette.getVibrantColor(defColor) + } + + val fg = getDifferentColor(bg)//palette.getVibrantColor(ContextCompat.getColor(ctx,R.color.ratingColor)) + itemView.text_rating.apply { + setTextColor(ColorStateList.valueOf(fg)) + } + itemView.text_rating_holder?.backgroundTintList =ColorStateList.valueOf(bg) + itemView.watchProgress?.apply { + progressTintList = ColorStateList.valueOf(fg) + progressBackgroundTintList = ColorStateList.valueOf(bg) + } + } + } ) // See searchAdaptor for this, it basically fixes the height @@ -74,9 +116,9 @@ class PageAdapter( itemView.imageText.text = item.name val showRating = (item.personalRating ?: 0) != 0 - itemView.text_rating.isVisible = showRating + itemView.text_rating_holder.isVisible = showRating if (showRating) { - itemView.text_rating.text = item.personalRating.toString() + itemView.text_rating.text = "★ ${item.personalRating.toString()}" } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt index 3afbb8c0..3447ee32 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchResultBuilder.kt @@ -1,12 +1,14 @@ package com.lagradost.cloudstream3.ui.search import android.content.Context +import android.graphics.drawable.Drawable import android.view.View import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.view.isVisible +import androidx.palette.graphics.Palette import androidx.preference.PreferenceManager import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings @@ -41,6 +43,7 @@ object SearchResultBuilder { nextFocusBehavior: Boolean? = null, nextFocusUp: Int? = null, nextFocusDown: Int? = null, + colorCallback : ((Palette) -> Unit)? = null ) { val cardView: ImageView = itemView.imageView val cardText: TextView? = itemView.imageText @@ -100,7 +103,7 @@ object SearchResultBuilder { cardText?.isVisible = showTitle cardView.isVisible = true - if (!cardView.setImage(card.posterUrl, card.posterHeaders)) { + if (!cardView.setImage(card.posterUrl, card.posterHeaders, colorCallback = colorCallback)) { cardView.setImageResource(R.drawable.default_cover) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt index b5a84ad0..c300d615 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt @@ -9,7 +9,9 @@ import android.content.Context import android.content.pm.PackageManager import android.content.res.Configuration import android.content.res.Resources +import android.graphics.Bitmap import android.graphics.Color +import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.view.* @@ -28,15 +30,21 @@ import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.graphics.alpha import androidx.core.graphics.blue +import androidx.core.graphics.drawable.toBitmapOrNull import androidx.core.graphics.green import androidx.core.graphics.red import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.navigation.fragment.NavHostFragment +import androidx.palette.graphics.Palette import androidx.preference.PreferenceManager +import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.target.Target import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings @@ -158,12 +166,27 @@ object UIHelper { return color } + var createPaletteAsyncCache: HashMap = hashMapOf() + fun createPaletteAsync(url: String, bitmap: Bitmap, callback: (Palette) -> Unit) { + createPaletteAsyncCache[url]?.let { palette -> + callback.invoke(palette) + return + } + Palette.from(bitmap).generate { paletteNull -> + paletteNull?.let { palette -> + createPaletteAsyncCache[url] = palette + callback(palette) + } + } + } + fun ImageView?.setImage( url: String?, headers: Map? = null, @DrawableRes errorImageDrawable: Int? = null, - fadeIn: Boolean = true + fadeIn: Boolean = true, + colorCallback: ((Palette) -> Unit)? = null ): Boolean { if (this == null || url.isNullOrBlank()) return false @@ -177,6 +200,33 @@ object UIHelper { else req } + if (colorCallback != null) { + builder.listener(object : RequestListener { + @SuppressLint("CheckResult") + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean + ): Boolean { + resource?.toBitmapOrNull() + ?.let { bitmap -> createPaletteAsync(url, bitmap, colorCallback) } + return false + } + + @SuppressLint("CheckResult") + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean { + return false + } + }) + } + val res = if (errorImageDrawable != null) builder.error(errorImageDrawable).into(this) else diff --git a/app/src/main/res/layout/search_result_grid_expanded.xml b/app/src/main/res/layout/search_result_grid_expanded.xml index e53a388d..850191ba 100644 --- a/app/src/main/res/layout/search_result_grid_expanded.xml +++ b/app/src/main/res/layout/search_result_grid_expanded.xml @@ -50,12 +50,29 @@ style="@style/SubButton" android:layout_gravity="end" /> - + android:visibility="gone" + tools:visibility="visible" + android:layout_margin="2dp" + android:elevation="0dp" + app:cardElevation="0dp" + android:backgroundTint="@color/ratingColorBg"> + + + + + android:visibility="gone" + tools:progress="50" + tools:visibility="visible" /> #F53B66 #BEC8FF ?attr/colorPrimaryDark - #3F51B5 + #4C3115 + #FFA662 #FF6F63 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index aff1ccb4..2540bf34 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -126,7 +126,10 @@