mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
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
|
||||
fun providerCorrectHomepage() {
|
||||
runBlocking {
|
||||
getAllProviders().apmap { api ->
|
||||
getAllProviders().amap { api ->
|
||||
if (api.hasMainPage) {
|
||||
try {
|
||||
val homepage = api.getMainPage()
|
||||
|
@ -217,7 +217,7 @@ class ExampleInstrumentedTest {
|
|||
runBlocking {
|
||||
val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
||||
val providers = getAllProviders()
|
||||
providers.apmap { api ->
|
||||
providers.amap { api ->
|
||||
try {
|
||||
println("Trying $api")
|
||||
if (testSingleProviderApi(api)) {
|
||||
|
|
|
@ -1066,7 +1066,7 @@ interface LoadResponse {
|
|||
) {
|
||||
if (!isTrailersEnabled || trailerUrls == null) return
|
||||
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 subs = arrayListOf<SubtitleFile>()
|
||||
if (!loadExtractor(
|
||||
|
|
|
@ -592,7 +592,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
api.init()
|
||||
}
|
||||
|
||||
inAppAuths.apmap { api ->
|
||||
inAppAuths.amap { api ->
|
||||
try {
|
||||
api.initialize()
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.lagradost.cloudstream3
|
||||
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
//https://stackoverflow.com/questions/34697828/parallel-operations-on-kotlin-collections
|
||||
/*
|
||||
|
@ -26,10 +25,25 @@ fun <T, R> Iterable<T>.pmap(
|
|||
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 {
|
||||
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 {
|
||||
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() }
|
||||
}
|
||||
|
||||
@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
|
||||
/*fun <R> argpmap(
|
||||
vararg transforms: () -> R,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
|
@ -21,10 +21,10 @@ class Fastream: ExtractorApi() {
|
|||
Pair("file_code",id),
|
||||
Pair("auto","1")
|
||||
)).document
|
||||
response.select("script").apmap { script ->
|
||||
response.select("script").amap { script ->
|
||||
if (script.data().contains("sources")) {
|
||||
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(
|
||||
name,
|
||||
m3u8,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
|
@ -35,7 +35,7 @@ class Pelisplus(val mainUrl: String) {
|
|||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
try {
|
||||
normalApis.apmap { api ->
|
||||
normalApis.amap { api ->
|
||||
val url = api.getExtractorUrl(id)
|
||||
api.getSafeUrl(url, subtitleCallback = subtitleCallback, callback = callback)
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ class Pelisplus(val mainUrl: String) {
|
|||
val qualityRegex = Regex("(\\d+)P")
|
||||
|
||||
//a[download]
|
||||
pageDoc.select(".dowload > a")?.apmap { element ->
|
||||
val href = element.attr("href") ?: return@apmap
|
||||
pageDoc.select(".dowload > a")?.amap { element ->
|
||||
val href = element.attr("href") ?: return@amap
|
||||
val qual = if (element.text()
|
||||
.contains("HDP")
|
||||
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
||||
|
@ -84,7 +84,7 @@ class Pelisplus(val mainUrl: String) {
|
|||
//val name = element.text()
|
||||
|
||||
// Matches vidstream links with extractors
|
||||
extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api ->
|
||||
extractorApis.filter { !it.requiresReferer || !isCasting }.amap { api ->
|
||||
if (link.startsWith(api.mainUrl)) {
|
||||
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -69,12 +69,12 @@ open class VidSrcExtractor : ExtractorApi() {
|
|||
} else ""
|
||||
}
|
||||
|
||||
serverslist.apmap { server ->
|
||||
serverslist.amap { server ->
|
||||
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
|
||||
if (linkfixed.contains("/pro")) {
|
||||
val srcresponse = app.get(server, referer = absoluteUrl).text
|
||||
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 pass = passRegex.find(srcresponse)?.groupValues?.get(1)?.replace(
|
||||
Regex("""^//"""), "https://"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.argamap
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
|
@ -37,7 +37,7 @@ class Vidstream(val mainUrl: String) {
|
|||
val extractorUrl = getExtractorUrl(id)
|
||||
argamap(
|
||||
{
|
||||
normalApis.apmap { api ->
|
||||
normalApis.amap { api ->
|
||||
val url = api.getExtractorUrl(id)
|
||||
api.getSafeUrl(
|
||||
url,
|
||||
|
@ -55,8 +55,8 @@ class Vidstream(val mainUrl: String) {
|
|||
val qualityRegex = Regex("(\\d+)P")
|
||||
|
||||
//a[download]
|
||||
pageDoc.select(".dowload > a")?.apmap { element ->
|
||||
val href = element.attr("href") ?: return@apmap
|
||||
pageDoc.select(".dowload > a")?.amap { element ->
|
||||
val href = element.attr("href") ?: return@amap
|
||||
val qual = if (element.text()
|
||||
.contains("HDP")
|
||||
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
|
||||
|
@ -87,7 +87,7 @@ class Vidstream(val mainUrl: String) {
|
|||
//val name = element.text()
|
||||
|
||||
// Matches vidstream links with extractors
|
||||
extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api ->
|
||||
extractorApis.filter { !it.requiresReferer || !isCasting }.amap { api ->
|
||||
if (link.startsWith(api.mainUrl)) {
|
||||
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
|
@ -36,7 +36,7 @@ open class ZplayerV2 : ExtractorApi() {
|
|||
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
||||
m3u8regex.findAll(testdata).map {
|
||||
it.value
|
||||
}.toList().apmap { urlm3u8 ->
|
||||
}.toList().amap { urlm3u8 ->
|
||||
if (urlm3u8.contains("m3u8")) {
|
||||
val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text
|
||||
if (testurl.contains("EXTM3U")) {
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.extractors.helper
|
|||
|
||||
import android.util.Log
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
|
@ -18,7 +18,7 @@ class AsianEmbedHelper {
|
|||
val doc = app.get(url).document
|
||||
val links = doc.select("div#list-server-more > ul > li.linkserver")
|
||||
if (!links.isNullOrEmpty()) {
|
||||
links.apmap {
|
||||
links.amap {
|
||||
val datavid = it.attr("data-video") ?: ""
|
||||
//Log.i("AsianEmbed", "Result => (datavid) ${datavid}")
|
||||
if (datavid.isNotBlank()) {
|
||||
|
|
|
@ -39,7 +39,7 @@ class CrossTmdbProvider : TmdbProvider() {
|
|||
): Boolean {
|
||||
tryParseJson<CrossMetaData>(data)?.let { metaData ->
|
||||
if (!metaData.isSuccess) return false
|
||||
metaData.movies?.apmap { (apiName, data) ->
|
||||
metaData.movies?.amap { (apiName, data) ->
|
||||
getApiFromNameNull(apiName)?.let {
|
||||
try {
|
||||
it.loadLinks(data, isCasting, subtitleCallback, callback)
|
||||
|
@ -64,10 +64,10 @@ class CrossTmdbProvider : TmdbProvider() {
|
|||
val matchName = filterName(this.name)
|
||||
when (this) {
|
||||
is MovieLoadResponse -> {
|
||||
val data = validApis.apmap { api ->
|
||||
val data = validApis.amap { api ->
|
||||
try {
|
||||
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(
|
||||
matchName,
|
||||
ignoreCase = true
|
||||
|
|
|
@ -45,7 +45,7 @@ class MultiAnimeProvider : MainAPI() {
|
|||
|
||||
override suspend fun load(url: String): LoadResponse? {
|
||||
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)
|
||||
}.filterNotNull()
|
||||
|
||||
|
|
|
@ -217,18 +217,17 @@ object PluginManager {
|
|||
* 3. If outdated download and load the plugin
|
||||
* 4. Else load the plugin normally
|
||||
**/
|
||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) {
|
||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) = ioSafe {
|
||||
// Load all plugins as fast as possible!
|
||||
loadAllOnlinePlugins(activity)
|
||||
|
||||
ioSafe {
|
||||
afterPluginsLoadedEvent.invoke(true)
|
||||
}
|
||||
|
||||
|
||||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||
|
||||
val onlinePlugins = urls.toList().apmap {
|
||||
val onlinePlugins = urls.toList().amap {
|
||||
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||
}.flatten().distinctBy { it.second.url }
|
||||
|
||||
|
@ -249,7 +248,7 @@ object PluginManager {
|
|||
|
||||
val updatedPlugins = mutableListOf<String>()
|
||||
|
||||
outdatedPlugins.apmap { pluginData ->
|
||||
outdatedPlugins.amap { pluginData ->
|
||||
if (pluginData.isDisabled) {
|
||||
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
||||
unloadPlugin(pluginData.savedData.filePath)
|
||||
|
@ -270,9 +269,9 @@ object PluginManager {
|
|||
createNotification(activity, updatedPlugins)
|
||||
}
|
||||
|
||||
ioSafe {
|
||||
// ioSafe {
|
||||
afterPluginsLoadedEvent.invoke(true)
|
||||
}
|
||||
// }
|
||||
|
||||
Log.i(TAG, "Plugin update done!")
|
||||
}
|
||||
|
@ -280,9 +279,9 @@ object PluginManager {
|
|||
/**
|
||||
* Use updateAllOnlinePluginsAndLoadThem
|
||||
* */
|
||||
fun loadAllOnlinePlugins(activity: Activity) {
|
||||
fun loadAllOnlinePlugins(activity: Activity) = ioSafe {
|
||||
// Load all plugins as fast as possible!
|
||||
(getPluginsOnline()).toList().apmap { pluginData ->
|
||||
(getPluginsOnline()).toList().amap { pluginData ->
|
||||
loadPlugin(
|
||||
activity,
|
||||
File(pluginData.filePath),
|
||||
|
@ -291,7 +290,7 @@ object PluginManager {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadAllLocalPlugins(activity: Activity) {
|
||||
fun loadAllLocalPlugins(activity: Activity) = ioSafe {
|
||||
val dir = File(LOCAL_PLUGINS_PATH)
|
||||
removeKey(PLUGINS_KEY_LOCAL)
|
||||
|
||||
|
@ -299,7 +298,7 @@ object PluginManager {
|
|||
val res = dir.mkdirs()
|
||||
if (!res) {
|
||||
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.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
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.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||
|
@ -95,7 +95,7 @@ object RepositoryManager {
|
|||
* */
|
||||
suspend fun getRepoPlugins(repositoryUrl: String): List<Pair<String, SitePlugin>>? {
|
||||
val repo = parseRepository(repositoryUrl) ?: return null
|
||||
return repo.pluginLists.apmap { url ->
|
||||
return repo.pluginLists.amap { url ->
|
||||
parsePlugins(url).map {
|
||||
repositoryUrl to it
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import com.lagradost.cloudstream3.mvvm.Resource
|
|||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||
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
|
||||
|
||||
class APIRepository(val api: MainAPI) {
|
||||
|
@ -27,7 +31,7 @@ class APIRepository(val api: MainAPI) {
|
|||
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
|
||||
|
@ -42,7 +46,7 @@ class APIRepository(val api: MainAPI) {
|
|||
return safeApiCall {
|
||||
if (isInvalidData(url)) throw ErrorLoadingException()
|
||||
val fixedUrl = api.fixUrl(url)
|
||||
val key = Pair(api.name,url)
|
||||
val key = Pair(api.name, url)
|
||||
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
|
||||
if (cacheHash.size > 20) cacheHash.remove(cacheHash.keys.random())
|
||||
|
@ -78,6 +82,7 @@ class APIRepository(val api: MainAPI) {
|
|||
delay(delta)
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
suspend fun getMainPage(page: Int, nameIndex: Int? = null): Resource<List<HomePageResponse?>> {
|
||||
return safeApiCall {
|
||||
api.lastHomepageRequest = unixTimeMS
|
||||
|
@ -103,11 +108,15 @@ class APIRepository(val api: MainAPI) {
|
|||
)
|
||||
}
|
||||
} else {
|
||||
api.mainPage.apmap { data ->
|
||||
api.getMainPage(
|
||||
page,
|
||||
MainPageRequest(data.name, data.data, data.horizontalImages)
|
||||
)
|
||||
with(CoroutineScope(coroutineContext)) {
|
||||
api.mainPage.map { data ->
|
||||
async {
|
||||
api.getMainPage(
|
||||
page,
|
||||
MainPageRequest(data.name, data.data, data.horizontalImages)
|
||||
)
|
||||
}
|
||||
}.map { it.await() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -547,51 +547,14 @@ class HomeFragment : Fragment() {
|
|||
when (preview) {
|
||||
is Resource.Success -> {
|
||||
home_preview?.isVisible = true
|
||||
|
||||
preview.value.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(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()
|
||||
}
|
||||
}
|
||||
(home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply {
|
||||
setItems(preview.value)
|
||||
// home_preview_viewpager?.setCurrentItem(1000, false)
|
||||
}
|
||||
|
||||
//.also {
|
||||
//home_preview_viewpager?.adapter =
|
||||
//}
|
||||
}
|
||||
else -> {
|
||||
home_preview?.isVisible = false
|
||||
|
@ -606,6 +569,58 @@ class HomeFragment : Fragment() {
|
|||
searchText.setTextColor(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 ->
|
||||
currentApiName = 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.randomApi
|
||||
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.DataStoreHelper
|
||||
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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import kotlin.collections.set
|
||||
|
@ -58,9 +61,9 @@ class HomeViewModel : ViewModel() {
|
|||
val bookmarks: LiveData<Pair<Boolean, List<SearchResponse>>> = _bookmarks
|
||||
|
||||
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 preview: LiveData<Resource<LoadResponse>> = _preview
|
||||
val preview: LiveData<Resource<List<LoadResponse>>> = _preview
|
||||
|
||||
fun loadResumeWatching() = viewModelScope.launchSafe {
|
||||
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) {
|
||||
APIRepository(api)
|
||||
} else {
|
||||
|
@ -236,7 +239,35 @@ class HomeViewModel : ViewModel() {
|
|||
ExpandableHomepageList(filteredList, 1, home.hasNext)
|
||||
}
|
||||
}
|
||||
|
||||
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 ->
|
||||
// backup request in case first fails
|
||||
var first = repo?.load(url)
|
||||
|
@ -264,7 +295,7 @@ class HomeViewModel : ViewModel() {
|
|||
"No homepage items"
|
||||
)
|
||||
)
|
||||
}
|
||||
}*/
|
||||
|
||||
_page.postValue(Resource.Success(expandable))
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
seasonNumber = currentTempMeta.season,
|
||||
lang = currentLanguageTwoLetters.ifBlank { null }
|
||||
)
|
||||
val results = providers.apmap {
|
||||
val results = providers.amap {
|
||||
try {
|
||||
it.search(search)
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.utils.*
|
||||
import java.net.URI
|
||||
|
@ -46,7 +46,7 @@ class LinkGenerator(
|
|||
subtitleCallback: (SubtitleData) -> Unit,
|
||||
offset: Int
|
||||
): Boolean {
|
||||
links.apmap { link ->
|
||||
links.amap { link ->
|
||||
if (!extract || !loadExtractor(link, referer, {
|
||||
subtitleCallback(PlayerSubtitleHelper.getSubtitleData(it))
|
||||
}) {
|
||||
|
|
|
@ -1972,7 +1972,7 @@ class ResultViewModel2 : ViewModel() {
|
|||
): List<ExtractedTrailerData> =
|
||||
coroutineScope {
|
||||
var currentCount = 0
|
||||
return@coroutineScope loadResponse.trailers.apmap { trailerData ->
|
||||
return@coroutineScope loadResponse.trailers.amap { trailerData ->
|
||||
try {
|
||||
val links = arrayListOf<ExtractorLink>()
|
||||
val subs = arrayListOf<SubtitleFile>()
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.util.Log
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
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.logError
|
||||
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
|
||||
private fun modifyData(update: ((SyncAPI.SyncStatus) -> (SyncAPI.SyncStatus?))) =
|
||||
ioSafe {
|
||||
syncs.apmap { (prefix, id) ->
|
||||
syncs.amap { (prefix, id) ->
|
||||
repos.firstOrNull { it.idPrefix == prefix }?.let { repo ->
|
||||
if (repo.hasAccount()) {
|
||||
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.setKey
|
||||
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.launchSafe
|
||||
import com.lagradost.cloudstream3.ui.APIRepository
|
||||
|
@ -108,9 +108,9 @@ class SearchViewModel : ViewModel() {
|
|||
|
||||
repos.filter { a ->
|
||||
(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)
|
||||
if (currentSearchIndex != currentIndex) return@apmap
|
||||
if (currentSearchIndex != currentIndex) return@amap
|
||||
currentList.add(OnGoingSearch(a.name, search))
|
||||
_currentSearch.postValue(currentList)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
|
|||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
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.debugAssert
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||
|
@ -49,7 +49,7 @@ class ExtensionsViewModel : ViewModel() {
|
|||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||
|
||||
val onlinePlugins = urls.toList().apmap {
|
||||
val onlinePlugins = urls.toList().amap {
|
||||
RepositoryManager.getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||
}.flatten().distinctBy { it.second.url }
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
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.plugins.PluginManager
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginPath
|
||||
|
@ -101,7 +101,7 @@ class PluginsViewModel : ViewModel() {
|
|||
Toast.LENGTH_SHORT
|
||||
)
|
||||
}
|
||||
}.apmap { (repo, metadata) ->
|
||||
}.amap { (repo, metadata) ->
|
||||
PluginManager.downloadAndLoadPlugin(
|
||||
activity,
|
||||
metadata.url,
|
||||
|
|
|
@ -13,7 +13,6 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
|||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY
|
||||
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_UNIXTIME_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.utils.DataStore.getDefaultSharedPrefs
|
||||
import com.lagradost.cloudstream3.utils.DataStore.getSharedPrefs
|
||||
|
|
|
@ -279,30 +279,40 @@
|
|||
<requestFocus />
|
||||
</ImageView>-->
|
||||
</FrameLayout>
|
||||
|
||||
<!--https://www.digitalocean.com/community/tutorials/android-viewpager-example-tutorial-->
|
||||
<FrameLayout
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/home_preview"
|
||||
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
|
||||
android:alpha="0.8"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/home_preview_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0.8"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@drawable/example_poster" />
|
||||
|
||||
<View
|
||||
android:visibility="visible"
|
||||
android:id="@+id/title_shadow_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:alpha="1"
|
||||
android:rotation="180"
|
||||
android:layout_gravity="top"
|
||||
android:background="@drawable/background_shadow" />
|
||||
android:alpha="1"
|
||||
android:background="@drawable/background_shadow"
|
||||
android:rotation="180"
|
||||
android:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/title_shadow"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -312,62 +322,63 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/home_padding"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.SearchView
|
||||
android:id="@+id/home_search"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="start"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:editTextColor="@color/white"
|
||||
android:gravity="start"
|
||||
android:iconifiedByDefault="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/white"
|
||||
app:iconifiedByDefault="true"
|
||||
app:queryBackground="@color/transparent"
|
||||
app:queryHint="@string/search"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/white"
|
||||
android:editTextColor="@color/white"
|
||||
|
||||
app:searchIcon="@drawable/search_icon"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</LinearLayout>
|
||||
|
||||
<!--
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/test_search"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
<!--
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/test_search"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
|
||||
android:textSize="20dp"
|
||||
android:layout_margin="20dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search"
|
||||
android:textColor="@color/white"
|
||||
app:drawableLeftCompat="@drawable/search_icon"
|
||||
app:tint="@color/white" />
|
||||
-->
|
||||
android:textSize="20dp"
|
||||
android:layout_margin="20dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search"
|
||||
android:textColor="@color/white"
|
||||
app:drawableLeftCompat="@drawable/search_icon"
|
||||
app:tint="@color/white" />
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textStyle="bold"
|
||||
android:paddingBottom="10dp"
|
||||
android:id="@+id/home_preview_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="The Perfect Run" />
|
||||
<!--<TextView
|
||||
android:paddingStart="30dp"
|
||||
|
@ -380,60 +391,62 @@
|
|||
android:textSize="14sp"
|
||||
tools:text="5 seasons 50 episodes" />-->
|
||||
<TextView
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:id="@+id/home_preview_tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="14sp"
|
||||
tools:text="Hello • World • Tags" />
|
||||
|
||||
<LinearLayout
|
||||
android:padding="20dp"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
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_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:textColor="?attr/white"
|
||||
app:drawableTint="?attr/white"
|
||||
app:drawableTopCompat="@drawable/ic_baseline_add_24"
|
||||
app:tint="?attr/white"
|
||||
app:drawableTint="?attr/white" />
|
||||
app:tint="?attr/white" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:layout_gravity="center"
|
||||
style="@style/WhiteButton"
|
||||
android:id="@+id/home_preview_play"
|
||||
style="@style/WhiteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
||||
android:text="@string/home_play"
|
||||
app:icon="@drawable/ic_baseline_play_arrow_24" />
|
||||
|
||||
<TextView
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:id="@+id/home_preview_info"
|
||||
android:gravity="center"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="25dp"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:text="@string/home_info"
|
||||
android:textColor="?attr/white"
|
||||
app:drawableTint="?attr/white"
|
||||
app:drawableTopCompat="@drawable/ic_outline_info_24"
|
||||
app:tint="?attr/white"
|
||||
app:drawableTint="?attr/white" />
|
||||
app:tint="?attr/white" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
@ -522,15 +535,15 @@
|
|||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="wrap_content"
|
||||
app:singleSelection="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/home_type_watching_btt"
|
||||
style="@style/ChipFilled"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nextFocusLeft="@id/nav_rail_view"
|
||||
android:nextFocusRight="@id/home_plan_to_watch_btt"
|
||||
|
@ -539,8 +552,8 @@
|
|||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/home_plan_to_watch_btt"
|
||||
style="@style/ChipFilled"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nextFocusLeft="@id/home_type_watching_btt"
|
||||
android:nextFocusRight="@id/home_type_on_hold_btt"
|
||||
|
@ -549,8 +562,8 @@
|
|||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/home_type_on_hold_btt"
|
||||
style="@style/ChipFilled"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nextFocusLeft="@id/home_plan_to_watch_btt"
|
||||
android:nextFocusRight="@id/home_type_dropped_btt"
|
||||
|
@ -559,8 +572,8 @@
|
|||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/home_type_dropped_btt"
|
||||
style="@style/ChipFilled"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nextFocusLeft="@id/home_type_on_hold_btt"
|
||||
android:nextFocusRight="@id/home_type_completed_btt"
|
||||
|
@ -568,10 +581,10 @@
|
|||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/home_type_completed_btt"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/ChipFilled"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
style="@style/ChipFilled"
|
||||
android:layout_height="wrap_content"
|
||||
android:nextFocusLeft="@id/home_type_dropped_btt"
|
||||
android:text="@string/type_completed" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
|
|
@ -162,7 +162,7 @@ class ProviderTests {
|
|||
// @Test
|
||||
// fun providerCorrectHomepage() {
|
||||
// runBlocking {
|
||||
// getAllProviders().apmap { api ->
|
||||
// getAllProviders().amap { api ->
|
||||
// if (api.hasMainPage) {
|
||||
// try {
|
||||
// val homepage = api.getMainPage()
|
||||
|
@ -197,7 +197,7 @@ class ProviderTests {
|
|||
// suspend fun providerCorrect() {
|
||||
// val invalidProvider = ArrayList<Pair<MainAPI, Exception?>>()
|
||||
// val providers = getAllProviders()
|
||||
// providers.apmap { api ->
|
||||
// providers.amap { api ->
|
||||
// try {
|
||||
// println("Trying $api")
|
||||
// if (testSingleProviderApi(api)) {
|
||||
|
|
Loading…
Reference in a new issue