mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
UI
This commit is contained in:
parent
1549f67cd7
commit
22f2a8810e
26 changed files with 827 additions and 16 deletions
|
@ -1,6 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
|
id 'kotlin-android-extensions'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
@ -59,4 +60,7 @@ dependencies {
|
||||||
implementation("com.google.android.material:material:1.3.0")
|
implementation("com.google.android.material:material:1.3.0")
|
||||||
|
|
||||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||||
|
|
||||||
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
|
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.lagradost.cloudstream3">
|
package="com.lagradost.cloudstream3">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|
45
app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt
Normal file
45
app/src/main/java/com/lagradost/cloudstream3/AllProvider.kt
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.apis
|
||||||
|
|
||||||
|
class AllProvider : MainAPI() {
|
||||||
|
override val name: String
|
||||||
|
get() = "All Sources"
|
||||||
|
|
||||||
|
var providersActive = HashSet<String>()
|
||||||
|
|
||||||
|
override fun search(query: String): ArrayList<Any>? {
|
||||||
|
val list = apis.filter { a ->
|
||||||
|
a.name != this.name && (providersActive.size == 0 || providersActive.contains(a.name))
|
||||||
|
}.pmap { a ->
|
||||||
|
a.search(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxCount = 0
|
||||||
|
var providerCount = 0
|
||||||
|
for (res in list) {
|
||||||
|
if (res != null) {
|
||||||
|
if (res.size > maxCount) {
|
||||||
|
maxCount = res.size
|
||||||
|
}
|
||||||
|
providerCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providerCount == 0) return null
|
||||||
|
if (maxCount == 0) return ArrayList()
|
||||||
|
|
||||||
|
val result = ArrayList<Any>()
|
||||||
|
for (i in 0..maxCount) {
|
||||||
|
for (res in list) {
|
||||||
|
if (res != null) {
|
||||||
|
if (i < res.size) {
|
||||||
|
result.add(res[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lagradost.cloudstream3
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
@ -13,9 +15,20 @@ val mapper = JsonMapper.builder().addModule(KotlinModule())
|
||||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!!
|
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!!
|
||||||
|
|
||||||
object APIHolder {
|
object APIHolder {
|
||||||
|
val allApi = AllProvider()
|
||||||
|
|
||||||
|
private const val defProvider = 0
|
||||||
|
|
||||||
val apis = arrayListOf<MainAPI>(
|
val apis = arrayListOf<MainAPI>(
|
||||||
ShiroProvider()
|
ShiroProvider()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun Activity.getApiSettings(): HashSet<String> {
|
||||||
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
|
return settingsManager.getStringSet(this.getString(R.string.search_providers_list_key),
|
||||||
|
setOf(apis[defProvider].name))?.toHashSet() ?: hashSetOf(apis[defProvider].name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +48,17 @@ abstract class MainAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MainAPI.fixUrl(url: String): String {
|
||||||
|
if (url.startsWith('/')) {
|
||||||
|
return mainUrl + url
|
||||||
|
}
|
||||||
|
else if(!url.startsWith("http") && !url.startsWith("//")) {
|
||||||
|
return "$mainUrl/$url"
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
data class Link(
|
data class Link(
|
||||||
val name: String,
|
val name: String,
|
||||||
val url: String,
|
val url: String,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
//https://stackoverflow.com/questions/34697828/parallel-operations-on-kotlin-collections
|
||||||
|
fun <T, R> Iterable<T>.pmap(
|
||||||
|
numThreads: Int = maxOf(Runtime.getRuntime().availableProcessors() - 2, 1),
|
||||||
|
exec: ExecutorService = Executors.newFixedThreadPool(numThreads),
|
||||||
|
transform: (T) -> R,
|
||||||
|
): List<R> {
|
||||||
|
|
||||||
|
// default size is just an inlined version of kotlin.collections.collectionSizeOrDefault
|
||||||
|
val defaultSize = if (this is Collection<*>) this.size else 10
|
||||||
|
val destination = Collections.synchronizedList(ArrayList<R>(defaultSize))
|
||||||
|
|
||||||
|
for (item in this) {
|
||||||
|
exec.submit { destination.add(transform(item)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
exec.shutdown()
|
||||||
|
exec.awaitTermination(1, TimeUnit.DAYS)
|
||||||
|
|
||||||
|
return ArrayList<R>(destination)
|
||||||
|
}
|
|
@ -1,20 +1,52 @@
|
||||||
package com.lagradost.cloudstream3
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.res.Resources
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
|
||||||
object UIHelper {
|
object UIHelper {
|
||||||
fun Activity.getStatusBarHeight(): Int {
|
val Int.toPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
|
||||||
|
val Float.toPx: Float get() = (this * Resources.getSystem().displayMetrics.density)
|
||||||
|
val Int.toDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
|
||||||
|
val Float.toDp: Float get() = (this / Resources.getSystem().displayMetrics.density)
|
||||||
|
|
||||||
|
fun Activity.loadResult(url: String, apiName: String) {
|
||||||
|
/*this.runOnUiThread {
|
||||||
|
this.supportFragmentManager.beginTransaction()
|
||||||
|
.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
|
||||||
|
.add(R.id.homeRoot, ResultFragment().newInstance(url, apiName))
|
||||||
|
.commit()
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Activity.getStatusBarHeight(): Int {
|
||||||
var result = 0
|
var result = 0
|
||||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||||
if (resourceId > 0) {
|
if (resourceId > 0) {
|
||||||
result = resources.getDimensionPixelSize(resourceId)
|
result = resources.getDimensionPixelSize(resourceId)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.fixPaddingStatusbar(v: View) {
|
fun Activity.fixPaddingStatusbar(v: View) {
|
||||||
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
|
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Activity.getGridFormat(): String {
|
||||||
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
return settingsManager.getString(getString(R.string.grid_format_key), "grid")!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Activity.getGridFormatId(): Int {
|
||||||
|
return when (getGridFormat()) {
|
||||||
|
"list" -> R.layout.search_result_compact
|
||||||
|
"compact_list" -> R.layout.search_result_super_compact
|
||||||
|
else -> R.layout.search_result_grid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Activity.getGridIsCompact(): Boolean {
|
||||||
|
return getGridFormat() != "grid"
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,9 +3,9 @@ package com.lagradost.cloudstream3.animeproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import java.lang.Exception
|
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class ShiroProvider : MainAPI() {
|
class ShiroProvider : MainAPI() {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -42,6 +42,12 @@ class ShiroProvider : MainAPI() {
|
||||||
@JsonProperty("_id") val _id: String,
|
@JsonProperty("_id") val _id: String,
|
||||||
@JsonProperty("slug") val slug: String,
|
@JsonProperty("slug") val slug: String,
|
||||||
@JsonProperty("name") val name: String,
|
@JsonProperty("name") val name: String,
|
||||||
|
@JsonProperty("episodeCount") val episodeCount: String,
|
||||||
|
@JsonProperty("language") val language: String,
|
||||||
|
@JsonProperty("type") val type: String,
|
||||||
|
@JsonProperty("year") val year: String,
|
||||||
|
@JsonProperty("canonicalTitle") val canonicalTitle: String,
|
||||||
|
@JsonProperty("english") val english: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ShiroSearchResponse(
|
data class ShiroSearchResponse(
|
||||||
|
@ -67,6 +73,7 @@ class ShiroProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun search(query: String): ArrayList<Any>? {
|
override fun search(query: String): ArrayList<Any>? {
|
||||||
|
try {
|
||||||
if (!autoLoadToken()) return null
|
if (!autoLoadToken()) return null
|
||||||
val returnValue: ArrayList<Any> = ArrayList()
|
val returnValue: ArrayList<Any> = ArrayList()
|
||||||
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
|
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
|
||||||
|
@ -74,9 +81,42 @@ class ShiroProvider : MainAPI() {
|
||||||
query,
|
query,
|
||||||
"UTF-8"
|
"UTF-8"
|
||||||
)
|
)
|
||||||
}&token=$token")
|
}&token=$token".replace("+", "%20"))
|
||||||
val mapped = response.let { mapper.readValue<ShiroSearchResponse>(it.text) }
|
println(response.text)
|
||||||
|
val mapped = response.let { mapper.readValue<ShiroFullSearchResponse>(it.text) }
|
||||||
|
for (i in mapped.data.nav.currentPage.items) {
|
||||||
|
|
||||||
|
val type = when (i.type) {
|
||||||
|
"TV" -> TvType.Anime
|
||||||
|
"OVA" -> TvType.ONA
|
||||||
|
"movie" -> TvType.Movie
|
||||||
|
else -> TvType.Anime
|
||||||
|
}
|
||||||
|
val isDubbed = i.language == "dubbed"
|
||||||
|
val set: EnumSet<DubStatus> = EnumSet.noneOf(DubStatus::class.java)
|
||||||
|
|
||||||
|
if (isDubbed)
|
||||||
|
set.add(DubStatus.HasDub)
|
||||||
|
else
|
||||||
|
set.add(DubStatus.HasSub)
|
||||||
|
val episodeCount = i.episodeCount.toInt()
|
||||||
|
|
||||||
|
returnValue.add(AnimeSearchResponse(
|
||||||
|
i.english ?: i.canonicalTitle,
|
||||||
|
"$mainUrl/${i.slug}",
|
||||||
|
this.name,
|
||||||
|
type,
|
||||||
|
"https://cdn.shiro.is/${i.image}",
|
||||||
|
i.year.toInt(),
|
||||||
|
i.canonicalTitle,
|
||||||
|
set,
|
||||||
|
if (isDubbed) episodeCount else null,
|
||||||
|
if (!isDubbed) episodeCount else null,
|
||||||
|
))
|
||||||
|
}
|
||||||
return returnValue
|
return returnValue
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package com.lagradost.cloudstream3.ui.search
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.getGridFormatId
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.loadResult
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.toPx
|
||||||
|
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
|
||||||
|
import kotlinx.android.synthetic.main.search_result_compact.view.*
|
||||||
|
import kotlinx.android.synthetic.main.search_result_compact.view.backgroundCard
|
||||||
|
import kotlinx.android.synthetic.main.search_result_compact.view.imageText
|
||||||
|
import kotlinx.android.synthetic.main.search_result_compact.view.imageView
|
||||||
|
import kotlinx.android.synthetic.main.search_result_grid.view.*
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
class SearchAdapter(
|
||||||
|
activity: Activity,
|
||||||
|
animeList: ArrayList<Any>,
|
||||||
|
resView: AutofitRecyclerView,
|
||||||
|
) :
|
||||||
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
var cardList = animeList
|
||||||
|
private var activity: Activity = activity
|
||||||
|
var resView: AutofitRecyclerView? = resView
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val layout = activity.getGridFormatId()
|
||||||
|
return CardViewHolder(
|
||||||
|
LayoutInflater.from(parent.context).inflate(layout, parent, false),
|
||||||
|
activity,
|
||||||
|
resView!!
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
when (holder) {
|
||||||
|
is CardViewHolder -> {
|
||||||
|
holder.bind(cardList[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return cardList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
class CardViewHolder
|
||||||
|
constructor(itemView: View, _activity: Activity, resView: AutofitRecyclerView) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
val activity = _activity
|
||||||
|
val cardView: ImageView = itemView.imageView
|
||||||
|
val cardText: TextView = itemView.imageText
|
||||||
|
val text_type: TextView? = itemView.text_type
|
||||||
|
val text_is_dub: TextView? = itemView.text_is_dub
|
||||||
|
val text_is_sub: TextView? = itemView.text_is_sub
|
||||||
|
|
||||||
|
//val cardTextExtra: TextView? = itemView.imageTextExtra
|
||||||
|
//val imageTextProvider: TextView? = itemView.imageTextProvider
|
||||||
|
val bg = itemView.backgroundCard
|
||||||
|
val compactView = activity.getGridIsCompact()
|
||||||
|
private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
|
||||||
|
|
||||||
|
fun bind(card: Any) {
|
||||||
|
if (card is SearchResponse) { // GENERIC
|
||||||
|
if (!compactView) {
|
||||||
|
cardView.apply {
|
||||||
|
layoutParams = FrameLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
coverHeight
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text_type?.text = when (card.type) {
|
||||||
|
TvType.Anime -> "Anime"
|
||||||
|
TvType.Movie -> "Movie"
|
||||||
|
TvType.ONA -> "ONA"
|
||||||
|
TvType.TvSeries -> "TV"
|
||||||
|
}
|
||||||
|
|
||||||
|
text_is_dub?.visibility = View.GONE
|
||||||
|
text_is_sub?.visibility = View.GONE
|
||||||
|
|
||||||
|
cardText.text = card.name
|
||||||
|
|
||||||
|
//imageTextProvider.text = card.apiName
|
||||||
|
|
||||||
|
val glideUrl =
|
||||||
|
GlideUrl(card.posterUrl)
|
||||||
|
activity.let {
|
||||||
|
Glide.with(it)
|
||||||
|
.load(glideUrl)
|
||||||
|
.into(cardView)
|
||||||
|
}
|
||||||
|
|
||||||
|
bg.setOnClickListener {
|
||||||
|
activity.loadResult(card.url, card.apiName)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (card) {
|
||||||
|
is AnimeSearchResponse -> {
|
||||||
|
if (card.dubStatus?.contains(DubStatus.HasDub) == true) {
|
||||||
|
text_is_dub?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
if (card.dubStatus?.contains(DubStatus.HasSub) == true) {
|
||||||
|
text_is_sub?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,29 @@
|
||||||
package com.lagradost.cloudstream3.ui.search
|
package com.lagradost.cloudstream3.ui.search
|
||||||
|
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
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.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.allApi
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.apis
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.getApiSettings
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
|
||||||
|
import kotlinx.android.synthetic.main.fragment_search.*
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
class SearchFragment : Fragment() {
|
class SearchFragment : Fragment() {
|
||||||
|
|
||||||
|
@ -18,7 +32,7 @@ class SearchFragment : Fragment() {
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?,
|
||||||
): View? {
|
): View? {
|
||||||
searchViewModel =
|
searchViewModel =
|
||||||
ViewModelProvider(this).get(SearchViewModel::class.java)
|
ViewModelProvider(this).get(SearchViewModel::class.java)
|
||||||
|
@ -29,6 +43,91 @@ class SearchFragment : Fragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
// activity?.fixPaddingStatusbar(searchRoot)
|
activity?.fixPaddingStatusbar(searchRoot)
|
||||||
|
|
||||||
|
val compactView = activity?.getGridIsCompact() ?: false
|
||||||
|
val spanCountLandscape = if (compactView) 2 else 6
|
||||||
|
val spanCountPortrait = if (compactView) 1 else 3
|
||||||
|
val orientation = resources.configuration.orientation
|
||||||
|
|
||||||
|
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
cardSpace.spanCount = spanCountLandscape
|
||||||
|
} else {
|
||||||
|
cardSpace.spanCount = spanCountPortrait
|
||||||
|
}
|
||||||
|
|
||||||
|
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = activity?.let {
|
||||||
|
SearchAdapter(
|
||||||
|
it,
|
||||||
|
ArrayList(),
|
||||||
|
cardSpace,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cardSpace.adapter = adapter
|
||||||
|
search_loading_bar.alpha = 0f
|
||||||
|
|
||||||
|
val search_exit_icon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
|
||||||
|
val search_mag_icon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_mag_icon)
|
||||||
|
search_mag_icon.scaleX = 0.65f
|
||||||
|
search_mag_icon.scaleY = 0.65f
|
||||||
|
search_filter.setOnClickListener {
|
||||||
|
val apiNamesSetting = activity?.getApiSettings()
|
||||||
|
if (apiNamesSetting != null) {
|
||||||
|
val apiNames = apis.map { it.name }
|
||||||
|
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
||||||
|
|
||||||
|
builder.setMultiChoiceItems(apiNames.toTypedArray(),
|
||||||
|
apiNames.map { a -> apiNamesSetting.contains(a) }.toBooleanArray()
|
||||||
|
) { _, position: Int, checked: Boolean ->
|
||||||
|
val apiNamesSettingLocal = activity?.getApiSettings()
|
||||||
|
if (apiNamesSettingLocal != null) {
|
||||||
|
val settingsManagerLocal = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
|
if (checked) {
|
||||||
|
apiNamesSettingLocal.add(apiNames[position])
|
||||||
|
} else {
|
||||||
|
apiNamesSettingLocal.remove(apiNames[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
val edit = settingsManagerLocal.edit()
|
||||||
|
edit.putStringSet(getString(R.string.search_providers_list_key),
|
||||||
|
apiNames.filter { a -> apiNamesSettingLocal.contains(a) }.toSet())
|
||||||
|
edit.apply()
|
||||||
|
allApi.providersActive = apiNamesSettingLocal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.setTitle("Search Providers")
|
||||||
|
builder.setNegativeButton("Cancel") { _, _ -> }
|
||||||
|
builder.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||||
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
|
search_exit_icon.alpha = 0f
|
||||||
|
search_loading_bar.alpha = 1f
|
||||||
|
thread {
|
||||||
|
val data = allApi.search(query)//MainActivity.activeAPI.search(query)
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
if (data == null) {
|
||||||
|
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
|
||||||
|
} else {
|
||||||
|
(cardSpace.adapter as SearchAdapter).cardList = data
|
||||||
|
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
search_exit_icon.alpha = 1f
|
||||||
|
search_loading_bar.alpha = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextChange(newText: String): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
main_search.onActionViewExpanded()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
19
app/src/main/res/anim/enter_anim.xml
Normal file
19
app/src/main/res/anim/enter_anim.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromXScale="0.9"
|
||||||
|
android:toXScale="1.0"
|
||||||
|
android:fromYScale="0.9"
|
||||||
|
android:toYScale="1.0"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
>
|
||||||
|
</scale>
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"/>
|
||||||
|
</set>
|
19
app/src/main/res/anim/exit_anim.xml
Normal file
19
app/src/main/res/anim/exit_anim.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromXScale="1.0"
|
||||||
|
android:toXScale="0.9"
|
||||||
|
android:fromYScale="1.0"
|
||||||
|
android:toYScale="0.9"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
>
|
||||||
|
</scale>
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="1.0"
|
||||||
|
android:toAlpha="0.0"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/nav_enter_anim.xml
Normal file
8
app/src/main/res/anim/nav_enter_anim.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/nav_exit_anim.xml
Normal file
8
app/src/main/res/anim/nav_exit_anim.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="1.0"
|
||||||
|
android:toAlpha="0.0"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/nav_pop_enter.xml
Normal file
8
app/src/main/res/anim/nav_pop_enter.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/nav_pop_exit.xml
Normal file
8
app/src/main/res/anim/nav_pop_exit.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="1.0"
|
||||||
|
android:toAlpha="0.0"/>
|
||||||
|
</set>
|
19
app/src/main/res/anim/pop_enter.xml
Normal file
19
app/src/main/res/anim/pop_enter.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromXScale="0.9"
|
||||||
|
android:toXScale="1.0"
|
||||||
|
android:fromYScale="0.9"
|
||||||
|
android:toYScale="1.0"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
>
|
||||||
|
</scale>
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"/>
|
||||||
|
</set>
|
19
app/src/main/res/anim/pop_exit.xml
Normal file
19
app/src/main/res/anim/pop_exit.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromXScale="1.0"
|
||||||
|
android:toXScale="0.9"
|
||||||
|
android:fromYScale="1.0"
|
||||||
|
android:toYScale="0.9"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
>
|
||||||
|
</scale>
|
||||||
|
<alpha
|
||||||
|
android:interpolator="@android:anim/linear_interpolator"
|
||||||
|
android:duration="@integer/config_navAnimTime"
|
||||||
|
android:fromAlpha="1.0"
|
||||||
|
android:toAlpha="0.0"/>
|
||||||
|
</set>
|
6
app/src/main/res/drawable/dub_bg_color.xml
Normal file
6
app/src/main/res/drawable/dub_bg_color.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/dubColorBg"/>
|
||||||
|
<corners android:radius="@dimen/roundedImageRadius"/>
|
||||||
|
<stroke android:color="@color/dubColor" android:width="1dp"/>
|
||||||
|
</shape>
|
6
app/src/main/res/drawable/sub_bg_color.xml
Normal file
6
app/src/main/res/drawable/sub_bg_color.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/subColorBg"/>
|
||||||
|
<corners android:radius="@dimen/roundedImageRadius"/>
|
||||||
|
<stroke android:color="@color/subColor" android:width="1dp"/>
|
||||||
|
</shape>
|
8
app/src/main/res/drawable/title_shadow.xml
Normal file
8
app/src/main/res/drawable/title_shadow.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:startColor="@android:color/transparent"
|
||||||
|
android:endColor="#000"
|
||||||
|
android:angle="-90">
|
||||||
|
</gradient>
|
||||||
|
</shape>
|
6
app/src/main/res/drawable/type_bg_color.xml
Normal file
6
app/src/main/res/drawable/type_bg_color.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/typeColorBg"/>
|
||||||
|
<corners android:radius="@dimen/roundedImageRadius"/>
|
||||||
|
<stroke android:color="@color/typeColor" android:width="1dp"/>
|
||||||
|
</shape>
|
80
app/src/main/res/layout/search_result_compact.xml
Normal file
80
app/src/main/res/layout/search_result_compact.xml
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:layout_marginBottom="0dp"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
|
||||||
|
android:id="@+id/backgroundCard"
|
||||||
|
android:layout_margin="2dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
|
||||||
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
|
app:cardBackgroundColor="@color/itemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
>
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:elevation="0dp"
|
||||||
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
|
android:layout_width="54dp"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="left"
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
tools:ignore="RtlHardcoded"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="64dp">
|
||||||
|
<TextView
|
||||||
|
tools:text="@string/no_data"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:id="@+id/imageText"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:maxLines="3"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
tools:text="@string/no_data"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/lightGrayTextColor"
|
||||||
|
android:id="@+id/imageTextExtra"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:maxLines="3"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
tools:text="Rated 4.13"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:id="@+id/imageTextProvider"
|
||||||
|
android:maxLines="1"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
</LinearLayout>
|
111
app/src/main/res/layout/search_result_grid.xml
Normal file
111
app/src/main/res/layout/search_result_grid.xml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
|
||||||
|
android:focusable="true"
|
||||||
|
android:clickable="true"
|
||||||
|
android:id="@+id/search_result_root"
|
||||||
|
|
||||||
|
>
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:layout_margin="2dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:elevation="10dp"
|
||||||
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
|
android:id="@+id/backgroundCard"
|
||||||
|
app:cardBackgroundColor="@color/darkBackground"
|
||||||
|
>
|
||||||
|
<!-- USING CROP RATIO (182/268), centerCrop for fill -->
|
||||||
|
<ImageView
|
||||||
|
android:duplicateParentState="true"
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/search_poster_descript"/>
|
||||||
|
<ImageView
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:src="@drawable/title_shadow"
|
||||||
|
android:layout_gravity="bottom" android:contentDescription="@string/shadow_descript">
|
||||||
|
</ImageView>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:id="@+id/imageText"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:text="Movie"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/text_type"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:minWidth="50dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="@drawable/type_bg_color"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<TextView
|
||||||
|
android:text="Dub"
|
||||||
|
android:id="@+id/text_is_dub"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:minWidth="50dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="@drawable/dub_bg_color"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_is_sub"
|
||||||
|
android:text="Sub"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:minWidth="50dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="@drawable/sub_bg_color"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
</TextView>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
78
app/src/main/res/layout/search_result_super_compact.xml
Normal file
78
app/src/main/res/layout/search_result_super_compact.xml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginBottom="3dp"
|
||||||
|
>
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/backgroundCard"
|
||||||
|
android:layout_margin="2dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
|
app:cardBackgroundColor="@color/itemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
>
|
||||||
|
<!-- USING CROP RATIO (182/268), centerCrop for fill -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="left"
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
tools:ignore="RtlHardcoded" android:contentDescription="@string/search_poster_descript"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="45dp">
|
||||||
|
<TextView
|
||||||
|
tools:text="@string/no_data"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:id="@+id/imageText"
|
||||||
|
android:textStyle="normal"
|
||||||
|
android:maxLines="3"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
tools:text="@string/no_data"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:textColor="@color/lightGrayTextColor"
|
||||||
|
android:id="@+id/imageTextExtra"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:maxLines="3"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
tools:text="Rated 4.13"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:id="@+id/imageTextProvider"
|
||||||
|
android:maxLines="1"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
</LinearLayout>
|
|
@ -21,4 +21,10 @@
|
||||||
<color name="transparent">#00000000</color>
|
<color name="transparent">#00000000</color>
|
||||||
|
|
||||||
<color name="white">#FFF</color>
|
<color name="white">#FFF</color>
|
||||||
|
<color name="dubColor">#3b65f5</color>
|
||||||
|
<color name="dubColorBg">#4D3B65F5</color>
|
||||||
|
<color name="subColor">#F53B66</color>
|
||||||
|
<color name="subColorBg">#4DF53B66</color>
|
||||||
|
<color name="typeColor">#F54A3B</color>
|
||||||
|
<color name="typeColorBg">#4DF54A3B</color>
|
||||||
</resources>
|
</resources>
|
|
@ -5,4 +5,9 @@
|
||||||
<string name="title_downloads">Downloads</string>
|
<string name="title_downloads">Downloads</string>
|
||||||
<string name="search_hint">Search...</string>
|
<string name="search_hint">Search...</string>
|
||||||
<string name="change_providers_descript">Change Providers</string>
|
<string name="change_providers_descript">Change Providers</string>
|
||||||
|
<string name="search_providers_list_key">search_providers_list</string>
|
||||||
|
<string name="grid_format_key">grid_format</string>
|
||||||
|
<string name="search_poster_descript">Poster</string>
|
||||||
|
<string name="no_data">No Data</string>
|
||||||
|
<string name="shadow_descript">Shadow</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue