colors go brrr

This commit is contained in:
reduplicated 2023-01-25 16:54:57 +01:00
parent dd293e9564
commit 9bc90438ec
7 changed files with 132 additions and 12 deletions

View file

@ -220,6 +220,9 @@ dependencies {
// Library/extensions searching with Levenshtein distance // Library/extensions searching with Levenshtein distance
implementation("me.xdrop:fuzzywuzzy:1.4.0") 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) { tasks.register("androidSourcesJar", Jar::class) {

View file

@ -1,12 +1,17 @@
package com.lagradost.cloudstream3.ui.library package com.lagradost.cloudstream3.ui.library
import android.content.res.ColorStateList
import android.graphics.Color
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.ui.AutofitRecyclerView 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 kotlinx.android.synthetic.main.search_result_grid_expanded.view.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
class PageAdapter( class PageAdapter(
override val items: MutableList<SyncAPI.LibraryItem>, override val items: MutableList<SyncAPI.LibraryItem>,
private val resView: AutofitRecyclerView, 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) { inner class LibraryItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardView: ImageView = itemView.imageView val cardView: ImageView = itemView.imageView
@ -47,11 +65,35 @@ class PageAdapter(
if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt() if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(item: SyncAPI.LibraryItem, position: Int) { fun bind(item: SyncAPI.LibraryItem, position: Int) {
/** https://stackoverflow.com/questions/8817522/how-to-get-color-code-of-image-view */
SearchResultBuilder.bind( SearchResultBuilder.bind(
this@PageAdapter.clickCallback, this@PageAdapter.clickCallback,
item, item,
position, position,
itemView, 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 // See searchAdaptor for this, it basically fixes the height
@ -74,9 +116,9 @@ class PageAdapter(
itemView.imageText.text = item.name itemView.imageText.text = item.name
val showRating = (item.personalRating ?: 0) != 0 val showRating = (item.personalRating ?: 0) != 0
itemView.text_rating.isVisible = showRating itemView.text_rating_holder.isVisible = showRating
if (showRating) { if (showRating) {
itemView.text_rating.text = item.personalRating.toString() itemView.text_rating.text = "${item.personalRating.toString()}"
} }
} }
} }

View file

@ -1,12 +1,14 @@
package com.lagradost.cloudstream3.ui.search package com.lagradost.cloudstream3.ui.search
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.palette.graphics.Palette
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
@ -41,6 +43,7 @@ object SearchResultBuilder {
nextFocusBehavior: Boolean? = null, nextFocusBehavior: Boolean? = null,
nextFocusUp: Int? = null, nextFocusUp: Int? = null,
nextFocusDown: Int? = null, nextFocusDown: Int? = null,
colorCallback : ((Palette) -> Unit)? = null
) { ) {
val cardView: ImageView = itemView.imageView val cardView: ImageView = itemView.imageView
val cardText: TextView? = itemView.imageText val cardText: TextView? = itemView.imageText
@ -100,7 +103,7 @@ object SearchResultBuilder {
cardText?.isVisible = showTitle cardText?.isVisible = showTitle
cardView.isVisible = true 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) cardView.setImageResource(R.drawable.default_cover)
} }

View file

@ -9,7 +9,9 @@ import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
@ -28,15 +30,21 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.alpha import androidx.core.graphics.alpha
import androidx.core.graphics.blue import androidx.core.graphics.blue
import androidx.core.graphics.drawable.toBitmapOrNull
import androidx.core.graphics.green import androidx.core.graphics.green
import androidx.core.graphics.red import androidx.core.graphics.red
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import androidx.palette.graphics.Palette
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy 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.model.GlideUrl
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions 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.R
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
@ -158,12 +166,27 @@ object UIHelper {
return color return color
} }
var createPaletteAsyncCache: HashMap<String, Palette> = 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( fun ImageView?.setImage(
url: String?, url: String?,
headers: Map<String, String>? = null, headers: Map<String, String>? = null,
@DrawableRes @DrawableRes
errorImageDrawable: Int? = null, errorImageDrawable: Int? = null,
fadeIn: Boolean = true fadeIn: Boolean = true,
colorCallback: ((Palette) -> Unit)? = null
): Boolean { ): Boolean {
if (this == null || url.isNullOrBlank()) return false if (this == null || url.isNullOrBlank()) return false
@ -177,6 +200,33 @@ object UIHelper {
else req else req
} }
if (colorCallback != null) {
builder.listener(object : RequestListener<Drawable> {
@SuppressLint("CheckResult")
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
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<Drawable>?,
isFirstResource: Boolean
): Boolean {
return false
}
})
}
val res = if (errorImageDrawable != null) val res = if (errorImageDrawable != null)
builder.error(errorImageDrawable).into(this) builder.error(errorImageDrawable).into(this)
else else

View file

@ -50,12 +50,29 @@
style="@style/SubButton" style="@style/SubButton"
android:layout_gravity="end" /> android:layout_gravity="end" />
<TextView <androidx.cardview.widget.CardView
android:visibility="gone" android:id="@+id/text_rating_holder"
android:id="@+id/text_rating" android:layout_width="wrap_content"
style="@style/RatingButton" android:layout_height="wrap_content"
app:cardCornerRadius="@dimen/rounded_image_radius"
android:layout_gravity="end" android:layout_gravity="end"
tools:text="7.7" /> android:visibility="gone"
tools:visibility="visible"
android:layout_margin="2dp"
android:elevation="0dp"
app:cardElevation="0dp"
android:backgroundTint="@color/ratingColorBg">
<TextView
style="@style/SearchBox"
android:minWidth="40dp"
android:layout_margin="0dp"
android:textColor="@color/ratingColor"
android:id="@+id/text_rating"
tools:text="★ 7.7" />
</androidx.cardview.widget.CardView>
<TextView <TextView
android:id="@+id/text_flag" android:id="@+id/text_flag"
@ -74,12 +91,13 @@
style="@android:style/Widget.Material.ProgressBar.Horizontal" style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="5dp" android:layout_height="5dp"
android:visibility="gone"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:layout_marginBottom="-1.5dp" android:layout_marginBottom="-1.5dp"
android:progressBackgroundTint="?attr/colorPrimary" android:progressBackgroundTint="?attr/colorPrimary"
android:progressTint="?attr/colorPrimary" android:progressTint="?attr/colorPrimary"
tools:progress="50" /> android:visibility="gone"
tools:progress="50"
tools:visibility="visible" />
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<TextView <TextView

View file

@ -36,7 +36,8 @@
<color name="subColorBg">#F53B66</color> <color name="subColorBg">#F53B66</color>
<color name="typeColorText">#BEC8FF</color> <color name="typeColorText">#BEC8FF</color>
<color name="typeColorBg">?attr/colorPrimaryDark</color> <color name="typeColorBg">?attr/colorPrimaryDark</color>
<color name="ratingColorBg">#3F51B5</color> <color name="ratingColor">#4C3115</color>
<color name="ratingColorBg">#FFA662</color>
<color name="adultColor">#FF6F63</color> <!-- same as sub color --> <color name="adultColor">#FF6F63</color> <!-- same as sub color -->

View file

@ -126,7 +126,10 @@
</style> </style>
<style name="RatingButton" parent="@style/SearchBox"> <style name="RatingButton" parent="@style/SearchBox">
<item name="android:minWidth">30dp</item>
<item name="android:background">@drawable/rating_bg_color</item> <item name="android:background">@drawable/rating_bg_color</item>
<item name="drawableTint">@color/ratingColor</item>
<item name="android:textColor">@color/ratingColor</item>
<item name="drawableStartCompat">@drawable/ic_baseline_star_24</item> <item name="drawableStartCompat">@drawable/ic_baseline_star_24</item>
</style> </style>