moved to List + animations

This commit is contained in:
LagradOst 2022-03-03 12:26:26 +01:00
parent 5d20feb2ad
commit 8aa907d1d9
13 changed files with 296 additions and 267 deletions

View file

@ -6,10 +6,17 @@ import android.content.res.ColorStateList
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.view.KeyEvent import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager import android.view.WindowManager
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavOptions
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
@ -270,6 +277,31 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
} }
} }
private fun NavDestination.matchDestination(@IdRes destId: Int): Boolean =
hierarchy.any { it.id == destId }
private fun onNavDestinationSelected(item: MenuItem, navController: NavController): Boolean {
val builder = NavOptions.Builder().setLaunchSingleTop(true).setRestoreState(true)
.setEnterAnim(R.anim.enter_anim)
.setExitAnim(R.anim.exit_anim)
.setPopEnterAnim(R.anim.pop_enter)
.setPopExitAnim(R.anim.pop_exit)
if (item.order and Menu.CATEGORY_SECONDARY == 0) {
builder.setPopUpTo(
navController.graph.findStartDestination().id,
inclusive = false,
saveState = true
)
}
val options = builder.build()
return try {
navController.navigate(item.itemId, null, options)
navController.currentDestination?.matchDestination(item.itemId) == true
} catch (e: IllegalArgumentException) {
false
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// init accounts // init accounts
for (api in OAuth2accountApis) { for (api in OAuth2accountApis) {
@ -315,9 +347,23 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
nav_view?.setupWithNavController(navController) nav_view?.setupWithNavController(navController)
val navRail = findViewById<NavigationRailView?>(R.id.nav_rail_view) val navRail = findViewById<NavigationRailView?>(R.id.nav_rail_view)
navRail?.setupWithNavController(navController) navRail?.setupWithNavController(navController)
navRail?.setOnItemSelectedListener { item ->
onNavDestinationSelected(
item,
navController
)
}
nav_view?.setOnItemSelectedListener { item ->
onNavDestinationSelected(
item,
navController
)
}
navController.addOnDestinationChangedListener { _, destination, _ -> navController.addOnDestinationChangedListener { _, destination, _ ->
updateNavBar(destination) updateNavBar(destination)
} }
loadCache() loadCache()
/*nav_view.setOnNavigationItemSelectedListener { item -> /*nav_view.setOnNavigationItemSelectedListener { item ->

View file

@ -140,14 +140,14 @@ class AnimePaheProvider : MainAPI() {
} }
override suspend fun search(query: String): ArrayList<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/api?m=search&l=8&q=$query" val url = "$mainUrl/api?m=search&l=8&q=$query"
val headers = mapOf("referer" to "$mainUrl/") val headers = mapOf("referer" to "$mainUrl/")
val req = app.get(url, headers = headers).text val req = app.get(url, headers = headers).text
val data = req.let { mapper.readValue<AnimePaheSearch>(it) } val data = req.let { mapper.readValue<AnimePaheSearch>(it) }
return ArrayList(data.data.map { return data.data.map {
AnimeSearchResponse( AnimeSearchResponse(
it.title, it.title,
"https://pahe.win/a/${it.id}?slug=${it.title}", "https://pahe.win/a/${it.id}?slug=${it.title}",
@ -160,7 +160,7 @@ class AnimePaheProvider : MainAPI() {
null, null,
it.episodes it.episodes
) )
}) }
} }
private data class AnimeData( private data class AnimeData(

View file

@ -4,7 +4,6 @@ import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.loadExtractor
import java.util.* import java.util.*
import kotlin.collections.ArrayList
class AnimeflvnetProvider : MainAPI() { class AnimeflvnetProvider : MainAPI() {
companion object { companion object {
@ -63,11 +62,10 @@ class AnimeflvnetProvider : MainAPI() {
return HomePageResponse(items) return HomePageResponse(items)
} }
override suspend fun search(query: String): ArrayList<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val url = "${mainUrl}/browse?q=${query}" val url = "${mainUrl}/browse?q=${query}"
val doc = app.get(url).document val doc = app.get(url).document
val episodes = doc.select("ul.List-Animes li.Anime").map { return doc.select("ul.List-Animes li.Anime").map {
val title = it.selectFirst("h2.title").text() val title = it.selectFirst("h2.title").text()
val href = fixUrl(it.selectFirst("a").attr("href")) val href = fixUrl(it.selectFirst("a").attr("href"))
val image = it.selectFirst(".Image img").attr("src") val image = it.selectFirst(".Image img").attr("src")
@ -83,7 +81,6 @@ class AnimeflvnetProvider : MainAPI() {
), ),
) )
} }
return ArrayList(episodes)
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {

View file

@ -73,7 +73,10 @@ class DubbedAnimeProvider : MainAPI() {
} }
} }
private suspend fun parseDocument(url: String, trimEpisode: Boolean = false): List<SearchResponse> { private suspend fun parseDocument(
url: String,
trimEpisode: Boolean = false
): List<SearchResponse> {
val response = app.get(url).text val response = app.get(url).text
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
return document.select("a.grid__link").map { return document.select("a.grid__link").map {
@ -131,31 +134,28 @@ class DubbedAnimeProvider : MainAPI() {
val response = app.get(url).text val response = app.get(url).text
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
val items = document.select("div.grid__item > a") val items = document.select("div.grid__item > a")
if (items.isEmpty()) return ArrayList() if (items.isEmpty()) return emptyList()
val returnValue = ArrayList<SearchResponse>() return items.map { i ->
for (i in items) {
val href = fixUrl(i.attr("href")) val href = fixUrl(i.attr("href"))
val title = i.selectFirst("div.gridtitlek").text() val title = i.selectFirst("div.gridtitlek").text()
val img = fixUrlNull(i.selectFirst("img.grid__img")?.attr("src")) val img = fixUrlNull(i.selectFirst("img.grid__img")?.attr("src"))
returnValue.add(
if (getIsMovie(href)) { if (getIsMovie(href)) {
MovieSearchResponse( MovieSearchResponse(
title, href, this.name, TvType.AnimeMovie, img, null title, href, this.name, TvType.AnimeMovie, img, null
) )
} else { } else {
AnimeSearchResponse( AnimeSearchResponse(
title, title,
href, href,
this.name, this.name,
TvType.Anime, TvType.Anime,
img, img,
null, null,
EnumSet.of(DubStatus.Dubbed), EnumSet.of(DubStatus.Dubbed),
) )
} }
)
} }
return returnValue
} }
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
@ -164,33 +164,28 @@ class DubbedAnimeProvider : MainAPI() {
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
val items = document.select("div.resultinner > a.resulta") val items = document.select("div.resultinner > a.resulta")
if (items.isEmpty()) return ArrayList() if (items.isEmpty()) return ArrayList()
val returnValue = ArrayList<SearchResponse>() return items.map { i ->
for (i in items) {
val innerDiv = i.selectFirst("> div.result") val innerDiv = i.selectFirst("> div.result")
val href = fixUrl(i.attr("href")) val href = fixUrl(i.attr("href"))
val img = fixUrl(innerDiv.selectFirst("> div.imgkz > img").attr("src")) val img = fixUrl(innerDiv.selectFirst("> div.imgkz > img").attr("src"))
val title = innerDiv.selectFirst("> div.titleresults").text() val title = innerDiv.selectFirst("> div.titleresults").text()
returnValue.add( if (getIsMovie(href)) {
if (getIsMovie(href)) { MovieSearchResponse(
MovieSearchResponse( title, href, this.name, TvType.AnimeMovie, img, null
title, href, this.name, TvType.AnimeMovie, img, null )
) } else {
} else { AnimeSearchResponse(
AnimeSearchResponse( title,
title, href,
href, this.name,
this.name, TvType.Anime,
TvType.Anime, img,
img, null,
null, EnumSet.of(DubStatus.Dubbed),
EnumSet.of(DubStatus.Dubbed), )
) }
}
)
} }
return returnValue
} }
override suspend fun loadLinks( override suspend fun loadLinks(

View file

@ -191,7 +191,7 @@ class TenshiProvider : MainAPI() {
// return returnValue // return returnValue
// } // }
override suspend fun search(query: String): ArrayList<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/anime" val url = "$mainUrl/anime"
var document = app.get( var document = app.get(
url, url,
@ -203,10 +203,10 @@ class TenshiProvider : MainAPI() {
val returnValue = parseSearchPage(document).toMutableList() val returnValue = parseSearchPage(document).toMutableList()
while (!document.select("""a.page-link[rel="next"]""").isEmpty()) { while (!document.select("""a.page-link[rel="next"]""").isEmpty()) {
val link = document.select("""a.page-link[rel="next"]""") val link = document.selectFirst("""a.page-link[rel="next"]""")?.attr("href")
if (link != null && !link.isEmpty()) { if (!link.isNullOrBlank()) {
document = app.get( document = app.get(
link[0].attr("href"), link,
cookies = mapOf("loop-view" to "thumb"), cookies = mapOf("loop-view" to "thumb"),
interceptor = ddosGuardKiller interceptor = ddosGuardKiller
).document ).document
@ -216,7 +216,7 @@ class TenshiProvider : MainAPI() {
} }
} }
return ArrayList(returnValue) return returnValue
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {

View file

@ -79,11 +79,10 @@ class WcoProvider : MainAPI() {
return "$mainUrl/anime/$aniId" return "$mainUrl/anime/$aniId"
} }
private fun parseSearchPage(soup: Document): ArrayList<SearchResponse> { private fun parseSearchPage(soup: Document): List<SearchResponse> {
val items = soup.select(".film_list-wrap > .flw-item") val items = soup.select(".film_list-wrap > .flw-item")
if (items.isEmpty()) return ArrayList() if (items.isEmpty()) return ArrayList()
val returnValue = ArrayList<SearchResponse>() return items.map { i ->
for (i in items) {
val href = fixAnimeLink(i.selectFirst("a").attr("href")) val href = fixAnimeLink(i.selectFirst("a").attr("href"))
val img = fixUrl(i.selectFirst("img").attr("data-src")) val img = fixUrl(i.selectFirst("img").attr("data-src"))
val title = i.selectFirst("img").attr("title") val title = i.selectFirst("img").attr("title")
@ -94,25 +93,22 @@ class WcoProvider : MainAPI() {
val type = val type =
i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text()
returnValue.add( if (getType(type) == TvType.AnimeMovie) {
if (getType(type) == TvType.AnimeMovie) { MovieSearchResponse(
MovieSearchResponse( title, href, this.name, TvType.AnimeMovie, img, year
title, href, this.name, TvType.AnimeMovie, img, year )
) } else {
} else { AnimeSearchResponse(
AnimeSearchResponse( title,
title, href,
href, this.name,
this.name, TvType.Anime,
TvType.Anime, img,
img, year,
year, EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed),
EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed), )
) }
}
)
} }
return returnValue
} }
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
@ -120,7 +116,7 @@ class WcoProvider : MainAPI() {
val response = val response =
app.get(url, params = mapOf("keyword" to query)) app.get(url, params = mapOf("keyword" to query))
var document = Jsoup.parse(response.text) var document = Jsoup.parse(response.text)
val returnValue = parseSearchPage(document) val returnValue = parseSearchPage(document).toMutableList()
while (!document.select(".pagination").isEmpty()) { while (!document.select(".pagination").isEmpty()) {
val link = document.select("a.page-link[rel=\"next\"]") val link = document.select("a.page-link[rel=\"next\"]")
@ -136,8 +132,6 @@ class WcoProvider : MainAPI() {
} }
override suspend fun quickSearch(query: String): List<SearchResponse> { override suspend fun quickSearch(query: String): List<SearchResponse> {
val returnValue: ArrayList<SearchResponse> = ArrayList()
val response = JSONObject( val response = JSONObject(
app.post( app.post(
"https://wcostream.cc/ajax/search", "https://wcostream.cc/ajax/search",
@ -146,35 +140,30 @@ class WcoProvider : MainAPI() {
).getString("html") // I won't make a dataclass for this shit ).getString("html") // I won't make a dataclass for this shit
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
document.select("a.nav-item").forEach { return document.select("a.nav-item").mapNotNull {
val title = it.selectFirst("img")?.attr("title").toString() val title = it.selectFirst("img")?.attr("title") ?: return@mapNotNull null
val img = it?.selectFirst("img")?.attr("src") val img = it?.selectFirst("img")?.attr("src") ?: return@mapNotNull null
val href = it?.attr("href").toString() val href = it?.attr("href") ?: return@mapNotNull null
val isDub = title.contains("(Dub)") val isDub = title.contains("(Dub)")
val filmInfo = it?.selectFirst(".film-infor") val filmInfo = it.selectFirst(".film-infor")
val year = filmInfo?.select("span")?.get(0)?.text()?.toIntOrNull() val year = filmInfo?.select("span")?.get(0)?.text()?.toIntOrNull()
val type = filmInfo?.select("span")?.get(1)?.text().toString() val type = filmInfo?.select("span")?.get(1)?.text().toString()
if (title != "null") { if (getType(type) == TvType.AnimeMovie) {
returnValue.add( MovieSearchResponse(
if (getType(type) == TvType.AnimeMovie) { title, href, this.name, TvType.AnimeMovie, img, year
MovieSearchResponse( )
title, href, this.name, TvType.AnimeMovie, img, year } else {
) AnimeSearchResponse(
} else { title,
AnimeSearchResponse( href,
title, this.name,
href, TvType.Anime,
this.name, img,
TvType.Anime, year,
img, EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed),
year,
EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed),
)
}
) )
} }
} }
return returnValue
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {

View file

@ -37,29 +37,25 @@ class AllMoviesForYouProvider : MainAPI() {
val document = app.get(url).document val document = app.get(url).document
val items = document.select("ul.MovieList > li > article > a") val items = document.select("ul.MovieList > li > article > a")
val returnValue = ArrayList<SearchResponse>() return items.map { item ->
for (item in items) {
val href = item.attr("href") val href = item.attr("href")
val title = item.selectFirst("> h2.Title").text() val title = item.selectFirst("> h2.Title").text()
val img = fixUrl(item.selectFirst("> div.Image > figure > img").attr("data-src")) val img = fixUrl(item.selectFirst("> div.Image > figure > img").attr("data-src"))
val type = getType(href) val type = getType(href)
if (type == TvType.Movie) { if (type == TvType.Movie) {
returnValue.add(MovieSearchResponse(title, href, this.name, type, img, null)) MovieSearchResponse(title, href, this.name, type, img, null)
} else if (type == TvType.TvSeries) { } else {
returnValue.add( TvSeriesSearchResponse(
TvSeriesSearchResponse( title,
title, href,
href, this.name,
this.name, type,
type, img,
img, null,
null, null
null
)
) )
} }
} }
return returnValue
} }
private fun getLink(document: Document): List<String>? { private fun getLink(document: Document): List<String>? {

View file

@ -5,7 +5,6 @@ import com.lagradost.cloudstream3.extractors.FEmbed
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.loadExtractor
import java.util.* import java.util.*
import kotlin.collections.ArrayList
class DoramasYTProvider : MainAPI() { class DoramasYTProvider : MainAPI() {
@ -99,25 +98,23 @@ class DoramasYTProvider : MainAPI() {
return HomePageResponse(items) return HomePageResponse(items)
} }
override suspend fun search(query: String): ArrayList<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val search = return app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map {
app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { val title = it.selectFirst(".animedtls p").text()
val title = it.selectFirst(".animedtls p").text() val href = it.selectFirst("a").attr("href")
val href = it.selectFirst("a").attr("href") val image = it.selectFirst(".animes img").attr("src")
val image = it.selectFirst(".animes img").attr("src") AnimeSearchResponse(
AnimeSearchResponse( title,
title, href,
href, this.name,
this.name, TvType.Anime,
TvType.Anime, image,
image, null,
null, if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( DubStatus.Dubbed
DubStatus.Dubbed ) else EnumSet.of(DubStatus.Subbed),
) else EnumSet.of(DubStatus.Subbed), )
) }
}
return ArrayList(search)
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {

View file

@ -25,13 +25,12 @@ class FilmanProvider : MainAPI() {
val categories = ArrayList<HomePageList>() val categories = ArrayList<HomePageList>()
for (l in lists) { for (l in lists) {
val title = l.parent().select("h3").text() val title = l.parent().select("h3").text()
val items = ArrayList<SearchResponse>() val items = l.select(".poster").map { i ->
for (i in l.select(".poster")) {
val name = i.select("a[href]").attr("title") val name = i.select("a[href]").attr("title")
val href = i.select("a[href]").attr("href") val href = i.select("a[href]").attr("href")
val poster = i.select("img[src]").attr("src") val poster = i.select("img[src]").attr("src")
val year = l.select(".film_year").text().toIntOrNull() val year = l.select(".film_year").text().toIntOrNull()
val returnValue = if (l.hasClass("series-list")) TvSeriesSearchResponse( if (l.hasClass("series-list")) TvSeriesSearchResponse(
name, name,
href, href,
this.name, this.name,
@ -47,7 +46,6 @@ class FilmanProvider : MainAPI() {
poster, poster,
year year
) )
items.add(returnValue)
} }
categories.add(HomePageList(title, items)) categories.add(HomePageList(title, items))
} }
@ -62,29 +60,25 @@ class FilmanProvider : MainAPI() {
val movies = lists[1].select(".item") val movies = lists[1].select(".item")
val series = lists[3].select(".item") val series = lists[3].select(".item")
if (movies.isEmpty() && series.isEmpty()) return ArrayList() if (movies.isEmpty() && series.isEmpty()) return ArrayList()
fun getVideos(type: TvType, items: Elements): ArrayList<SearchResponse> { fun getVideos(type: TvType, items: Elements): List<SearchResponse> {
val returnValue = ArrayList<SearchResponse>() return items.map { i ->
for (i in items) {
val href = i.attr("href") val href = i.attr("href")
val img = i.selectFirst("> img").attr("src").replace("/thumb/", "/big/") val img = i.selectFirst("> img").attr("src").replace("/thumb/", "/big/")
val name = i.selectFirst(".title").text() val name = i.selectFirst(".title").text()
if (type === TvType.TvSeries) { if (type === TvType.TvSeries) {
returnValue.add( TvSeriesSearchResponse(
TvSeriesSearchResponse( name,
name, href,
href, this.name,
this.name, type,
type, img,
img, null,
null, null
null
)
) )
} else { } else {
returnValue.add(MovieSearchResponse(name, href, this.name, type, img, null)) MovieSearchResponse(name, href, this.name, type, img, null)
} }
} }
return returnValue
} }
return getVideos(TvType.Movie, movies) + getVideos(TvType.TvSeries, series) return getVideos(TvType.Movie, movies) + getVideos(TvType.TvSeries, series)
} }
@ -102,22 +96,17 @@ class FilmanProvider : MainAPI() {
return MovieLoadResponse(title, url, name, TvType.Movie, data, posterUrl, year, plot) return MovieLoadResponse(title, url, name, TvType.Movie, data, posterUrl, year, plot)
} }
title = document.selectFirst(".info").parent().select("h2").text() title = document.selectFirst(".info").parent().select("h2").text()
val episodes = ArrayList<TvSeriesEpisode>() val episodes = episodesElements.mapNotNull { episode ->
for (episode in episodesElements) {
val e = episode.text() val e = episode.text()
val regex = Regex("""\[s(\d{1,3})e(\d{1,3})]""").find(e) val regex = Regex("""\[s(\d{1,3})e(\d{1,3})]""").find(e) ?: return@mapNotNull null
if (regex != null) { val eid = regex.groups
val eid = regex.groups TvSeriesEpisode(
episodes.add( e.split("]")[1].trim(),
TvSeriesEpisode( eid[1]?.value?.toInt(),
e.split("]")[1].trim(), eid[2]?.value?.toInt(),
eid[1]?.value?.toInt(), episode.attr("href"),
eid[2]?.value?.toInt(), )
episode.attr("href"), }.toMutableList()
)
)
}
}
episodes.sortBy { (it.season?.times(10000) ?: 0) + (it.episode ?: 0) } episodes.sortBy { (it.season?.times(10000) ?: 0) + (it.episode ?: 0) }
return TvSeriesLoadResponse( return TvSeriesLoadResponse(
title, title,

View file

@ -19,17 +19,15 @@ class HDMProvider : MainAPI() {
val response = app.get(url).text val response = app.get(url).text
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
val items = document.select("div.col-md-2 > article > a") val items = document.select("div.col-md-2 > article > a")
if (items.isEmpty()) return ArrayList() if (items.isEmpty()) return emptyList()
val returnValue = ArrayList<SearchResponse>()
for (i in items) { return items.map { i ->
val href = i.attr("href") val href = i.attr("href")
val data = i.selectFirst("> div.item") val data = i.selectFirst("> div.item")
val img = data.selectFirst("> img").attr("src") val img = data.selectFirst("> img").attr("src")
val name = data.selectFirst("> div.movie-details").text() val name = data.selectFirst("> div.movie-details").text()
returnValue.add(MovieSearchResponse(name, href, this.name, TvType.Movie, img, null)) MovieSearchResponse(name, href, this.name, TvType.Movie, img, null)
} }
return returnValue
} }
override suspend fun loadLinks( override suspend fun loadLinks(
@ -72,7 +70,7 @@ class HDMProvider : MainAPI() {
} }
override suspend fun getMainPage(): HomePageResponse { override suspend fun getMainPage(): HomePageResponse {
val html = app.get("$mainUrl", timeout = 25).text val html = app.get(mainUrl, timeout = 25).text
val document = Jsoup.parse(html) val document = Jsoup.parse(html)
val all = ArrayList<HomePageList>() val all = ArrayList<HomePageList>()

View file

@ -110,36 +110,31 @@ class LookMovieProvider : MainAPI() {
} }
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
suspend fun search(query: String, isMovie: Boolean): ArrayList<SearchResponse> { suspend fun search(query: String, isMovie: Boolean): List<SearchResponse> {
val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query" val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query"
val response = app.get(url).text val response = app.get(url).text
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1") val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1")
val returnValue = ArrayList<SearchResponse>() return items.map { item ->
items.forEach { item ->
val titleHolder = item.selectFirst("> div.mv-item-infor > h6 > a") val titleHolder = item.selectFirst("> div.mv-item-infor > h6 > a")
val href = fixUrl(titleHolder.attr("href")) val href = fixUrl(titleHolder.attr("href"))
val name = titleHolder.text() val name = titleHolder.text()
val posterHolder = item.selectFirst("> div.image__placeholder > a") val posterHolder = item.selectFirst("> div.image__placeholder > a")
val poster = posterHolder.selectFirst("> img")?.attr("data-src") val poster = posterHolder.selectFirst("> img")?.attr("data-src")
val year = posterHolder.selectFirst("> p.year")?.text()?.toIntOrNull() val year = posterHolder.selectFirst("> p.year")?.text()?.toIntOrNull()
if (isMovie) {
returnValue.add( MovieSearchResponse(
if (isMovie) { name, href, this.name, TvType.Movie, poster, year
MovieSearchResponse( )
name, href, this.name, TvType.Movie, poster, year } else
) TvSeriesSearchResponse(
} else name, href, this.name, TvType.TvSeries, poster, year, null
TvSeriesSearchResponse( )
name, href, this.name, TvType.TvSeries, poster, year, null
)
)
} }
return returnValue
} }
val movieList = search(query, true) val movieList = search(query, true).toMutableList()
val seriesList = search(query, false) val seriesList = search(query, false)
movieList.addAll(seriesList) movieList.addAll(seriesList)
return movieList return movieList

View file

@ -13,11 +13,11 @@ class FrenchStreamProvider : MainAPI() {
override val lang = "fr" override val lang = "fr"
override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie)
override suspend fun search(query: String): ArrayList<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val link = "$mainUrl/?do=search&subaction=search&story=$query" val link = "$mainUrl/?do=search&subaction=search&story=$query"
val soup = app.post(link).document val soup = app.post(link).document
return ArrayList(soup.select("div.short-in.nl").map { li -> return soup.select("div.short-in.nl").map { li ->
val href = fixUrl(li.selectFirst("a.short-poster").attr("href")) val href = fixUrl(li.selectFirst("a.short-poster").attr("href"))
val poster = li.selectFirst("img")?.attr("src") val poster = li.selectFirst("img")?.attr("src")
val title = li.selectFirst("> a.short-poster").text().toString().replace(". ", "") val title = li.selectFirst("> a.short-poster").text().toString().replace(". ", "")
@ -46,7 +46,7 @@ class FrenchStreamProvider : MainAPI() {
year, year,
) )
} }
}) }
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {

View file

@ -1,74 +1,67 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android" <navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation" android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home"> app:startDestination="@+id/navigation_home">
<action android:id="@+id/global_to_navigation_results" <action
android:id="@+id/global_to_navigation_results"
app:destination="@id/navigation_results" app:destination="@id/navigation_results"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim">
>
<argument <argument
android:name="url" android:name="url"
app:argType="string"/> app:argType="string" />
<argument <argument
android:name="apiName" android:name="apiName"
app:argType="string" app:argType="string" />
/>
<argument <argument
android:name="startAction" android:name="startAction"
app:argType="integer" app:argType="integer"
android:defaultValue="0" android:defaultValue="0" />
/>
<argument <argument
android:name="startValue" android:name="startValue"
app:argType="integer" app:argType="integer"
android:defaultValue="0" android:defaultValue="0" />
/>
<argument <argument
android:name="restart" android:name="restart"
app:argType="boolean" app:argType="boolean"
android:defaultValue="false" android:defaultValue="false" />
/>
</action> </action>
<action android:id="@+id/global_to_navigation_player" <action
android:id="@+id/global_to_navigation_player"
app:destination="@id/navigation_player" app:destination="@id/navigation_player"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim">
>
<argument <argument
android:name="data" android:name="data"
app:argType="string" app:argType="string"
android:defaultValue="@null" android:defaultValue="@null" />
/>
<argument <argument
android:name="uriData" android:name="uriData"
app:argType="string" app:argType="string"
android:defaultValue="@null" android:defaultValue="@null" />
/>
<argument <argument
android:name="resumePosition" android:name="resumePosition"
app:argType="long" app:argType="long"
android:defaultValue="0L" android:defaultValue="0L" />
/>
</action> </action>
<action android:id="@+id/global_to_navigation_home" <action
android:id="@+id/global_to_navigation_home"
app:destination="@id/navigation_home" app:destination="@id/navigation_home"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim" />
>
</action>
<action android:id="@+id/global_to_navigation_subtitles" <action
android:id="@+id/global_to_navigation_subtitles"
app:destination="@id/navigation_subtitles" app:destination="@id/navigation_subtitles"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
@ -77,11 +70,11 @@
<argument <argument
android:name="hide" android:name="hide"
app:argType="boolean" app:argType="boolean"
android:defaultValue="true" android:defaultValue="true" />
/>
</action> </action>
<action android:id="@+id/global_to_navigation_chrome_subtitles" <action
android:id="@+id/global_to_navigation_chrome_subtitles"
app:destination="@id/navigation_chrome_subtitles" app:destination="@id/navigation_chrome_subtitles"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
@ -90,11 +83,11 @@
<argument <argument
android:name="hide" android:name="hide"
app:argType="boolean" app:argType="boolean"
android:defaultValue="true" android:defaultValue="true" />
/>
</action> </action>
<action android:id="@+id/global_to_navigation_quick_search" <action
android:id="@+id/global_to_navigation_quick_search"
app:destination="@id/navigation_quick_search" app:destination="@id/navigation_quick_search"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
@ -103,109 +96,143 @@
<argument <argument
android:name="mainapi" android:name="mainapi"
app:argType="boolean" app:argType="boolean"
android:defaultValue="true" android:defaultValue="true" />
/>
<argument <argument
android:name="autosearch" android:name="autosearch"
app:argType="string" app:argType="string"
android:defaultValue="@null" android:defaultValue="@null" />
/>
</action> </action>
<action android:id="@+id/global_to_navigation_settings" <action
android:id="@+id/global_to_navigation_settings"
app:destination="@id/navigation_settings" app:destination="@id/navigation_settings"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim" />
>
</action>
<action android:id="@+id/global_to_navigation_downloads" <action
android:id="@+id/global_to_navigation_downloads"
app:destination="@id/navigation_downloads" app:destination="@id/navigation_downloads"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim" />
>
</action>
<action android:id="@+id/global_to_navigation_search" <action
android:id="@+id/global_to_navigation_search"
app:destination="@id/navigation_search" app:destination="@id/navigation_search"
app:enterAnim="@anim/enter_anim" app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim" app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim" />
>
</action>
<fragment <fragment
android:id="@+id/navigation_home" android:id="@+id/navigation_home"
android:name="com.lagradost.cloudstream3.ui.home.HomeFragment" android:name="com.lagradost.cloudstream3.ui.home.HomeFragment"
android:label="@string/title_home" android:label="@string/title_home"
tools:layout="@layout/fragment_home"/> tools:layout="@layout/fragment_home"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_search" android:id="@+id/navigation_search"
android:name="com.lagradost.cloudstream3.ui.search.SearchFragment" android:name="com.lagradost.cloudstream3.ui.search.SearchFragment"
android:label="@string/title_search" android:label="@string/title_search"
tools:layout="@layout/fragment_search"/> tools:layout="@layout/fragment_search"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_downloads" android:id="@+id/navigation_downloads"
android:name="com.lagradost.cloudstream3.ui.download.DownloadFragment" android:name="com.lagradost.cloudstream3.ui.download.DownloadFragment"
android:label="@string/title_downloads" android:label="@string/title_downloads"
tools:layout="@layout/fragment_downloads"> tools:layout="@layout/fragment_downloads"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim">
<action android:id="@+id/action_navigation_downloads_to_navigation_download_child" <action
android:id="@+id/action_navigation_downloads_to_navigation_download_child"
app:destination="@id/navigation_download_child"> app:destination="@id/navigation_download_child">
<argument <argument
android:name="name" android:name="name"
app:argType="string"/> app:argType="string" />
<argument <argument
android:name="folder" android:name="folder"
app:argType="string" app:argType="string" />
/>
</action> </action>
</fragment> </fragment>
<fragment <fragment
android:id="@+id/navigation_settings" android:id="@+id/navigation_settings"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.settings.SettingsFragment" android:name="com.lagradost.cloudstream3.ui.settings.SettingsFragment"
android:label="@string/title_settings"/> android:label="@string/title_settings"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_subtitles" android:id="@+id/navigation_subtitles"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment" android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment"
android:label="@string/subtitles_settings"/> android:label="@string/subtitles_settings"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_chrome_subtitles" android:id="@+id/navigation_chrome_subtitles"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment" android:name="com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment"
android:label="@string/chromecast_subtitles_settings"/> android:label="@string/chromecast_subtitles_settings"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_quick_search" android:id="@+id/navigation_quick_search"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment" android:name="com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment"
android:label="@string/search"/> app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim"
android:label="@string/search" />
<fragment <fragment
android:id="@+id/navigation_download_child" android:id="@+id/navigation_download_child"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.download.DownloadChildFragment" android:name="com.lagradost.cloudstream3.ui.download.DownloadChildFragment"
android:label="@string/title_settings"/> app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim"
android:label="@string/title_settings" />
<fragment <fragment
android:id="@+id/navigation_results" android:id="@+id/navigation_results"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.result.ResultFragment"/> android:name="com.lagradost.cloudstream3.ui.result.ResultFragment"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_player" android:id="@+id/navigation_player"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.player.GeneratorPlayer"/> android:name="com.lagradost.cloudstream3.ui.player.GeneratorPlayer"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
</navigation> </navigation>