forked from recloudstream/cloudstream
colors go brrr
This commit is contained in:
parent
dd293e9564
commit
9bc90438ec
7 changed files with 132 additions and 12 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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()}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 -->
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue