added flags to livestreams 🇸🇪 🇮🇳 🇦🇶 & horizontal

This commit is contained in:
LagradOst 2022-07-25 03:18:27 +02:00
parent 8ad17143a4
commit 9b6b06437f
11 changed files with 146 additions and 29 deletions

View file

@ -99,14 +99,14 @@ object APIHolder {
RebahinProvider(),
LayarKacaProvider(),
HDTodayProvider(),
OpenVidsProvider(),
OpenVidsProvider(),
IdlixProvider(),
MultiplexProvider(),
VidSrcProvider(),
UakinoProvider(),
PhimmoichillProvider(),
HDrezkaProvider(),
// Metadata providers
//TmdbProvider(),
@ -555,8 +555,10 @@ fun capitalizeStringNullable(str: String?): String? {
}
fun fixTitle(str: String): String {
return str.split(" ").joinToString(" ") { it.lowercase()
.replaceFirstChar { char -> if (char.isLowerCase()) char.titlecase(Locale.getDefault()) else it } }
return str.split(" ").joinToString(" ") {
it.lowercase()
.replaceFirstChar { char -> if (char.isLowerCase()) char.titlecase(Locale.getDefault()) else it }
}
}
/** https://www.imdb.com/title/tt2861424/ -> tt2861424 */
@ -623,13 +625,14 @@ fun TvType.isAnimeOp(): Boolean {
data class SubtitleFile(val lang: String, val url: String)
class HomePageResponse(
data class HomePageResponse(
val items: List<HomePageList>
)
class HomePageList(
data class HomePageList(
val name: String,
var list: List<SearchResponse>
var list: List<SearchResponse>,
val isHorizontalImages: Boolean = false
)
enum class SearchQuality {
@ -865,6 +868,19 @@ data class MovieSearchResponse(
override var posterHeaders: Map<String, String>? = null,
) : SearchResponse
data class LiveSearchResponse(
override val name: String,
override val url: String,
override val apiName: String,
override var type: TvType? = null,
override var posterUrl: String? = null,
override var id: Int? = null,
override var quality: SearchQuality? = null,
override var posterHeaders: Map<String, String>? = null,
val lang: String? = null,
) : SearchResponse
data class TvSeriesSearchResponse(
override val name: String,
override val url: String,

View file

@ -1,13 +1,11 @@
package com.lagradost.cloudstream3.liveproviders
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
class EjaTv : MainAPI() {
override var mainUrl = "https://eja.tv/"
@ -22,18 +20,19 @@ class EjaTv : MainAPI() {
TvType.Live
)
private fun Element.toSearchResponse(): MovieSearchResponse? {
private fun Element.toSearchResponse(): LiveSearchResponse? {
val link = this.select("div.alternative a").last() ?: return null
val href = fixUrl(link.attr("href"))
val img = this.select("div.thumb img")
return MovieSearchResponse(
val img = this.selectFirst("div.thumb img")
val lang = this.selectFirst(".card-title > a")?.attr("href")?.removePrefix("?country=")
return LiveSearchResponse(
// Kinda hack way to get the title
img.attr("alt").replaceFirst("Watch ", ""),
img?.attr("alt")?.replaceFirst("Watch ", "") ?: return null,
href,
this@EjaTv.name,
TvType.Live,
fixUrl(img.attr("src"))
fixUrl(img.attr("src")),
lang = lang
)
}
@ -46,13 +45,15 @@ class EjaTv : MainAPI() {
"Entertainment" to mapOf("language" to language, "category" to "Entertainment")
)
return HomePageResponse(dataMap.apmap { (title, data) ->
println("ADDED isHorizontalImages")
val document = app.post(mainUrl, data = data).document
val shows = document.select("div.card-body").mapNotNull {
it.toSearchResponse()
}
HomePageList(
title,
shows
shows,
isHorizontalImages = true
)
})
}

View file

@ -11,26 +11,31 @@ import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchResponseDiffCallback
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.utils.UIHelper.IsBottomLayout
import kotlinx.android.synthetic.main.home_result_grid.view.*
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.android.synthetic.main.home_result_grid.view.background_card
import kotlinx.android.synthetic.main.home_result_grid_expanded.view.*
class HomeChildItemAdapter(
val cardList: MutableList<SearchResponse>,
private val overrideLayout : Int? = null,
private val overrideLayout: Int? = null,
private val nextFocusUp: Int? = null,
private val nextFocusDown: Int? = null,
private val clickCallback: (SearchClickCallback) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var isHorizontal: Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = overrideLayout ?: if(parent.context.IsBottomLayout()) R.layout.home_result_grid_expanded else R.layout.home_result_grid
val layout = overrideLayout
?: if (parent.context.IsBottomLayout()) R.layout.home_result_grid_expanded else R.layout.home_result_grid
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
clickCallback,
itemCount,
nextFocusUp,
nextFocusDown
nextFocusDown,
isHorizontal
)
}
@ -68,6 +73,7 @@ class HomeChildItemAdapter(
private val itemCount: Int,
private val nextFocusUp: Int? = null,
private val nextFocusDown: Int? = null,
private val isHorizontal: Boolean = false
) :
RecyclerView.ViewHolder(itemView) {
@ -80,6 +86,26 @@ class HomeChildItemAdapter(
else -> null
}
(itemView.image_holder ?: itemView.background_card)?.apply {
val min = 114.toPx
val max = 180.toPx
layoutParams =
layoutParams.apply {
width = if (!isHorizontal) {
min
} else {
max
}
height = if (!isHorizontal) {
max
} else {
min
}
}
}
SearchResultBuilder.bind(
clickCallback,
card,

View file

@ -12,6 +12,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.widget.SearchView
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
@ -505,8 +506,9 @@ class HomeFragment : Fragment() {
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(
d?.items?.mapNotNull {
try {
listHomepageItems.addAll(it.list.filterSearchResponse())
HomePageList(it.name, it.list.filterSearchResponse())
val filter = it.list.filterSearchResponse()
listHomepageItems.addAll(filter)
it.copy(list = filter)
} catch (e: Exception) {
logError(e)
null
@ -518,6 +520,8 @@ class HomeFragment : Fragment() {
home_loaded?.isVisible = true
if (toggleRandomButton) {
home_random?.isVisible = listHomepageItems.isNotEmpty()
} else {
home_random?.isGone = true
}
}
is Resource.Failure -> {

View file

@ -83,8 +83,11 @@ class ParentItemAdapter(
info.list.toMutableList(),
clickCallback = clickCallback,
nextFocusUp = recyclerView.nextFocusUpId,
nextFocusDown = recyclerView.nextFocusDownId
)
nextFocusDown = recyclerView.nextFocusDownId,
).apply {
isHorizontal = info.isHorizontalImages
}
//(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
moreInfo?.setOnClickListener {

View file

@ -13,6 +13,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueT
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual
import com.lagradost.cloudstream3.utils.SubtitleHelper
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.android.synthetic.main.home_result_grid.view.*
@ -46,6 +47,7 @@ object SearchResultBuilder {
val textIsDub: TextView? = itemView.text_is_dub
val textIsSub: TextView? = itemView.text_is_sub
val textFlag: TextView? = itemView.text_flag
val textQuality: TextView? = itemView.text_quality
val shadow: View? = itemView.title_shadow
@ -60,6 +62,7 @@ object SearchResultBuilder {
playImg?.isVisible = false
textIsDub?.isVisible = false
textIsSub?.isVisible = false
textFlag?.isVisible = false
val showSub = showCache[textIsDub?.context?.getString(R.string.show_sub_key)] ?: false
val showDub = showCache[textIsDub?.context?.getString(R.string.show_dub_key)] ?: false
@ -188,6 +191,14 @@ object SearchResultBuilder {
}
when (card) {
is LiveSearchResponse -> {
SubtitleHelper.getFlagFromIso(card.lang)?.let { flagEmoji ->
textFlag?.apply {
isVisible = true
text = flagEmoji
}
}
}
is DataStoreHelper.ResumeWatchingResult -> {
val pos = card.watchPos?.fixVisual()
if (pos != null) {

View file

@ -116,15 +116,30 @@ object SubtitleHelper {
private const val asciiOffset = 0x41
private const val offset = flagOffset - asciiOffset
private val flagRegex = Regex("[\uD83C\uDDE6-\uD83C\uDDFF]{2}")
fun getFlagFromIso(inp: String?): String? {
try {
flags[inp ?: return null]?.let { flagAscii ->
val firstChar: Int = Character.codePointAt(flagAscii, 0) + offset
val secondChar: Int = Character.codePointAt(flagAscii, 1) + offset
val ret = getFlagFromIsoShort(flags[inp ?: return null])
?: getFlagFromIsoShort(inp.uppercase()) ?: return null
return (String(Character.toChars(firstChar)) + String(Character.toChars(secondChar)))
return if (flagRegex.matches(ret)) {
ret
} else {
null
}
} catch (e: Exception) {
logError(e)
return null
}
}
private fun getFlagFromIsoShort(flagAscii: String?): String? {
try {
val firstChar: Int = Character.codePointAt(flagAscii ?: return null, 0) + offset
val secondChar: Int = Character.codePointAt(flagAscii, 1) + offset
return (String(Character.toChars(firstChar)) + String(Character.toChars(secondChar)))
} catch (e: Exception) {
logError(e)
return null

View file

@ -90,7 +90,7 @@
tools:text="@string/quality_hd"
android:id="@+id/text_quality"
style="@style/SearchBox"
android:background="@drawable/type_bg_color"/>
android:background="@drawable/type_bg_color" />
<LinearLayout
android:orientation="vertical"
@ -117,5 +117,15 @@
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@drawable/sub_bg_color" />
<TextView
tools:visibility="visible"
android:visibility="gone"
android:textSize="20sp"
android:id="@+id/text_flag"
tools:text="🇸🇪"
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@color/transparent" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -22,6 +22,7 @@
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/image_holder"
android:layout_width="114dp"
android:layout_height="180dp"
android:elevation="10dp"
@ -105,6 +106,16 @@
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@drawable/sub_bg_color" />
<TextView
tools:visibility="visible"
android:visibility="gone"
android:textSize="20sp"
android:id="@+id/text_flag"
tools:text="🇸🇪"
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@color/transparent" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -83,6 +83,16 @@
android:layout_gravity="end"
style="@style/SearchBox"
android:background="@drawable/sub_bg_color" />
<TextView
tools:visibility="visible"
android:visibility="gone"
android:textSize="20sp"
android:id="@+id/text_flag"
tools:text="🇸🇪"
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@color/transparent" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -58,6 +58,16 @@
android:layout_gravity="end"
style="@style/SearchBox"
android:background="@drawable/sub_bg_color" />
<TextView
tools:visibility="visible"
android:visibility="gone"
android:textSize="20sp"
android:id="@+id/text_flag"
tools:text="🇸🇪"
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@color/transparent" />
</LinearLayout>
</androidx.cardview.widget.CardView>