forked from recloudstream/cloudstream
scroll
This commit is contained in:
parent
47b79550f1
commit
d349190238
29 changed files with 337 additions and 179 deletions
|
@ -180,7 +180,7 @@ class ExampleInstrumentedTest {
|
||||||
@Test
|
@Test
|
||||||
fun providerCorrectHomepage() {
|
fun providerCorrectHomepage() {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
getAllProviders().apmap { api ->
|
getAllProviders().amap { api ->
|
||||||
if (api.hasMainPage) {
|
if (api.hasMainPage) {
|
||||||
try {
|
try {
|
||||||
val homepage = api.getMainPage()
|
val homepage = api.getMainPage()
|
||||||
|
@ -217,7 +217,7 @@ class ExampleInstrumentedTest {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
||||||
val providers = getAllProviders()
|
val providers = getAllProviders()
|
||||||
providers.apmap { api ->
|
providers.amap { api ->
|
||||||
try {
|
try {
|
||||||
println("Trying $api")
|
println("Trying $api")
|
||||||
if (testSingleProviderApi(api)) {
|
if (testSingleProviderApi(api)) {
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ interface LoadResponse {
|
||||||
) {
|
) {
|
||||||
if (!isTrailersEnabled || trailerUrls == null) return
|
if (!isTrailersEnabled || trailerUrls == null) return
|
||||||
trailers.addAll(trailerUrls.map { TrailerData(it, referer, addRaw) })
|
trailers.addAll(trailerUrls.map { TrailerData(it, referer, addRaw) })
|
||||||
/*val trailers = trailerUrls.filter { it.isNotBlank() }.apmap { trailerUrl ->
|
/*val trailers = trailerUrls.filter { it.isNotBlank() }.amap { trailerUrl ->
|
||||||
val links = arrayListOf<ExtractorLink>()
|
val links = arrayListOf<ExtractorLink>()
|
||||||
val subs = arrayListOf<SubtitleFile>()
|
val subs = arrayListOf<SubtitleFile>()
|
||||||
if (!loadExtractor(
|
if (!loadExtractor(
|
||||||
|
|
|
@ -592,7 +592,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
api.init()
|
api.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
inAppAuths.apmap { api ->
|
inAppAuths.amap { api ->
|
||||||
try {
|
try {
|
||||||
api.initialize()
|
api.initialize()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.lagradost.cloudstream3
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
|
|
||||||
//https://stackoverflow.com/questions/34697828/parallel-operations-on-kotlin-collections
|
//https://stackoverflow.com/questions/34697828/parallel-operations-on-kotlin-collections
|
||||||
/*
|
/*
|
||||||
|
@ -26,10 +25,25 @@ fun <T, R> Iterable<T>.pmap(
|
||||||
return ArrayList<R>(destination)
|
return ArrayList<R>(destination)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
suspend fun <K, V, R> Map<out K, V>.amap(f: suspend (Map.Entry<K, V>) -> R): List<R> =
|
||||||
|
with(CoroutineScope(GlobalScope.coroutineContext)) {
|
||||||
|
map { async { f(it) } }.map { it.await() }
|
||||||
|
}
|
||||||
|
|
||||||
fun <K, V, R> Map<out K, V>.apmap(f: suspend (Map.Entry<K, V>) -> R): List<R> = runBlocking {
|
fun <K, V, R> Map<out K, V>.apmap(f: suspend (Map.Entry<K, V>) -> R): List<R> = runBlocking {
|
||||||
map { async { f(it) } }.map { it.await() }
|
map { async { f(it) } }.map { it.await() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
suspend fun <A, B> List<A>.amap(f: suspend (A) -> B): List<B> =
|
||||||
|
with(CoroutineScope(GlobalScope.coroutineContext)) {
|
||||||
|
map { async { f(it) } }.map { it.await() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun <A, B> List<A>.apmap(f: suspend (A) -> B): List<B> = runBlocking {
|
fun <A, B> List<A>.apmap(f: suspend (A) -> B): List<B> = runBlocking {
|
||||||
map { async { f(it) } }.map { it.await() }
|
map { async { f(it) } }.map { it.await() }
|
||||||
}
|
}
|
||||||
|
@ -38,6 +52,12 @@ fun <A, B> List<A>.apmapIndexed(f: suspend (index: Int, A) -> B): List<B> = runB
|
||||||
mapIndexed { index, a -> async { f(index, a) } }.map { it.await() }
|
mapIndexed { index, a -> async { f(index, a) } }.map { it.await() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
suspend fun <A, B> List<A>.amapIndexed(f: suspend (index: Int, A) -> B): List<B> =
|
||||||
|
with(CoroutineScope(GlobalScope.coroutineContext)) {
|
||||||
|
mapIndexed { index, a -> async { f(index, a) } }.map { it.await() }
|
||||||
|
}
|
||||||
|
|
||||||
// run code in parallel
|
// run code in parallel
|
||||||
/*fun <R> argpmap(
|
/*fun <R> argpmap(
|
||||||
vararg transforms: () -> R,
|
vararg transforms: () -> R,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
@ -21,10 +21,10 @@ class Fastream: ExtractorApi() {
|
||||||
Pair("file_code",id),
|
Pair("file_code",id),
|
||||||
Pair("auto","1")
|
Pair("auto","1")
|
||||||
)).document
|
)).document
|
||||||
response.select("script").apmap { script ->
|
response.select("script").amap { script ->
|
||||||
if (script.data().contains("sources")) {
|
if (script.data().contains("sources")) {
|
||||||
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
||||||
val m3u8 = m3u8regex.find(script.data())?.value ?: return@apmap
|
val m3u8 = m3u8regex.find(script.data())?.value ?: return@amap
|
||||||
generateM3u8(
|
generateM3u8(
|
||||||
name,
|
name,
|
||||||
m3u8,
|
m3u8,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
@ -35,7 +35,7 @@ class Pelisplus(val mainUrl: String) {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
try {
|
try {
|
||||||
normalApis.apmap { api ->
|
normalApis.amap { api ->
|
||||||
val url = api.getExtractorUrl(id)
|
val url = api.getExtractorUrl(id)
|
||||||
api.getSafeUrl(url, subtitleCallback = subtitleCallback, callback = callback)
|
api.getSafeUrl(url, subtitleCallback = subtitleCallback, callback = callback)
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ class Pelisplus(val mainUrl: String) {
|
||||||
val qualityRegex = Regex("(\\d+)P")
|
val qualityRegex = Regex("(\\d+)P")
|
||||||
|
|
||||||
//a[download]
|
//a[download]
|
||||||
pageDoc.select(".dowload > a")?.apmap { element ->
|
pageDoc.select(".dowload > a")?.amap { element ->
|
||||||
val href = element.attr("href") ?: return@apmap
|
val href = element.attr("href") ?: return@amap
|
||||||
val qual = if (element.text()
|
val qual = if (element.text()
|
||||||
.contains("HDP")
|
.contains("HDP")
|
||||||
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
||||||
|
@ -84,7 +84,7 @@ class Pelisplus(val mainUrl: String) {
|
||||||
//val name = element.text()
|
//val name = element.text()
|
||||||
|
|
||||||
// Matches vidstream links with extractors
|
// Matches vidstream links with extractors
|
||||||
extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api ->
|
extractorApis.filter { !it.requiresReferer || !isCasting }.amap { api ->
|
||||||
if (link.startsWith(api.mainUrl)) {
|
if (link.startsWith(api.mainUrl)) {
|
||||||
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -69,12 +69,12 @@ open class VidSrcExtractor : ExtractorApi() {
|
||||||
} else ""
|
} else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
serverslist.apmap { server ->
|
serverslist.amap { server ->
|
||||||
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
|
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
|
||||||
if (linkfixed.contains("/pro")) {
|
if (linkfixed.contains("/pro")) {
|
||||||
val srcresponse = app.get(server, referer = absoluteUrl).text
|
val srcresponse = app.get(server, referer = absoluteUrl).text
|
||||||
val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)")
|
val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)")
|
||||||
val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@apmap
|
val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@amap
|
||||||
val passRegex = Regex("""['"](.*set_pass[^"']*)""")
|
val passRegex = Regex("""['"](.*set_pass[^"']*)""")
|
||||||
val pass = passRegex.find(srcresponse)?.groupValues?.get(1)?.replace(
|
val pass = passRegex.find(srcresponse)?.groupValues?.get(1)?.replace(
|
||||||
Regex("""^//"""), "https://"
|
Regex("""^//"""), "https://"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.argamap
|
import com.lagradost.cloudstream3.argamap
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
@ -37,7 +37,7 @@ class Vidstream(val mainUrl: String) {
|
||||||
val extractorUrl = getExtractorUrl(id)
|
val extractorUrl = getExtractorUrl(id)
|
||||||
argamap(
|
argamap(
|
||||||
{
|
{
|
||||||
normalApis.apmap { api ->
|
normalApis.amap { api ->
|
||||||
val url = api.getExtractorUrl(id)
|
val url = api.getExtractorUrl(id)
|
||||||
api.getSafeUrl(
|
api.getSafeUrl(
|
||||||
url,
|
url,
|
||||||
|
@ -55,8 +55,8 @@ class Vidstream(val mainUrl: String) {
|
||||||
val qualityRegex = Regex("(\\d+)P")
|
val qualityRegex = Regex("(\\d+)P")
|
||||||
|
|
||||||
//a[download]
|
//a[download]
|
||||||
pageDoc.select(".dowload > a")?.apmap { element ->
|
pageDoc.select(".dowload > a")?.amap { element ->
|
||||||
val href = element.attr("href") ?: return@apmap
|
val href = element.attr("href") ?: return@amap
|
||||||
val qual = if (element.text()
|
val qual = if (element.text()
|
||||||
.contains("HDP")
|
.contains("HDP")
|
||||||
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
||||||
|
@ -87,7 +87,7 @@ class Vidstream(val mainUrl: String) {
|
||||||
//val name = element.text()
|
//val name = element.text()
|
||||||
|
|
||||||
// Matches vidstream links with extractors
|
// Matches vidstream links with extractors
|
||||||
extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api ->
|
extractorApis.filter { !it.requiresReferer || !isCasting }.amap { api ->
|
||||||
if (link.startsWith(api.mainUrl)) {
|
if (link.startsWith(api.mainUrl)) {
|
||||||
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
@ -36,7 +36,7 @@ open class ZplayerV2 : ExtractorApi() {
|
||||||
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
||||||
m3u8regex.findAll(testdata).map {
|
m3u8regex.findAll(testdata).map {
|
||||||
it.value
|
it.value
|
||||||
}.toList().apmap { urlm3u8 ->
|
}.toList().amap { urlm3u8 ->
|
||||||
if (urlm3u8.contains("m3u8")) {
|
if (urlm3u8.contains("m3u8")) {
|
||||||
val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text
|
val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text
|
||||||
if (testurl.contains("EXTM3U")) {
|
if (testurl.contains("EXTM3U")) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.extractors.helper
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
@ -18,7 +18,7 @@ class AsianEmbedHelper {
|
||||||
val doc = app.get(url).document
|
val doc = app.get(url).document
|
||||||
val links = doc.select("div#list-server-more > ul > li.linkserver")
|
val links = doc.select("div#list-server-more > ul > li.linkserver")
|
||||||
if (!links.isNullOrEmpty()) {
|
if (!links.isNullOrEmpty()) {
|
||||||
links.apmap {
|
links.amap {
|
||||||
val datavid = it.attr("data-video") ?: ""
|
val datavid = it.attr("data-video") ?: ""
|
||||||
//Log.i("AsianEmbed", "Result => (datavid) ${datavid}")
|
//Log.i("AsianEmbed", "Result => (datavid) ${datavid}")
|
||||||
if (datavid.isNotBlank()) {
|
if (datavid.isNotBlank()) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ class CrossTmdbProvider : TmdbProvider() {
|
||||||
): Boolean {
|
): Boolean {
|
||||||
tryParseJson<CrossMetaData>(data)?.let { metaData ->
|
tryParseJson<CrossMetaData>(data)?.let { metaData ->
|
||||||
if (!metaData.isSuccess) return false
|
if (!metaData.isSuccess) return false
|
||||||
metaData.movies?.apmap { (apiName, data) ->
|
metaData.movies?.amap { (apiName, data) ->
|
||||||
getApiFromNameNull(apiName)?.let {
|
getApiFromNameNull(apiName)?.let {
|
||||||
try {
|
try {
|
||||||
it.loadLinks(data, isCasting, subtitleCallback, callback)
|
it.loadLinks(data, isCasting, subtitleCallback, callback)
|
||||||
|
@ -64,10 +64,10 @@ class CrossTmdbProvider : TmdbProvider() {
|
||||||
val matchName = filterName(this.name)
|
val matchName = filterName(this.name)
|
||||||
when (this) {
|
when (this) {
|
||||||
is MovieLoadResponse -> {
|
is MovieLoadResponse -> {
|
||||||
val data = validApis.apmap { api ->
|
val data = validApis.amap { api ->
|
||||||
try {
|
try {
|
||||||
if (api.supportedTypes.contains(TvType.Movie)) { //|| api.supportedTypes.contains(TvType.AnimeMovie)
|
if (api.supportedTypes.contains(TvType.Movie)) { //|| api.supportedTypes.contains(TvType.AnimeMovie)
|
||||||
return@apmap api.search(this.name)?.first {
|
return@amap api.search(this.name)?.first {
|
||||||
if (filterName(it.name).equals(
|
if (filterName(it.name).equals(
|
||||||
matchName,
|
matchName,
|
||||||
ignoreCase = true
|
ignoreCase = true
|
||||||
|
|
|
@ -45,7 +45,7 @@ class MultiAnimeProvider : MainAPI() {
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse? {
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
return syncApi.getResult(url)?.let { res ->
|
return syncApi.getResult(url)?.let { res ->
|
||||||
val data = SyncUtil.getUrlsFromId(res.id, syncUtilType).apmap { url ->
|
val data = SyncUtil.getUrlsFromId(res.id, syncUtilType).amap { url ->
|
||||||
validApis.firstOrNull { api -> url.startsWith(api.mainUrl) }?.load(url)
|
validApis.firstOrNull { api -> url.startsWith(api.mainUrl) }?.load(url)
|
||||||
}.filterNotNull()
|
}.filterNotNull()
|
||||||
|
|
||||||
|
|
|
@ -217,18 +217,17 @@ object PluginManager {
|
||||||
* 3. If outdated download and load the plugin
|
* 3. If outdated download and load the plugin
|
||||||
* 4. Else load the plugin normally
|
* 4. Else load the plugin normally
|
||||||
**/
|
**/
|
||||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) {
|
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) = ioSafe {
|
||||||
// Load all plugins as fast as possible!
|
// Load all plugins as fast as possible!
|
||||||
loadAllOnlinePlugins(activity)
|
loadAllOnlinePlugins(activity)
|
||||||
|
|
||||||
ioSafe {
|
|
||||||
afterPluginsLoadedEvent.invoke(true)
|
afterPluginsLoadedEvent.invoke(true)
|
||||||
}
|
|
||||||
|
|
||||||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||||
?: emptyArray()) + PREBUILT_REPOSITORIES
|
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||||
|
|
||||||
val onlinePlugins = urls.toList().apmap {
|
val onlinePlugins = urls.toList().amap {
|
||||||
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||||
}.flatten().distinctBy { it.second.url }
|
}.flatten().distinctBy { it.second.url }
|
||||||
|
|
||||||
|
@ -249,7 +248,7 @@ object PluginManager {
|
||||||
|
|
||||||
val updatedPlugins = mutableListOf<String>()
|
val updatedPlugins = mutableListOf<String>()
|
||||||
|
|
||||||
outdatedPlugins.apmap { pluginData ->
|
outdatedPlugins.amap { pluginData ->
|
||||||
if (pluginData.isDisabled) {
|
if (pluginData.isDisabled) {
|
||||||
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
||||||
unloadPlugin(pluginData.savedData.filePath)
|
unloadPlugin(pluginData.savedData.filePath)
|
||||||
|
@ -270,9 +269,9 @@ object PluginManager {
|
||||||
createNotification(activity, updatedPlugins)
|
createNotification(activity, updatedPlugins)
|
||||||
}
|
}
|
||||||
|
|
||||||
ioSafe {
|
// ioSafe {
|
||||||
afterPluginsLoadedEvent.invoke(true)
|
afterPluginsLoadedEvent.invoke(true)
|
||||||
}
|
// }
|
||||||
|
|
||||||
Log.i(TAG, "Plugin update done!")
|
Log.i(TAG, "Plugin update done!")
|
||||||
}
|
}
|
||||||
|
@ -280,9 +279,9 @@ object PluginManager {
|
||||||
/**
|
/**
|
||||||
* Use updateAllOnlinePluginsAndLoadThem
|
* Use updateAllOnlinePluginsAndLoadThem
|
||||||
* */
|
* */
|
||||||
fun loadAllOnlinePlugins(activity: Activity) {
|
fun loadAllOnlinePlugins(activity: Activity) = ioSafe {
|
||||||
// Load all plugins as fast as possible!
|
// Load all plugins as fast as possible!
|
||||||
(getPluginsOnline()).toList().apmap { pluginData ->
|
(getPluginsOnline()).toList().amap { pluginData ->
|
||||||
loadPlugin(
|
loadPlugin(
|
||||||
activity,
|
activity,
|
||||||
File(pluginData.filePath),
|
File(pluginData.filePath),
|
||||||
|
@ -291,7 +290,7 @@ object PluginManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadAllLocalPlugins(activity: Activity) {
|
fun loadAllLocalPlugins(activity: Activity) = ioSafe {
|
||||||
val dir = File(LOCAL_PLUGINS_PATH)
|
val dir = File(LOCAL_PLUGINS_PATH)
|
||||||
removeKey(PLUGINS_KEY_LOCAL)
|
removeKey(PLUGINS_KEY_LOCAL)
|
||||||
|
|
||||||
|
@ -299,7 +298,7 @@ object PluginManager {
|
||||||
val res = dir.mkdirs()
|
val res = dir.mkdirs()
|
||||||
if (!res) {
|
if (!res) {
|
||||||
Log.w(TAG, "Failed to create local directories")
|
Log.w(TAG, "Failed to create local directories")
|
||||||
return
|
return@ioSafe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||||
|
@ -95,7 +95,7 @@ object RepositoryManager {
|
||||||
* */
|
* */
|
||||||
suspend fun getRepoPlugins(repositoryUrl: String): List<Pair<String, SitePlugin>>? {
|
suspend fun getRepoPlugins(repositoryUrl: String): List<Pair<String, SitePlugin>>? {
|
||||||
val repo = parseRepository(repositoryUrl) ?: return null
|
val repo = parseRepository(repositoryUrl) ?: return null
|
||||||
return repo.pluginLists.apmap { url ->
|
return repo.pluginLists.amap { url ->
|
||||||
parsePlugins(url).map {
|
parsePlugins(url).map {
|
||||||
repositoryUrl to it
|
repositoryUrl to it
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
|
import kotlinx.coroutines.GlobalScope.coroutineContext
|
||||||
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
class APIRepository(val api: MainAPI) {
|
class APIRepository(val api: MainAPI) {
|
||||||
|
@ -27,7 +31,7 @@ class APIRepository(val api: MainAPI) {
|
||||||
return data.isEmpty() || data == "[]" || data == "about:blank"
|
return data.isEmpty() || data == "[]" || data == "about:blank"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val cacheHash: HashMap<Pair<String,String>, LoadResponse> = hashMapOf()
|
private val cacheHash: HashMap<Pair<String, String>, LoadResponse> = hashMapOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val hasMainPage = api.hasMainPage
|
val hasMainPage = api.hasMainPage
|
||||||
|
@ -42,7 +46,7 @@ class APIRepository(val api: MainAPI) {
|
||||||
return safeApiCall {
|
return safeApiCall {
|
||||||
if (isInvalidData(url)) throw ErrorLoadingException()
|
if (isInvalidData(url)) throw ErrorLoadingException()
|
||||||
val fixedUrl = api.fixUrl(url)
|
val fixedUrl = api.fixUrl(url)
|
||||||
val key = Pair(api.name,url)
|
val key = Pair(api.name, url)
|
||||||
cacheHash[key] ?: api.load(fixedUrl)?.also {
|
cacheHash[key] ?: api.load(fixedUrl)?.also {
|
||||||
// we cache 20 responses because ppl often go back to the same shit + 20 because I dont want to cause too much memory leak
|
// we cache 20 responses because ppl often go back to the same shit + 20 because I dont want to cause too much memory leak
|
||||||
if (cacheHash.size > 20) cacheHash.remove(cacheHash.keys.random())
|
if (cacheHash.size > 20) cacheHash.remove(cacheHash.keys.random())
|
||||||
|
@ -78,6 +82,7 @@ class APIRepository(val api: MainAPI) {
|
||||||
delay(delta)
|
delay(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
suspend fun getMainPage(page: Int, nameIndex: Int? = null): Resource<List<HomePageResponse?>> {
|
suspend fun getMainPage(page: Int, nameIndex: Int? = null): Resource<List<HomePageResponse?>> {
|
||||||
return safeApiCall {
|
return safeApiCall {
|
||||||
api.lastHomepageRequest = unixTimeMS
|
api.lastHomepageRequest = unixTimeMS
|
||||||
|
@ -103,12 +108,16 @@ class APIRepository(val api: MainAPI) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
api.mainPage.apmap { data ->
|
with(CoroutineScope(coroutineContext)) {
|
||||||
|
api.mainPage.map { data ->
|
||||||
|
async {
|
||||||
api.getMainPage(
|
api.getMainPage(
|
||||||
page,
|
page,
|
||||||
MainPageRequest(data.name, data.data, data.horizontalImages)
|
MainPageRequest(data.name, data.data, data.horizontalImages)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}.map { it.await() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,51 +547,14 @@ class HomeFragment : Fragment() {
|
||||||
when (preview) {
|
when (preview) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
home_preview?.isVisible = true
|
home_preview?.isVisible = true
|
||||||
|
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
|
||||||
|
setItems(preview.value)
|
||||||
|
// home_preview_viewpager?.setCurrentItem(1000, false)
|
||||||
|
}
|
||||||
|
|
||||||
preview.value.apply {
|
//.also {
|
||||||
home_preview_tags?.text = tags?.joinToString(" • ") ?: ""
|
//home_preview_viewpager?.adapter =
|
||||||
home_preview_tags?.isGone = tags.isNullOrEmpty()
|
//}
|
||||||
home_preview_image?.setImage(posterUrl, posterHeaders)
|
|
||||||
home_preview_title?.text = name
|
|
||||||
home_preview_play?.setOnClickListener {
|
|
||||||
activity?.loadResult(url, apiName, START_ACTION_RESUME_LATEST)
|
|
||||||
//activity.loadSearchResult(url, START_ACTION_RESUME_LATEST)
|
|
||||||
}
|
|
||||||
home_preview_info?.setOnClickListener {
|
|
||||||
activity?.loadResult(url, apiName)
|
|
||||||
//activity.loadSearchResult(random)
|
|
||||||
}
|
|
||||||
// very ugly code, but I dont care
|
|
||||||
val watchType = DataStoreHelper.getResultWatchState(preview.value.getId())
|
|
||||||
home_preview_bookmark?.setText(watchType.stringRes)
|
|
||||||
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
null,
|
|
||||||
getDrawable(home_preview_bookmark.context, watchType.iconRes),
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
home_preview_bookmark?.setOnClickListener { fab ->
|
|
||||||
activity?.showBottomDialog(
|
|
||||||
WatchType.values().map { fab.context.getString(it.stringRes) }
|
|
||||||
.toList(),
|
|
||||||
DataStoreHelper.getResultWatchState(preview.value.getId()).ordinal,
|
|
||||||
fab.context.getString(R.string.action_add_to_bookmarks),
|
|
||||||
showApply = false,
|
|
||||||
{}) {
|
|
||||||
val newValue = WatchType.values()[it]
|
|
||||||
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
null,
|
|
||||||
getDrawable(home_preview_bookmark.context, newValue.iconRes),
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
home_preview_bookmark?.setText(newValue.stringRes)
|
|
||||||
|
|
||||||
updateWatchStatus(preview.value, newValue)
|
|
||||||
reloadStored()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
home_preview?.isVisible = false
|
home_preview?.isVisible = false
|
||||||
|
@ -606,6 +569,58 @@ class HomeFragment : Fragment() {
|
||||||
searchText.setTextColor(color)
|
searchText.setTextColor(color)
|
||||||
searchText.setHintTextColor(color)
|
searchText.setHintTextColor(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
home_preview_viewpager?.apply {
|
||||||
|
setPageTransformer(false, HomeScrollTransformer())
|
||||||
|
adapter = HomeScrollAdapter { load ->
|
||||||
|
load.apply {
|
||||||
|
home_preview_tags?.text = tags?.joinToString(" • ") ?: ""
|
||||||
|
home_preview_tags?.isGone = tags.isNullOrEmpty()
|
||||||
|
home_preview_image?.setImage(posterUrl, posterHeaders)
|
||||||
|
home_preview_title?.text = name
|
||||||
|
home_preview_play?.setOnClickListener {
|
||||||
|
activity?.loadResult(url, apiName, START_ACTION_RESUME_LATEST)
|
||||||
|
//activity.loadSearchResult(url, START_ACTION_RESUME_LATEST)
|
||||||
|
}
|
||||||
|
home_preview_info?.setOnClickListener {
|
||||||
|
activity?.loadResult(url, apiName)
|
||||||
|
//activity.loadSearchResult(random)
|
||||||
|
}
|
||||||
|
// very ugly code, but I dont care
|
||||||
|
val watchType = DataStoreHelper.getResultWatchState(load.getId())
|
||||||
|
home_preview_bookmark?.setText(watchType.stringRes)
|
||||||
|
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
null,
|
||||||
|
getDrawable(home_preview_bookmark.context, watchType.iconRes),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
home_preview_bookmark?.setOnClickListener { fab ->
|
||||||
|
activity?.showBottomDialog(
|
||||||
|
WatchType.values().map { fab.context.getString(it.stringRes) }
|
||||||
|
.toList(),
|
||||||
|
DataStoreHelper.getResultWatchState(load.getId()).ordinal,
|
||||||
|
fab.context.getString(R.string.action_add_to_bookmarks),
|
||||||
|
showApply = false,
|
||||||
|
{}) {
|
||||||
|
val newValue = WatchType.values()[it]
|
||||||
|
home_preview_bookmark?.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
null,
|
||||||
|
getDrawable(home_preview_bookmark.context, newValue.iconRes),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
home_preview_bookmark?.setText(newValue.stringRes)
|
||||||
|
|
||||||
|
updateWatchStatus(load, newValue)
|
||||||
|
reloadStored()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
observe(homeViewModel.apiName) { apiName ->
|
observe(homeViewModel.apiName) { apiName ->
|
||||||
currentApiName = apiName
|
currentApiName = apiName
|
||||||
// setKey(USER_SELECTED_HOMEPAGE_API, apiName)
|
// setKey(USER_SELECTED_HOMEPAGE_API, apiName)
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.lagradost.cloudstream3.ui.home
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.viewpager.widget.PagerAdapter
|
||||||
|
import com.lagradost.cloudstream3.LoadResponse
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||||
|
|
||||||
|
|
||||||
|
class HomeScrollAdapter(private val onPrimaryCallback: (LoadResponse) -> Unit) : PagerAdapter() {
|
||||||
|
private var items: List<LoadResponse> = listOf()
|
||||||
|
|
||||||
|
fun setItems(newItems: List<LoadResponse>) {
|
||||||
|
items = newItems
|
||||||
|
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCount(): Int {
|
||||||
|
return Int.MAX_VALUE//items.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemPosition(`object`: Any): Int {
|
||||||
|
return POSITION_NONE//super.getItemPosition(`object`)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getItemAtPosition(idx: Int): LoadResponse {
|
||||||
|
return items[idx % items.size]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||||
|
super.setPrimaryItem(container, position, `object`)
|
||||||
|
onPrimaryCallback.invoke(getItemAtPosition(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||||
|
val image = ImageView(container.context)
|
||||||
|
val item = getItemAtPosition(position)
|
||||||
|
image.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
image.setImage(item.posterUrl ?: item.backgroundPosterUrl, item.posterHeaders)
|
||||||
|
|
||||||
|
// val itemView: View = mLayoutInflater.inflate(R.layout.pager_item, container, false)
|
||||||
|
|
||||||
|
// val imageView: ImageView = itemView.findViewById<View>(R.id.imageView) as ImageView
|
||||||
|
// imageView.setImageResource(mResources.get(position))
|
||||||
|
|
||||||
|
container.addView(image)
|
||||||
|
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||||
|
container.removeView(`object` as View)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isViewFromObject(view: View, `object`: Any): Boolean {
|
||||||
|
return view === `object`
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.lagradost.cloudstream3.ui.home
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.viewpager.widget.ViewPager
|
||||||
|
|
||||||
|
class HomeScrollTransformer : ViewPager.PageTransformer {
|
||||||
|
override fun transformPage(page: View, position: Float) {
|
||||||
|
page.setPadding(
|
||||||
|
maxOf(0, (-position * page.width / 2).toInt()), 0,
|
||||||
|
maxOf(0, (position * page.width / 2).toInt()), 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ import com.lagradost.cloudstream3.ui.APIRepository
|
||||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
|
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
|
||||||
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
|
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
||||||
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllResumeStateIds
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllResumeStateIds
|
||||||
|
@ -33,6 +35,7 @@ import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
|
||||||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
@ -58,9 +61,9 @@ class HomeViewModel : ViewModel() {
|
||||||
val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks
|
val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks
|
||||||
|
|
||||||
private val _resumeWatching = MutableLiveData<List<SearchResponse>>()
|
private val _resumeWatching = MutableLiveData<List<SearchResponse>>()
|
||||||
private val _preview = MutableLiveData<Resource<LoadResponse>>()
|
private val _preview = MutableLiveData<Resource<List<LoadResponse>>>()
|
||||||
val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching
|
val resumeWatching: LiveData<List<SearchResponse>> = _resumeWatching
|
||||||
val preview: LiveData<Resource<LoadResponse>> = _preview
|
val preview: LiveData<Resource<List<LoadResponse>>> = _preview
|
||||||
|
|
||||||
fun loadResumeWatching() = viewModelScope.launchSafe {
|
fun loadResumeWatching() = viewModelScope.launchSafe {
|
||||||
val resumeWatching = withContext(Dispatchers.IO) {
|
val resumeWatching = withContext(Dispatchers.IO) {
|
||||||
|
@ -210,7 +213,7 @@ class HomeViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun load(api: MainAPI?) = viewModelScope.launchSafe {
|
private fun load(api: MainAPI?) = ioSafe {
|
||||||
repo = if (api != null) {
|
repo = if (api != null) {
|
||||||
APIRepository(api)
|
APIRepository(api)
|
||||||
} else {
|
} else {
|
||||||
|
@ -236,7 +239,35 @@ class HomeViewModel : ViewModel() {
|
||||||
ExpandableHomepageList(filteredList, 1, home.hasNext)
|
ExpandableHomepageList(filteredList, 1, home.hasNext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val items = data.value.mapNotNull { it?.items }.flatten()
|
val items = data.value.mapNotNull { it?.items }.flatten()
|
||||||
|
val responses = ioWork {
|
||||||
|
items.flatMap { it.list }.shuffled().take(6).map { searchResponse ->
|
||||||
|
async { repo?.load(searchResponse.url) }
|
||||||
|
}.map { it.await() }.mapNotNull { if (it != null && it is Resource.Success) it.value else null } }
|
||||||
|
//.amap { searchResponse ->
|
||||||
|
// repo?.load(searchResponse.url)
|
||||||
|
///}
|
||||||
|
|
||||||
|
//.map { searchResponse ->
|
||||||
|
// async { repo?.load(searchResponse.url) }
|
||||||
|
// }.map { it.await() }
|
||||||
|
|
||||||
|
|
||||||
|
if (responses.isEmpty()) {
|
||||||
|
_preview.postValue(
|
||||||
|
Resource.Failure(
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"No homepage responses"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
_preview.postValue(Resource.Success(responses))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
items.randomOrNull()?.list?.randomOrNull()?.url?.let { url ->
|
items.randomOrNull()?.list?.randomOrNull()?.url?.let { url ->
|
||||||
// backup request in case first fails
|
// backup request in case first fails
|
||||||
var first = repo?.load(url)
|
var first = repo?.load(url)
|
||||||
|
@ -264,7 +295,7 @@ class HomeViewModel : ViewModel() {
|
||||||
"No homepage items"
|
"No homepage items"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
_page.postValue(Resource.Success(expandable))
|
_page.postValue(Resource.Success(expandable))
|
||||||
|
|
||||||
|
|
|
@ -344,7 +344,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
seasonNumber = currentTempMeta.season,
|
seasonNumber = currentTempMeta.season,
|
||||||
lang = currentLanguageTwoLetters.ifBlank { null }
|
lang = currentLanguageTwoLetters.ifBlank { null }
|
||||||
)
|
)
|
||||||
val results = providers.apmap {
|
val results = providers.amap {
|
||||||
try {
|
try {
|
||||||
it.search(search)
|
it.search(search)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.ui.player
|
package com.lagradost.cloudstream3.ui.player
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
@ -46,7 +46,7 @@ class LinkGenerator(
|
||||||
subtitleCallback: (SubtitleData) -> Unit,
|
subtitleCallback: (SubtitleData) -> Unit,
|
||||||
offset: Int
|
offset: Int
|
||||||
): Boolean {
|
): Boolean {
|
||||||
links.apmap { link ->
|
links.amap { link ->
|
||||||
if (!extract || !loadExtractor(link, referer, {
|
if (!extract || !loadExtractor(link, referer, {
|
||||||
subtitleCallback(PlayerSubtitleHelper.getSubtitleData(it))
|
subtitleCallback(PlayerSubtitleHelper.getSubtitleData(it))
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -1972,7 +1972,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
): List<ExtractedTrailerData> =
|
): List<ExtractedTrailerData> =
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
var currentCount = 0
|
var currentCount = 0
|
||||||
return@coroutineScope loadResponse.trailers.apmap { trailerData ->
|
return@coroutineScope loadResponse.trailers.amap { trailerData ->
|
||||||
try {
|
try {
|
||||||
val links = arrayListOf<ExtractorLink>()
|
val links = arrayListOf<ExtractorLink>()
|
||||||
val subs = arrayListOf<SubtitleFile>()
|
val subs = arrayListOf<SubtitleFile>()
|
||||||
|
|
|
@ -4,7 +4,7 @@ import android.util.Log
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
|
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
|
||||||
|
@ -197,7 +197,7 @@ class SyncViewModel : ViewModel() {
|
||||||
/// modifies the current sync data, return null if you don't want to change it
|
/// modifies the current sync data, return null if you don't want to change it
|
||||||
private fun modifyData(update: ((SyncAPI.SyncStatus) -> (SyncAPI.SyncStatus?))) =
|
private fun modifyData(update: ((SyncAPI.SyncStatus) -> (SyncAPI.SyncStatus?))) =
|
||||||
ioSafe {
|
ioSafe {
|
||||||
syncs.apmap { (prefix, id) ->
|
syncs.amap { (prefix, id) ->
|
||||||
repos.firstOrNull { it.idPrefix == prefix }?.let { repo ->
|
repos.firstOrNull { it.idPrefix == prefix }?.let { repo ->
|
||||||
if (repo.hasAccount()) {
|
if (repo.hasAccount()) {
|
||||||
val result = repo.getStatus(id)
|
val result = repo.getStatus(id)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
import com.lagradost.cloudstream3.SearchResponse
|
import com.lagradost.cloudstream3.SearchResponse
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.launchSafe
|
import com.lagradost.cloudstream3.mvvm.launchSafe
|
||||||
import com.lagradost.cloudstream3.ui.APIRepository
|
import com.lagradost.cloudstream3.ui.APIRepository
|
||||||
|
@ -108,9 +108,9 @@ class SearchViewModel : ViewModel() {
|
||||||
|
|
||||||
repos.filter { a ->
|
repos.filter { a ->
|
||||||
(ignoreSettings || (providersActive.isEmpty() || providersActive.contains(a.name))) && (!isQuickSearch || a.hasQuickSearch)
|
(ignoreSettings || (providersActive.isEmpty() || providersActive.contains(a.name))) && (!isQuickSearch || a.hasQuickSearch)
|
||||||
}.apmap { a -> // Parallel
|
}.amap { a -> // Parallel
|
||||||
val search = if (isQuickSearch) a.quickSearch(query) else a.search(query)
|
val search = if (isQuickSearch) a.quickSearch(query) else a.search(query)
|
||||||
if (currentSearchIndex != currentIndex) return@apmap
|
if (currentSearchIndex != currentIndex) return@amap
|
||||||
currentList.add(OnGoingSearch(a.name, search))
|
currentList.add(OnGoingSearch(a.name, search))
|
||||||
_currentSearch.postValue(currentList)
|
_currentSearch.postValue(currentList)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.Some
|
import com.lagradost.cloudstream3.mvvm.Some
|
||||||
import com.lagradost.cloudstream3.mvvm.debugAssert
|
import com.lagradost.cloudstream3.mvvm.debugAssert
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
|
@ -49,7 +49,7 @@ class ExtensionsViewModel : ViewModel() {
|
||||||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||||
?: emptyArray()) + PREBUILT_REPOSITORIES
|
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||||
|
|
||||||
val onlinePlugins = urls.toList().apmap {
|
val onlinePlugins = urls.toList().amap {
|
||||||
RepositoryManager.getRepoPlugins(it.url)?.toList() ?: emptyList()
|
RepositoryManager.getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||||
}.flatten().distinctBy { it.second.url }
|
}.flatten().distinctBy { it.second.url }
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.launchSafe
|
import com.lagradost.cloudstream3.mvvm.launchSafe
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginPath
|
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginPath
|
||||||
|
@ -101,7 +101,7 @@ class PluginsViewModel : ViewModel() {
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.apmap { (repo, metadata) ->
|
}.amap { (repo, metadata) ->
|
||||||
PluginManager.downloadAndLoadPlugin(
|
PluginManager.downloadAndLoadPlugin(
|
||||||
activity,
|
activity,
|
||||||
metadata.url,
|
metadata.url,
|
||||||
|
|
|
@ -13,7 +13,6 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.apmap
|
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY
|
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY
|
||||||
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY_LOCAL
|
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY_LOCAL
|
||||||
|
@ -28,7 +27,6 @@ import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_S
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_TOKEN_KEY
|
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_TOKEN_KEY
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_UNIXTIME_KEY
|
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_UNIXTIME_KEY
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_USER_KEY
|
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_USER_KEY
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.OpenSubtitlesApi
|
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.OpenSubtitlesApi.Companion.OPEN_SUBTITLES_USER_KEY
|
import com.lagradost.cloudstream3.syncproviders.providers.OpenSubtitlesApi.Companion.OPEN_SUBTITLES_USER_KEY
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getDefaultSharedPrefs
|
import com.lagradost.cloudstream3.utils.DataStore.getDefaultSharedPrefs
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getSharedPrefs
|
import com.lagradost.cloudstream3.utils.DataStore.getSharedPrefs
|
||||||
|
|
|
@ -279,30 +279,40 @@
|
||||||
<requestFocus />
|
<requestFocus />
|
||||||
</ImageView>-->
|
</ImageView>-->
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
<!--https://www.digitalocean.com/community/tutorials/android-viewpager-example-tutorial-->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
tools:visibility="visible"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:id="@+id/home_preview"
|
android:id="@+id/home_preview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="500dp">
|
android:layout_height="500dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/home_preview_viewpager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</androidx.viewpager.widget.ViewPager>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:alpha="0.8"
|
android:visibility="gone"
|
||||||
android:id="@+id/home_preview_image"
|
android:id="@+id/home_preview_image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.8"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@drawable/example_poster" />
|
tools:src="@drawable/example_poster" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:visibility="visible"
|
|
||||||
android:id="@+id/title_shadow_top"
|
android:id="@+id/title_shadow_top"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dp"
|
android:layout_height="150dp"
|
||||||
android:alpha="1"
|
|
||||||
android:rotation="180"
|
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
android:background="@drawable/background_shadow" />
|
android:alpha="1"
|
||||||
|
android:background="@drawable/background_shadow"
|
||||||
|
android:rotation="180"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/title_shadow"
|
android:id="@+id/title_shadow"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -312,29 +322,29 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/home_padding"
|
android:id="@+id/home_padding"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.appcompat.widget.SearchView
|
<androidx.appcompat.widget.SearchView
|
||||||
android:id="@+id/home_search"
|
android:id="@+id/home_search"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:gravity="start"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
|
android:editTextColor="@color/white"
|
||||||
|
android:gravity="start"
|
||||||
android:iconifiedByDefault="true"
|
android:iconifiedByDefault="true"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white"
|
||||||
app:iconifiedByDefault="true"
|
app:iconifiedByDefault="true"
|
||||||
app:queryBackground="@color/transparent"
|
app:queryBackground="@color/transparent"
|
||||||
app:queryHint="@string/search"
|
app:queryHint="@string/search"
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textColorHint="@color/white"
|
|
||||||
android:editTextColor="@color/white"
|
|
||||||
|
|
||||||
app:searchIcon="@drawable/search_icon"
|
app:searchIcon="@drawable/search_icon"
|
||||||
tools:ignore="RtlSymmetry" />
|
tools:ignore="RtlSymmetry" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<TextView
|
<TextView
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/test_search"
|
android:id="@+id/test_search"
|
||||||
|
@ -350,24 +360,25 @@
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
app:drawableLeftCompat="@drawable/search_icon"
|
app:drawableLeftCompat="@drawable/search_icon"
|
||||||
app:tint="@color/white" />
|
app:tint="@color/white" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:paddingStart="30dp"
|
|
||||||
android:paddingEnd="30dp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:paddingBottom="10dp"
|
|
||||||
android:id="@+id/home_preview_title"
|
android:id="@+id/home_preview_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:paddingStart="30dp"
|
||||||
|
android:paddingEnd="30dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
android:textColor="?attr/white"
|
android:textColor="?attr/white"
|
||||||
android:textSize="17sp"
|
android:textSize="17sp"
|
||||||
|
android:textStyle="bold"
|
||||||
tools:text="The Perfect Run" />
|
tools:text="The Perfect Run" />
|
||||||
<!--<TextView
|
<!--<TextView
|
||||||
android:paddingStart="30dp"
|
android:paddingStart="30dp"
|
||||||
|
@ -380,60 +391,62 @@
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:text="5 seasons 50 episodes" />-->
|
tools:text="5 seasons 50 episodes" />-->
|
||||||
<TextView
|
<TextView
|
||||||
android:paddingStart="30dp"
|
|
||||||
android:paddingEnd="30dp"
|
|
||||||
android:id="@+id/home_preview_tags"
|
android:id="@+id/home_preview_tags"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:paddingStart="30dp"
|
||||||
|
android:paddingEnd="30dp"
|
||||||
android:textColor="?attr/white"
|
android:textColor="?attr/white"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:text="Hello • World • Tags" />
|
tools:text="Hello • World • Tags" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:padding="20dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/home_preview_bookmark"
|
android:id="@+id/home_preview_bookmark"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_marginStart="25dp"
|
|
||||||
android:layout_marginEnd="25dp"
|
|
||||||
android:layout_width="70dp"
|
android:layout_width="70dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginEnd="25dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:gravity="center"
|
||||||
android:text="@string/none"
|
android:text="@string/none"
|
||||||
android:textColor="?attr/white"
|
android:textColor="?attr/white"
|
||||||
|
app:drawableTint="?attr/white"
|
||||||
app:drawableTopCompat="@drawable/ic_baseline_add_24"
|
app:drawableTopCompat="@drawable/ic_baseline_add_24"
|
||||||
app:tint="?attr/white"
|
app:tint="?attr/white" />
|
||||||
app:drawableTint="?attr/white" />
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:layout_gravity="center"
|
|
||||||
style="@style/WhiteButton"
|
|
||||||
android:id="@+id/home_preview_play"
|
android:id="@+id/home_preview_play"
|
||||||
|
style="@style/WhiteButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
|
||||||
android:text="@string/home_play"
|
android:text="@string/home_play"
|
||||||
app:icon="@drawable/ic_baseline_play_arrow_24" />
|
app:icon="@drawable/ic_baseline_play_arrow_24" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:id="@+id/home_preview_info"
|
android:id="@+id/home_preview_info"
|
||||||
android:gravity="center"
|
android:layout_width="70dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginStart="25dp"
|
android:layout_marginStart="25dp"
|
||||||
android:layout_marginEnd="25dp"
|
android:layout_marginEnd="25dp"
|
||||||
android:layout_width="70dp"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:layout_height="wrap_content"
|
android:gravity="center"
|
||||||
android:text="@string/home_info"
|
android:text="@string/home_info"
|
||||||
android:textColor="?attr/white"
|
android:textColor="?attr/white"
|
||||||
|
app:drawableTint="?attr/white"
|
||||||
app:drawableTopCompat="@drawable/ic_outline_info_24"
|
app:drawableTopCompat="@drawable/ic_outline_info_24"
|
||||||
app:tint="?attr/white"
|
app:tint="?attr/white" />
|
||||||
app:drawableTint="?attr/white" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -522,15 +535,15 @@
|
||||||
|
|
||||||
<com.google.android.material.chip.ChipGroup
|
<com.google.android.material.chip.ChipGroup
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
app:singleSelection="true"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal"
|
||||||
|
app:singleSelection="true">
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/home_type_watching_btt"
|
android:id="@+id/home_type_watching_btt"
|
||||||
style="@style/ChipFilled"
|
style="@style/ChipFilled"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:nextFocusLeft="@id/nav_rail_view"
|
android:nextFocusLeft="@id/nav_rail_view"
|
||||||
android:nextFocusRight="@id/home_plan_to_watch_btt"
|
android:nextFocusRight="@id/home_plan_to_watch_btt"
|
||||||
|
@ -539,8 +552,8 @@
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/home_plan_to_watch_btt"
|
android:id="@+id/home_plan_to_watch_btt"
|
||||||
style="@style/ChipFilled"
|
style="@style/ChipFilled"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:nextFocusLeft="@id/home_type_watching_btt"
|
android:nextFocusLeft="@id/home_type_watching_btt"
|
||||||
android:nextFocusRight="@id/home_type_on_hold_btt"
|
android:nextFocusRight="@id/home_type_on_hold_btt"
|
||||||
|
@ -549,8 +562,8 @@
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/home_type_on_hold_btt"
|
android:id="@+id/home_type_on_hold_btt"
|
||||||
style="@style/ChipFilled"
|
style="@style/ChipFilled"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:nextFocusLeft="@id/home_plan_to_watch_btt"
|
android:nextFocusLeft="@id/home_plan_to_watch_btt"
|
||||||
android:nextFocusRight="@id/home_type_dropped_btt"
|
android:nextFocusRight="@id/home_type_dropped_btt"
|
||||||
|
@ -559,8 +572,8 @@
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/home_type_dropped_btt"
|
android:id="@+id/home_type_dropped_btt"
|
||||||
style="@style/ChipFilled"
|
style="@style/ChipFilled"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:nextFocusLeft="@id/home_type_on_hold_btt"
|
android:nextFocusLeft="@id/home_type_on_hold_btt"
|
||||||
android:nextFocusRight="@id/home_type_completed_btt"
|
android:nextFocusRight="@id/home_type_completed_btt"
|
||||||
|
@ -568,10 +581,10 @@
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/home_type_completed_btt"
|
android:id="@+id/home_type_completed_btt"
|
||||||
android:layout_height="wrap_content"
|
style="@style/ChipFilled"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
||||||
style="@style/ChipFilled"
|
android:layout_height="wrap_content"
|
||||||
android:nextFocusLeft="@id/home_type_dropped_btt"
|
android:nextFocusLeft="@id/home_type_dropped_btt"
|
||||||
android:text="@string/type_completed" />
|
android:text="@string/type_completed" />
|
||||||
</com.google.android.material.chip.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
|
|
|
@ -162,7 +162,7 @@ class ProviderTests {
|
||||||
// @Test
|
// @Test
|
||||||
// fun providerCorrectHomepage() {
|
// fun providerCorrectHomepage() {
|
||||||
// runBlocking {
|
// runBlocking {
|
||||||
// getAllProviders().apmap { api ->
|
// getAllProviders().amap { api ->
|
||||||
// if (api.hasMainPage) {
|
// if (api.hasMainPage) {
|
||||||
// try {
|
// try {
|
||||||
// val homepage = api.getMainPage()
|
// val homepage = api.getMainPage()
|
||||||
|
@ -197,7 +197,7 @@ class ProviderTests {
|
||||||
// suspend fun providerCorrect() {
|
// suspend fun providerCorrect() {
|
||||||
// val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
// val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
||||||
// val providers = getAllProviders()
|
// val providers = getAllProviders()
|
||||||
// providers.apmap { api ->
|
// providers.amap { api ->
|
||||||
// try {
|
// try {
|
||||||
// println("Trying $api")
|
// println("Trying $api")
|
||||||
// if (testSingleProviderApi(api)) {
|
// if (testSingleProviderApi(api)) {
|
||||||
|
|
Loading…
Reference in a new issue