mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
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
|
||||
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) {
|
||||
|
|
|
@ -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<SyncAPI.LibraryItem>,
|
||||
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()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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(
|
||||
url: String?,
|
||||
headers: Map<String, String>? = 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<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)
|
||||
builder.error(errorImageDrawable).into(this)
|
||||
else
|
||||
|
|
|
@ -50,12 +50,29 @@
|
|||
style="@style/SubButton"
|
||||
android:layout_gravity="end" />
|
||||
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/text_rating"
|
||||
style="@style/RatingButton"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/text_rating_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||
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
|
||||
android:id="@+id/text_flag"
|
||||
|
@ -74,12 +91,13 @@
|
|||
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="5dp"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="-1.5dp"
|
||||
android:progressBackgroundTint="?attr/colorPrimary"
|
||||
android:progressTint="?attr/colorPrimary"
|
||||
tools:progress="50" />
|
||||
android:visibility="gone"
|
||||
tools:progress="50"
|
||||
tools:visibility="visible" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
<color name="subColorBg">#F53B66</color>
|
||||
<color name="typeColorText">#BEC8FF</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 -->
|
||||
|
||||
|
|
|
@ -126,7 +126,10 @@
|
|||
</style>
|
||||
|
||||
<style name="RatingButton" parent="@style/SearchBox">
|
||||
<item name="android:minWidth">30dp</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>
|
||||
</style>
|
||||
|
||||
|
|
Loading…
Reference in a new issue