removed slug

This commit is contained in:
LagradOst 2021-07-30 16:09:57 +02:00
parent 9695c980d6
commit 891d9b717f
23 changed files with 223 additions and 158 deletions

View File

@ -98,7 +98,7 @@ abstract class MainAPI {
return null
}
open fun load(slug: String): LoadResponse? {
open fun load(url: String): LoadResponse? {
return null
}
@ -185,7 +185,6 @@ class HomePageList(
interface SearchResponse {
val name: String
val url: String // PUBLIC URL FOR OPEN IN APP
val slug: String // USED FOR INTERNAL DATA
val apiName: String
val type: TvType
val posterUrl: String?
@ -195,7 +194,6 @@ interface SearchResponse {
data class AnimeSearchResponse(
override val name: String,
override val url: String,
override val slug: String,
override val apiName: String,
override val type: TvType,
@ -211,7 +209,6 @@ data class AnimeSearchResponse(
data class MovieSearchResponse(
override val name: String,
override val url: String,
override val slug: String,
override val apiName: String,
override val type: TvType,
@ -222,7 +219,6 @@ data class MovieSearchResponse(
data class TvSeriesSearchResponse(
override val name: String,
override val url: String,
override val slug: String,
override val apiName: String,
override val type: TvType,

View File

@ -160,7 +160,7 @@ class MainActivity : AppCompatActivity() {
} else {
for (api in apis) {
if (str.startsWith(api.mainUrl)) {
loadResult(str, str, api.name)
loadResult(str, api.name)
break
}
}

View File

@ -84,13 +84,12 @@ class DubbedAnimeProvider : MainAPI() {
returnValue.add(
if (getIsMovie(href)) {
MovieSearchResponse(
title, href, getSlug(href), this.name, TvType.Movie, img, null
title, href, this.name, TvType.Movie, img, null
)
} else {
AnimeSearchResponse(
title,
href,
getSlug(href),
this.name,
TvType.Anime,
img,
@ -122,13 +121,12 @@ class DubbedAnimeProvider : MainAPI() {
returnValue.add(
if (getIsMovie(href)) {
MovieSearchResponse(
title, href, getSlug(href), this.name, TvType.Movie, img, null
title, href, this.name, TvType.Movie, img, null
)
} else {
AnimeSearchResponse(
title,
href,
getSlug(href),
this.name,
TvType.Anime,
img,
@ -183,7 +181,8 @@ class DubbedAnimeProvider : MainAPI() {
return true
}
override fun load(slug: String): LoadResponse {
override fun load(url: String): LoadResponse {
val slug = url.replace("$mainUrl/","")
if (getIsMovie(slug)) {
val realSlug = slug.replace("movies/", "")
val episode = getAnimeEpisode(realSlug, true)

View File

@ -165,7 +165,6 @@ class ShiroProvider : MainAPI() {
return@map AnimeSearchResponse(
data.name.replace("Dubbed", ""), // i.english ?: i.canonicalTitle,
"$mainUrl/anime/${data.slug}",
data.slug,
this.name,
type,
"https://cdn.shiro.is/${data.image}",
@ -193,7 +192,6 @@ class ShiroProvider : MainAPI() {
return AnimeSearchResponse(
data.name.replace("Dubbed", ""), // i.english ?: i.canonicalTitle,
"$mainUrl/anime/${data.slug}",
data.slug,
this.name,
type,
"https://cdn.shiro.is/${data.image}",
@ -264,8 +262,9 @@ class ShiroProvider : MainAPI() {
return returnValue
}
override fun load(slug: String): LoadResponse? {
override fun load(url: String): LoadResponse? {
if (!autoLoadToken()) return null
val slug = url.replace("$mainUrl/anime/", "").replace("$mainUrl/", "")
val rurl = "https://tapi.shiro.is/anime/slug/${slug}?token=${token}"
val response = khttp.get(rurl, timeout = 120.0)
val mapped = response.let { mapper.readValue<AnimePage>(it.text) }
@ -286,7 +285,7 @@ class ShiroProvider : MainAPI() {
data.english,
data.japanese,
data.name.replace("Dubbed", ""),//data.canonicalTitle ?: data.name.replace("Dubbed", ""),
"$mainUrl/anime/${slug}",
"$mainUrl/anime/${url}",
this.name,
getType(data.type ?: ""),
"https://cdn.shiro.is/${data.image}",

View File

@ -54,10 +54,6 @@ class TenshiProvider : MainAPI() {
return movies.contains(aniId)
}
private fun getSlug(href: String): String {
return href.replace("$mainUrl/anime/", "")
}
private fun parseSearchPage(soup: Document): ArrayList<SearchResponse> {
val items = soup.select("ul.thumb > li > a")
if (items.isEmpty()) return ArrayList()
@ -70,13 +66,12 @@ class TenshiProvider : MainAPI() {
returnValue.add(
if (getIsMovie(href, true)) {
MovieSearchResponse(
title, href, getSlug(href), this.name, TvType.Movie, img, null
title, href, this.name, TvType.Movie, img, null
)
} else {
AnimeSearchResponse(
title,
href,
getSlug(href),
this.name,
TvType.Anime,
img,
@ -170,9 +165,7 @@ class TenshiProvider : MainAPI() {
return returnValue
}
override fun load(slug: String): LoadResponse {
val url = "$mainUrl/anime/${slug}"
override fun load(url: String): LoadResponse {
val response = khttp.get(url, timeout = 120.0, cookies=mapOf("loop-view" to "thumb"))
val document = Jsoup.parse(response.text)
@ -213,7 +206,7 @@ class TenshiProvider : MainAPI() {
englishTitle,
japaneseTitle,
canonicalTitle,
"$mainUrl/anime/${slug}",
url,
this.name,
TenshiProvider.getType(type ?: ""),
poster,

View File

@ -25,11 +25,6 @@ class WcoProvider : MainAPI() {
override val hasQuickSearch: Boolean
get() = true
private fun getSlug(href: String): String {
return href.replace("$mainUrl/anime/", "").replace("/", "")
}
private fun fixAnimeLink(url: String): String {
val regex = "watch/([a-zA-Z\\-0-9]*)-episode".toRegex()
val (aniId) = regex.find(url)!!.destructured
@ -51,13 +46,12 @@ class WcoProvider : MainAPI() {
returnValue.add(
if (getType(type) == TvType.Movie) {
MovieSearchResponse(
title, href, getSlug(href), this.name, TvType.Movie, img, year
title, href, this.name, TvType.Movie, img, year
)
} else {
AnimeSearchResponse(
title,
href,
getSlug(href),
this.name,
TvType.Anime,
img,
@ -113,13 +107,12 @@ class WcoProvider : MainAPI() {
returnValue.add(
if (getType(type) == TvType.Movie) {
MovieSearchResponse(
title, href, getSlug(href), this.name, TvType.Movie, img, year
title, href, this.name, TvType.Movie, img, year
)
} else {
AnimeSearchResponse(
title,
href,
getSlug(href),
this.name,
TvType.Anime,
img,
@ -136,9 +129,7 @@ class WcoProvider : MainAPI() {
return returnValue
}
override fun load(slug: String): LoadResponse {
val url = "$mainUrl/anime/${slug}"
override fun load(url: String): LoadResponse {
val response = khttp.get(url, timeout = 120.0)
val document = Jsoup.parse(response.text)
@ -174,7 +165,7 @@ class WcoProvider : MainAPI() {
canonicalTitle,
japaneseTitle,
canonicalTitle,
"$mainUrl/anime/${slug}",
url,
this.name,
getType(type ?: ""),
poster,

View File

@ -25,7 +25,7 @@ class HDMProvider : MainAPI() {
val data = i.selectFirst("> div.item")
val img = data.selectFirst("> img").attr("src")
val name = data.selectFirst("> div.movie-details").text()
returnValue.add(MovieSearchResponse(name, href, href, this.name, TvType.Movie, img, null))
returnValue.add(MovieSearchResponse(name, href, this.name, TvType.Movie, img, null))
}
return returnValue
@ -54,8 +54,8 @@ class HDMProvider : MainAPI() {
return true
}
override fun load(slug: String): LoadResponse? {
val response = khttp.get(slug)
override fun load(url: String): LoadResponse? {
val response = khttp.get(url)
val document = Jsoup.parse(response.text)
val title = document.selectFirst("h2.movieTitle").text()
val poster = document.selectFirst("div.post-thumbnail > img").attr("src")
@ -65,7 +65,7 @@ class HDMProvider : MainAPI() {
val data = "src/player/\\?v=(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
return MovieLoadResponse(
title, slug, this.name, TvType.Movie,
title, url, this.name, TvType.Movie,
"$mainUrl/src/player/?v=$data", poster, year, descript, null
)
}

View File

@ -80,7 +80,6 @@ class LookMovieProvider : MainAPI() {
MovieSearchResponse(
m.title,
url,
url,//m.slug,
this.name,
TvType.Movie,
m.poster ?: m.backdrop,
@ -97,7 +96,6 @@ class LookMovieProvider : MainAPI() {
MovieSearchResponse(
s.title,
url,
url,//s.slug,
this.name,
TvType.TvSeries,
s.poster ?: s.backdrop,
@ -129,11 +127,11 @@ class LookMovieProvider : MainAPI() {
returnValue.add(
if (isMovie) {
MovieSearchResponse(
name, href, href, this.name, TvType.Movie, poster, year
name, href, this.name, TvType.Movie, poster, year
)
} else
TvSeriesSearchResponse(
name, href, href, this.name, TvType.TvSeries, poster, year, null
name, href, this.name, TvType.TvSeries, poster, year, null
)
)
}
@ -196,10 +194,10 @@ class LookMovieProvider : MainAPI() {
return true
}
override fun load(slug: String): LoadResponse? {
val response = khttp.get(slug)
override fun load(url: String): LoadResponse? {
val response = khttp.get(url)
val document = Jsoup.parse(response.text)
val isMovie = slug.contains("/movies/")
val isMovie = url.contains("/movies/")
val watchHeader = document.selectFirst("div.watch-heading")
val nameHeader = watchHeader.selectFirst("> h1.bd-hd")
@ -214,7 +212,7 @@ class LookMovieProvider : MainAPI() {
val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex().find(response.text)?.groupValues?.get(1)
?.replace(" ", "")
?: return null
val realSlug = slug.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "")
val realSlug = url.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "")
val realUrl =
"$mainUrl/api/v1/security/${if (isMovie) "movie" else "show"}-access?${if (isMovie) "id_movie=$id" else "slug=$realSlug"}&token=1&sk=&step=1"
@ -228,7 +226,7 @@ class LookMovieProvider : MainAPI() {
)
return MovieLoadResponse(
title,
slug,
url,
this.name,
TvType.Movie,
localData,
@ -280,7 +278,7 @@ class LookMovieProvider : MainAPI() {
return TvSeriesLoadResponse(
title,
slug,
url,
this.name,
TvType.TvSeries,
ArrayList(episodes),

View File

@ -50,7 +50,6 @@ class MeloMovieProvider : MainAPI() {
TvSeriesSearchResponse(
i.title,
currentUrl,
currentUrl,
this.name,
TvType.TvSeries,
currentPoster,
@ -63,7 +62,6 @@ class MeloMovieProvider : MainAPI() {
MovieSearchResponse(
i.title,
currentUrl,
currentUrl,
this.name,
TvType.Movie,
currentUrl,
@ -116,8 +114,8 @@ class MeloMovieProvider : MainAPI() {
return true
}
override fun load(slug: String): LoadResponse? {
val response = khttp.get(slug).text
override fun load(url: String): LoadResponse? {
val response = khttp.get(url).text
//backdrop = imgurl
fun findUsingRegex(src: String): String? {
@ -137,7 +135,7 @@ class MeloMovieProvider : MainAPI() {
val serialize = document.selectFirst("table.accordion__list")
return MovieLoadResponse(
title,
slug,
url,
this.name,
TvType.Movie,
serializeData(serialize),
@ -164,7 +162,7 @@ class MeloMovieProvider : MainAPI() {
episodes.reverse()
return TvSeriesLoadResponse(
title,
slug,
url,
this.name,
TvType.TvSeries,
episodes,

View File

@ -40,7 +40,6 @@ class TrailersToProvider : MainAPI() {
return@mapNotNull if (isMovieType) MovieSearchResponse(
name,
href,
href,
this.name,
TvType.Movie,
posterUrl,
@ -48,7 +47,6 @@ class TrailersToProvider : MainAPI() {
) else TvSeriesSearchResponse(
name,
href,
href,
this.name,
TvType.TvSeries,
posterUrl,
@ -84,9 +82,9 @@ class TrailersToProvider : MainAPI() {
returnValue.add(
if (isTvShow) {
TvSeriesSearchResponse(name, href, href, this.name, TvType.TvSeries, poster, year, null)
TvSeriesSearchResponse(name, href, this.name, TvType.TvSeries, poster, year, null)
} else {
MovieSearchResponse(name, href, href, this.name, TvType.Movie, poster, year)
MovieSearchResponse(name, href, this.name, TvType.Movie, poster, year)
}
)
}
@ -111,9 +109,9 @@ class TrailersToProvider : MainAPI() {
returnValue.add(
if (isTvShow) {
TvSeriesSearchResponse(name, href, href, this.name, TvType.TvSeries, poster, year, null)
TvSeriesSearchResponse(name, href, this.name, TvType.TvSeries, poster, year, null)
} else {
MovieSearchResponse(name, href, href, this.name, TvType.Movie, poster, year)
MovieSearchResponse(name, href, this.name, TvType.Movie, poster, year)
}
)
}

View File

@ -9,12 +9,13 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
class ErrorLoadingException(message: String) : Exception(message)
class APIRepository(val api: MainAPI) {
val name : String get() = api.name
val mainUrl : String get() = api.mainUrl
val name: String get() = api.name
val mainUrl: String get() = api.mainUrl
suspend fun load(url: String): Resource<LoadResponse> {
return safeApiCall {
api.load(url) ?: throw ErrorLoadingException("Error Loading")
// remove suffix for some slugs to handle correctly
api.load(url.removeSuffix("/")) ?: throw ErrorLoadingException("Error Loading")
}
}

View File

@ -143,11 +143,10 @@ fun ResultEpisode.getWatchProgress(): Float {
class ResultFragment : Fragment() {
companion object {
fun newInstance(url: String, slug: String, apiName: String, startAction: Int = 0) =
fun newInstance(url: String, apiName: String, startAction: Int = 0) =
ResultFragment().apply {
arguments = Bundle().apply {
putString("url", url)
putString("slug", slug)
putString("apiName", apiName)
putInt("startAction", startAction)
}
@ -257,7 +256,6 @@ class ResultFragment : Fragment() {
// activity?.fixPaddingStatusbar(result_toolbar)
url = arguments?.getString("url")
val slug = arguments?.getString("slug")
val apiName = arguments?.getString("apiName") ?: return
startAction = arguments?.getInt("startAction") ?: START_ACTION_NORMAL
@ -431,7 +429,6 @@ class ResultFragment : Fragment() {
VideoDownloadHelper.DownloadHeaderCached(
apiName,
url ?: return@let,
slug ?: return@let,
currentType ?: return@let,
currentHeaderName ?: return@let,
currentPoster ?: return@let,
@ -986,21 +983,20 @@ class ResultFragment : Fragment() {
}
}
if (apiName != null && slug != null) {
val tempUrl = url
if (tempUrl != null) {
result_reload_connectionerror.setOnClickListener {
viewModel.load(requireContext(), slug, apiName)
viewModel.load(requireContext(), tempUrl, apiName)
}
if (url != null) {
result_reload_connection_open_in_browser.setOnClickListener {
val i = Intent(ACTION_VIEW)
i.data = Uri.parse(url)
startActivity(i)
}
result_reload_connection_open_in_browser.setOnClickListener {
val i = Intent(ACTION_VIEW)
i.data = Uri.parse(tempUrl)
startActivity(i)
}
if (viewModel.resultResponse.value == null)
viewModel.load(requireContext(), slug, apiName)
viewModel.load(requireContext(), tempUrl, apiName)
}
}
}

View File

@ -9,9 +9,11 @@ import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultSeason
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.DataStoreHelper.setBookmarkedData
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultSeason
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
import com.lagradost.cloudstream3.utils.ExtractorLink
@ -21,7 +23,7 @@ const val EPISODE_RANGE_SIZE = 50
const val EPISODE_RANGE_OVERLOAD = 60
class ResultViewModel : ViewModel() {
var repo : APIRepository? = null
var repo: APIRepository? = null
private val _resultResponse: MutableLiveData<Resource<Any?>> = MutableLiveData()
private val _episodes: MutableLiveData<List<ResultEpisode>> = MutableLiveData()
@ -51,6 +53,21 @@ class ResultViewModel : ViewModel() {
val currentId = id.value ?: return
_watchStatus.postValue(status)
context.setResultWatchState(currentId, status.internalId)
val resultPage = page.value
if (resultPage != null) {
context.setBookmarkedData(
currentId,
DataStoreHelper.BookmarkedData(
currentId,
resultPage.name,
resultPage.url,
resultPage.apiName,
resultPage.type,
resultPage.posterUrl,
resultPage.year
)
)
}
}
private fun loadWatchStatus(context: Context, localId: Int? = null) {
@ -154,80 +171,78 @@ class ResultViewModel : ViewModel() {
when (data) {
is Resource.Success -> {
val d = data.value
if (d is LoadResponse) {
page.postValue(d)
val mainId = d.getId()
id.postValue(mainId)
loadWatchStatus(context, mainId)
page.postValue(d)
val mainId = d.getId()
id.postValue(mainId)
loadWatchStatus(context, mainId)
when (d) {
is AnimeLoadResponse -> {
val isDub = d.dubEpisodes != null && d.dubEpisodes.size > 0
dubStatus.postValue(if (isDub) DubStatus.Dubbed else DubStatus.Subbed)
when (d) {
is AnimeLoadResponse -> {
val isDub = d.dubEpisodes != null && d.dubEpisodes.size > 0
dubStatus.postValue(if (isDub) DubStatus.Dubbed else DubStatus.Subbed)
val dataList = (if (isDub) d.dubEpisodes else d.subEpisodes)
val dataList = (if (isDub) d.dubEpisodes else d.subEpisodes)
if (dataList != null) {
val episodes = ArrayList<ResultEpisode>()
for ((index, i) in dataList.withIndex()) {
episodes.add(
context.buildResultEpisode(
i.name,
i.posterUrl,
index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE
null, // TODO FIX SEASON
i.url,
apiName,
(mainId + index + 1),
index,
i.rating,
i.descript,
)
)
}
updateEpisodes(context, mainId, episodes, -1)
}
}
is TvSeriesLoadResponse -> {
if (dataList != null) {
val episodes = ArrayList<ResultEpisode>()
for ((index, i) in d.episodes.withIndex()) {
for ((index, i) in dataList.withIndex()) {
episodes.add(
context.buildResultEpisode(
i.name,
//?: (if (i.season != null && i.episode != null) "S${i.season}:E${i.episode}" else null)), // TODO ADD NAMES
i.posterUrl,
i.episode ?: (index + 1),
i.season,
i.data,
index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE
null, // TODO FIX SEASON
i.url,
apiName,
(mainId + index + 1).hashCode(),
(mainId + index + 1),
index,
i.rating,
i.descript
i.descript,
)
)
}
updateEpisodes(context, mainId, episodes, -1)
}
is MovieLoadResponse -> {
updateEpisodes(
context, mainId, arrayListOf(
context.buildResultEpisode(
d.name,
null,
0,
null,
d.dataUrl,
d.apiName,
(mainId), // HAS SAME ID
0,
null,
null,
)
), -1
}
is TvSeriesLoadResponse -> {
val episodes = ArrayList<ResultEpisode>()
for ((index, i) in d.episodes.withIndex()) {
episodes.add(
context.buildResultEpisode(
i.name,
//?: (if (i.season != null && i.episode != null) "S${i.season}:E${i.episode}" else null)), // TODO ADD NAMES
i.posterUrl,
i.episode ?: (index + 1),
i.season,
i.data,
apiName,
(mainId + index + 1).hashCode(),
index,
i.rating,
i.descript
)
)
}
updateEpisodes(context, mainId, episodes, -1)
}
is MovieLoadResponse -> {
updateEpisodes(
context, mainId, arrayListOf(
context.buildResultEpisode(
d.name,
null,
0,
null,
d.dataUrl,
d.apiName,
(mainId), // HAS SAME ID
0,
null,
null,
)
), -1
)
}
}
}
@ -303,8 +318,4 @@ class ResultViewModel : ViewModel() {
val localData = loadEpisode(id, data, isCasting)
callback.invoke(localData)
}
fun loadIndex(index: Int): ResultEpisode? {
return episodes.value?.get(index)
}
}

View File

@ -142,7 +142,7 @@ class SearchFragment : Fragment() {
search_loading_bar.alpha = 0f
}
is Resource.Failure -> {
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
// Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
searchExitIcon.alpha = 1f
search_loading_bar.alpha = 0f
}

View File

@ -43,18 +43,18 @@ object AppUtils {
}
}
fun AppCompatActivity.loadResult(url: String, slug: String, apiName: String, startAction: Int = 0) {
fun AppCompatActivity.loadResult(url: String, apiName: String, startAction: Int = 0) {
this.runOnUiThread {
viewModelStore.clear()
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, slug, apiName, startAction))
.add(R.id.homeRoot, ResultFragment.newInstance(url, apiName, startAction))
.commit()
}
}
fun Activity?.loadSearchResult(card: SearchResponse, startAction: Int = 0) {
(this as AppCompatActivity?)?.loadResult(card.url, card.slug, card.apiName, startAction)
(this as AppCompatActivity?)?.loadResult(card.url, card.apiName, startAction)
}
fun Activity.requestLocalAudioFocus(focusRequest: AudioFocusRequest?) {

View File

@ -1,17 +1,21 @@
package com.lagradost.cloudstream3.utils
import android.content.Context
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey
const val VIDEO_POS_DUR = "video_pos_dur"
const val RESULT_WATCH_STATE = "result_watch_state"
const val RESULT_WATCH_STATE_DATA = "result_watch_state_data"
const val RESULT_SEASON = "result_season"
object DataStoreHelper {
data class PosDur(val position: Long, val duration: Long)
fun PosDur.fixVisual(): PosDur {
if (duration <= 0) return PosDur(0, duration)
val percentage = position * 100 / duration
@ -21,8 +25,28 @@ object DataStoreHelper {
return this
}
data class BookmarkedData(
val parentId: Int,
override val name: String,
override val url: String,
override val apiName: String,
override val type: TvType,
override val posterUrl: String?,
override val year: Int?,
) : SearchResponse
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
fun Context.setBookmarkedData(id: Int?, data: BookmarkedData) {
if (id == null) return
setKey("$currentAccount/$RESULT_WATCH_STATE", id.toString(), data)
}
fun Context.getBookmarkedData(id: Int?): BookmarkedData? {
if (id == null) return null
return getKey("$currentAccount/$RESULT_WATCH_STATE", id.toString())
}
fun Context.setViewPos(id: Int?, pos: Long, dur: Long) {
if (id == null) return
setKey("$currentAccount/$VIDEO_POS_DUR", id.toString(), PosDur(pos, dur))
@ -44,7 +68,8 @@ object DataStoreHelper {
fun Context.getResultSeason(id: Int): Int {
return getKey("$currentAccount/$RESULT_SEASON", id.toString(), -1)!!
}
fun Context.setResultSeason(id: Int, value : Int?) {
fun Context.setResultSeason(id: Int, value: Int?) {
return setKey("$currentAccount/$RESULT_SEASON", id.toString(), value)
}
}

View File

@ -2,7 +2,6 @@ package com.lagradost.cloudstream3.utils
import com.lagradost.cloudstream3.extractors.*
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.utils.extractors.*
data class ExtractorLink(
val source: String,

View File

@ -17,7 +17,6 @@ object VideoDownloadHelper {
data class DownloadHeaderCached(
val apiName: String,
val url: String,
val slug : String,
val type : TvType,
val name: String,
val poster: String?,

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
</vector>

View File

@ -87,6 +87,7 @@
android:id="@+id/home_loaded"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
@ -202,6 +203,57 @@
</ImageView>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/home_bookmarked_holder"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:id="@+id/home_bookmarked_child_more_info"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="@drawable/ic_baseline_filter_list_24"
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/filter_bookmarks">
</ImageView>
<TextView
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:id="@+id/home_bookmarked_parent_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/textColor"
android:gravity="center_vertical"
android:textSize="18sp"
android:textStyle="bold"
android:text="Bookmarked"
/>
<ImageView
android:layout_marginEnd="5dp"
android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_width="30dp"
android:layout_height="match_parent"
android:contentDescription="@string/home_more_info">
</ImageView>
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_bookmarked_child_recyclerview"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid"
/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_master_recycler"
android:layout_width="match_parent"
@ -210,5 +262,4 @@
/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</FrameLayout>

View File

@ -108,6 +108,7 @@
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:visibility="gone"
android:alpha="0"
android:layout_width="match_parent"
android:id="@+id/result_poster_blur_holder"
@ -120,10 +121,13 @@
tools:src="@drawable/example_poster"
android:background="@color/darkBackground"
android:id="@+id/result_poster_blur"
android:contentDescription=""/>
<ImageView android:src="@drawable/background_shadow" android:layout_gravity="bottom"
android:layout_width="match_parent" android:layout_height="30dp">
android:contentDescription="@string/background_blur"/>
<ImageView
android:src="@drawable/background_shadow"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="30dp"
android:contentDescription="@string/background_shadow">
</ImageView>
</FrameLayout>
<androidx.core.widget.NestedScrollView
@ -163,13 +167,13 @@
<LinearLayout
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:gravity="center_vertical"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_marginRight="50dp"
android:layout_marginEnd="50dp"
tools:text="The Perfect Run The Perfect Run The Perfect Run"
android:id="@+id/result_title"
android:textSize="20sp"
@ -201,7 +205,6 @@
android:layout_width="match_parent"
android:layout_height="50dp">
<com.google.android.material.button.MaterialButton
android:visibility="gone"
android:layout_gravity="center_vertical"
app:cornerRadius="4dp"
android:id="@+id/result_bookmark_button"

View File

@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
@ -36,7 +36,7 @@
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/home_child_recyclerview"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/home_result_grid"
/>

View File

@ -61,4 +61,7 @@
<string name="home_info">Info</string>
<string name="home_next_random">Next Random</string>
<string name="home_change_provider">Change Provider</string>
<string name="background_blur">Background blur</string>
<string name="background_shadow">Background Shadow</string>
<string name="filter_bookmarks">Filter Bookmarks</string>
</resources>