fix(all/yomiroll): Fetch anime status from AniList (#2728)
Co-authored-by: Samfun75 <38332931+Samfun75@users.noreply.github.com> Co-authored-by: jmir1 <jhmiramon@gmail.com>
This commit is contained in:
@ -8,7 +8,7 @@ ext {
|
|||||||
extName = 'Yomiroll'
|
extName = 'Yomiroll'
|
||||||
pkgNameSuffix = 'all.kamyroll'
|
pkgNameSuffix = 'all.kamyroll'
|
||||||
extClass = '.Yomiroll'
|
extClass = '.Yomiroll'
|
||||||
extVersionCode = 26
|
extVersionCode = 27
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,30 +59,26 @@ data class Anime(
|
|||||||
val genres: ArrayList<String>? = null,
|
val genres: ArrayList<String>? = null,
|
||||||
val series_metadata: Metadata? = null,
|
val series_metadata: Metadata? = null,
|
||||||
@SerialName("movie_listing_metadata")
|
@SerialName("movie_listing_metadata")
|
||||||
val movie_metadata: MovieMeta? = null,
|
val movie_metadata: Metadata? = null,
|
||||||
val content_provider: String? = null,
|
val content_provider: String? = null,
|
||||||
|
val audio_locale: String? = null,
|
||||||
|
val audio_locales: ArrayList<String>? = null,
|
||||||
|
val subtitle_locales: ArrayList<String>? = null,
|
||||||
|
val maturity_ratings: ArrayList<String>? = null,
|
||||||
|
val is_dubbed: Boolean? = null,
|
||||||
|
val is_subbed: Boolean? = null,
|
||||||
) {
|
) {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Metadata(
|
data class Metadata(
|
||||||
val maturity_ratings: ArrayList<String>,
|
val maturity_ratings: ArrayList<String>,
|
||||||
val is_simulcast: Boolean,
|
val is_simulcast: Boolean? = null,
|
||||||
val audio_locales: ArrayList<String>,
|
val audio_locales: ArrayList<String>? = null,
|
||||||
val subtitle_locales: ArrayList<String>,
|
val subtitle_locales: ArrayList<String>,
|
||||||
val is_dubbed: Boolean,
|
val is_dubbed: Boolean,
|
||||||
val is_subbed: Boolean,
|
val is_subbed: Boolean,
|
||||||
@SerialName("tenant_categories")
|
@SerialName("tenant_categories")
|
||||||
val genres: ArrayList<String>? = null,
|
val genres: ArrayList<String>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class MovieMeta(
|
|
||||||
val is_dubbed: Boolean,
|
|
||||||
val is_subbed: Boolean,
|
|
||||||
val maturity_ratings: ArrayList<String>,
|
|
||||||
val subtitle_locales: ArrayList<String>,
|
|
||||||
@SerialName("tenant_categories")
|
|
||||||
val genres: ArrayList<String>? = null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -172,6 +168,22 @@ data class Subtitle(
|
|||||||
val url: String,
|
val url: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class AnilistResult(
|
||||||
|
val data: AniData,
|
||||||
|
) {
|
||||||
|
@Serializable
|
||||||
|
data class AniData(
|
||||||
|
@SerialName("Media")
|
||||||
|
val media: Media? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Media(
|
||||||
|
val status: String,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> List<T>.thirdLast(): T? {
|
fun <T> List<T>.thirdLast(): T? {
|
||||||
if (size < 3) return null
|
if (size < 3) return null
|
||||||
return this[size - 3]
|
return this[size - 3]
|
||||||
|
@ -15,15 +15,19 @@ import eu.kanade.tachiyomi.animesource.model.Track
|
|||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import okhttp3.FormBody
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -53,6 +57,8 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
|
private val mainScope by lazy { MainScope() }
|
||||||
|
|
||||||
private val preferences: SharedPreferences by lazy {
|
private val preferences: SharedPreferences by lazy {
|
||||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
}
|
}
|
||||||
@ -65,6 +71,8 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
super.client.newBuilder().addInterceptor(tokenInterceptor).build()
|
super.client.newBuilder().addInterceptor(tokenInterceptor).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val noTokenClient = super.client
|
||||||
|
|
||||||
// ============================== Popular ===============================
|
// ============================== Popular ===============================
|
||||||
|
|
||||||
override fun popularAnimeRequest(page: Int): Request {
|
override fun popularAnimeRequest(page: Int): Request {
|
||||||
@ -73,7 +81,7 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun popularAnimeParse(response: Response): AnimesPage {
|
override fun popularAnimeParse(response: Response): AnimesPage {
|
||||||
val parsed = json.decodeFromString<AnimeResult>(response.body.string())
|
val parsed = json.decodeFromString<AnimeResult>(response.use { it.body.string() })
|
||||||
val animeList = parsed.data.mapNotNull { it.toSAnimeOrNull() }
|
val animeList = parsed.data.mapNotNull { it.toSAnimeOrNull() }
|
||||||
val position = response.request.url.queryParameter("start")?.toIntOrNull() ?: 0
|
val position = response.request.url.queryParameter("start")?.toIntOrNull() ?: 0
|
||||||
return AnimesPage(animeList, position + 36 < parsed.total)
|
return AnimesPage(animeList, position + 36 < parsed.total)
|
||||||
@ -103,7 +111,7 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun searchAnimeParse(response: Response): AnimesPage {
|
override fun searchAnimeParse(response: Response): AnimesPage {
|
||||||
val bod = response.body.string()
|
val bod = response.use { it.body.string() }
|
||||||
val total: Int
|
val total: Int
|
||||||
val items =
|
val items =
|
||||||
if (response.request.url.encodedPath.contains("search")) {
|
if (response.request.url.encodedPath.contains("search")) {
|
||||||
@ -125,6 +133,43 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
|
|
||||||
// =========================== Anime Details ============================
|
// =========================== Anime Details ============================
|
||||||
|
|
||||||
|
// Function to fetch anime status using AniList GraphQL API ispired by OppaiStream.kt
|
||||||
|
private fun fetchStatusByTitle(title: String): Int {
|
||||||
|
val query = """
|
||||||
|
query {
|
||||||
|
Media(search: "$title", isAdult: false, type: ANIME) {
|
||||||
|
id
|
||||||
|
idMal
|
||||||
|
title {
|
||||||
|
romaji
|
||||||
|
native
|
||||||
|
english
|
||||||
|
}
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
val requestBody = FormBody.Builder()
|
||||||
|
.add("query", query)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val response = noTokenClient.newCall(
|
||||||
|
POST("https://graphql.anilist.co", body = requestBody),
|
||||||
|
).execute().use { it.body.string() }
|
||||||
|
|
||||||
|
val responseParsed = json.decodeFromString<AnilistResult>(response)
|
||||||
|
|
||||||
|
return when (responseParsed.data.media?.status) {
|
||||||
|
"FINISHED" -> SAnime.COMPLETED
|
||||||
|
"RELEASING" -> SAnime.ONGOING
|
||||||
|
"NOT_YET_RELEASED" -> SAnime.LICENSED
|
||||||
|
"CANCELLED" -> SAnime.CANCELLED
|
||||||
|
"HIATUS" -> SAnime.ON_HIATUS
|
||||||
|
else -> SAnime.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
|
override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
|
||||||
val mediaId = json.decodeFromString<LinkData>(anime.url)
|
val mediaId = json.decodeFromString<LinkData>(anime.url)
|
||||||
val resp = client.newCall(
|
val resp = client.newCall(
|
||||||
@ -133,17 +178,10 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
} else {
|
} else {
|
||||||
GET("$crApiUrl/cms/movie_listings/${mediaId.id}?locale=en-US")
|
GET("$crApiUrl/cms/movie_listings/${mediaId.id}?locale=en-US")
|
||||||
},
|
},
|
||||||
).execute()
|
).execute().use { it.body.string() }
|
||||||
val info = json.decodeFromString<AnimeResult>(resp.body.string())
|
val info = json.decodeFromString<AnimeResult>(resp)
|
||||||
return Observable.just(
|
return Observable.just(
|
||||||
anime.apply {
|
info.data.first().toSAnimeOrNull(anime) ?: anime,
|
||||||
author = info.data.first().content_provider
|
|
||||||
status = SAnime.COMPLETED
|
|
||||||
if (genre.isNullOrBlank()) {
|
|
||||||
genre =
|
|
||||||
info.data.first().genres?.joinToString { gen -> gen.replaceFirstChar { it.uppercase() } }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +199,7 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||||
val seasons = json.decodeFromString<SeasonResult>(response.body.string())
|
val seasons = json.decodeFromString<SeasonResult>(response.use { it.body.string() })
|
||||||
val series = response.request.url.encodedPath.contains("series/")
|
val series = response.request.url.encodedPath.contains("series/")
|
||||||
val chunkSize = Runtime.getRuntime().availableProcessors()
|
val chunkSize = Runtime.getRuntime().availableProcessors()
|
||||||
return if (series) {
|
return if (series) {
|
||||||
@ -176,7 +214,7 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
seasons.data.mapIndexed { index, movie ->
|
seasons.data.mapIndexed { index, movie ->
|
||||||
SEpisode.create().apply {
|
SEpisode.create().apply {
|
||||||
url = EpisodeData(listOf(Pair(movie.id, ""))).toJsonString()
|
url = EpisodeData(listOf(Pair(movie.id, ""))).toJsonString()
|
||||||
name = "Movie"
|
name = "Movie ${index + 1}"
|
||||||
episode_number = (index + 1).toFloat()
|
episode_number = (index + 1).toFloat()
|
||||||
date_upload = movie.date?.let(::parseDate) ?: 0L
|
date_upload = movie.date?.let(::parseDate) ?: 0L
|
||||||
}
|
}
|
||||||
@ -185,10 +223,9 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getEpisodes(seasonData: SeasonResult.Season): List<SEpisode> {
|
private fun getEpisodes(seasonData: SeasonResult.Season): List<SEpisode> {
|
||||||
val episodeResp =
|
val body =
|
||||||
client.newCall(GET("$crApiUrl/cms/seasons/${seasonData.id}/episodes"))
|
client.newCall(GET("$crApiUrl/cms/seasons/${seasonData.id}/episodes"))
|
||||||
.execute()
|
.execute().use { it.body.string() }
|
||||||
val body = episodeResp.body.string()
|
|
||||||
val episodes = json.decodeFromString<EpisodeResult>(body)
|
val episodes = json.decodeFromString<EpisodeResult>(body)
|
||||||
|
|
||||||
return episodes.data.sortedBy { it.episode_number }.mapNotNull EpisodeMap@{ ep ->
|
return episodes.data.sortedBy { it.episode_number }.mapNotNull EpisodeMap@{ ep ->
|
||||||
@ -246,8 +283,8 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
|
|
||||||
private fun extractVideo(media: Pair<String, String>): List<Video> {
|
private fun extractVideo(media: Pair<String, String>): List<Video> {
|
||||||
val (mediaId, aud) = media
|
val (mediaId, aud) = media
|
||||||
val response = client.newCall(getVideoRequest(mediaId)).execute()
|
val response = client.newCall(getVideoRequest(mediaId)).execute().use { it.body.string() }
|
||||||
val streams = json.decodeFromString<VideoStreams>(response.body.string())
|
val streams = json.decodeFromString<VideoStreams>(response)
|
||||||
|
|
||||||
val subLocale = preferences.getString(PREF_SUB_KEY, PREF_SUB_DEFAULT)!!.getLocale()
|
val subLocale = preferences.getString(PREF_SUB_KEY, PREF_SUB_DEFAULT)!!.getLocale()
|
||||||
val subsList = runCatching {
|
val subsList = runCatching {
|
||||||
@ -276,7 +313,7 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
runCatching {
|
runCatching {
|
||||||
val playlist = client.newCall(GET(stream.url)).execute()
|
val playlist = client.newCall(GET(stream.url)).execute()
|
||||||
if (playlist.code != 200) return@parallelMap null
|
if (playlist.code != 200) return@parallelMap null
|
||||||
playlist.body.string().substringAfter("#EXT-X-STREAM-INF:")
|
playlist.use { it.body.string() }.substringAfter("#EXT-X-STREAM-INF:")
|
||||||
.split("#EXT-X-STREAM-INF:").map {
|
.split("#EXT-X-STREAM-INF:").map {
|
||||||
val hardsub = stream.hardsub_locale.let { hs ->
|
val hardsub = stream.hardsub_locale.let { hs ->
|
||||||
if (hs.isNotBlank()) " - HardSub: $hs" else ""
|
if (hs.isNotBlank()) " - HardSub: $hs" else ""
|
||||||
@ -340,6 +377,14 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
Pair("sv-SE", "Swedish"),
|
Pair("sv-SE", "Swedish"),
|
||||||
Pair("zh-CN", "Chinese (PRC)"),
|
Pair("zh-CN", "Chinese (PRC)"),
|
||||||
Pair("zh-HK", "Chinese (Hong Kong)"),
|
Pair("zh-HK", "Chinese (Hong Kong)"),
|
||||||
|
Pair("zh-TW", "Chinese (Taiwan)"),
|
||||||
|
Pair("ca-ES", "Català"),
|
||||||
|
Pair("id-ID", "Bahasa Indonesia"),
|
||||||
|
Pair("ms-MY", "Bahasa Melayu"),
|
||||||
|
Pair("ta-IN", "Tamil"),
|
||||||
|
Pair("te-IN", "Telugu"),
|
||||||
|
Pair("th-TH", "Thai"),
|
||||||
|
Pair("vi-VN", "Vietnamese"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun LinkData.toJsonString(): String {
|
private fun LinkData.toJsonString(): String {
|
||||||
@ -355,55 +400,69 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
.getOrNull() ?: 0L
|
.getOrNull() ?: 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Anime.toSAnimeOrNull() = runCatching { toSAnime() }.getOrNull()
|
private fun Anime.toSAnimeOrNull(anime: SAnime? = null) =
|
||||||
|
runCatching { toSAnime(anime) }.getOrNull()
|
||||||
|
|
||||||
private fun Anime.toSAnime(): SAnime =
|
private fun Anime.toSAnime(anime: SAnime? = null): SAnime =
|
||||||
SAnime.create().apply {
|
SAnime.create().apply {
|
||||||
title = this@toSAnime.title
|
title = this@toSAnime.title
|
||||||
thumbnail_url = images.poster_tall?.getOrNull(0)?.thirdLast()?.source
|
thumbnail_url = images.poster_tall?.getOrNull(0)?.thirdLast()?.source
|
||||||
?: images.poster_tall?.getOrNull(0)?.last()?.source
|
?: images.poster_tall?.getOrNull(0)?.last()?.source
|
||||||
url = LinkData(id, type!!).toJsonString()
|
url = anime?.url ?: LinkData(id, type!!).toJsonString()
|
||||||
genre = series_metadata?.genres?.joinToString()
|
genre = anime?.genre ?: (series_metadata?.genres ?: movie_metadata?.genres ?: genres)
|
||||||
?: movie_metadata?.genres?.joinToString() ?: ""
|
?.joinToString { gen -> gen.replaceFirstChar { it.uppercase() } }
|
||||||
status = SAnime.COMPLETED
|
status = if (anime != null) fetchStatusByTitle(this@toSAnime.title) else SAnime.UNKNOWN
|
||||||
var desc = this@toSAnime.description + "\n"
|
author = content_provider
|
||||||
desc += "\nLanguage:" +
|
description = anime?.description ?: StringBuilder().apply {
|
||||||
(
|
appendLine(this@toSAnime.description)
|
||||||
if (series_metadata?.subtitle_locales?.any() == true ||
|
appendLine()
|
||||||
movie_metadata?.subtitle_locales?.any() == true ||
|
|
||||||
series_metadata?.is_subbed == true
|
append("Language:")
|
||||||
) {
|
if ((
|
||||||
" Sub"
|
subtitle_locales ?: (
|
||||||
} else {
|
series_metadata
|
||||||
""
|
?: movie_metadata
|
||||||
}
|
)?.subtitle_locales
|
||||||
) +
|
)?.any() == true ||
|
||||||
(
|
(series_metadata ?: movie_metadata)?.is_subbed == true ||
|
||||||
if (series_metadata?.audio_locales?.size ?: 0 > 1 ||
|
is_subbed == true
|
||||||
movie_metadata?.is_dubbed == true
|
) {
|
||||||
) {
|
append(" Sub")
|
||||||
" Dub"
|
}
|
||||||
} else {
|
if (((series_metadata?.audio_locales ?: audio_locales)?.size ?: 0) > 1 ||
|
||||||
""
|
(series_metadata ?: movie_metadata)?.is_dubbed == true ||
|
||||||
}
|
is_dubbed == true
|
||||||
)
|
) {
|
||||||
desc += "\nMaturity Ratings: " +
|
append(" Dub")
|
||||||
(
|
}
|
||||||
series_metadata?.maturity_ratings?.joinToString()
|
appendLine()
|
||||||
?: movie_metadata?.maturity_ratings?.joinToString() ?: ""
|
|
||||||
)
|
append("Maturity Ratings: ")
|
||||||
desc += if (series_metadata?.is_simulcast == true) "\nSimulcast" else ""
|
appendLine(
|
||||||
desc += "\n\nAudio: " + (
|
((series_metadata ?: movie_metadata)?.maturity_ratings ?: maturity_ratings)
|
||||||
series_metadata?.audio_locales?.sortedBy { it.getLocale() }
|
?.joinToString() ?: "-",
|
||||||
?.joinToString { it.getLocale() } ?: ""
|
|
||||||
)
|
)
|
||||||
desc += "\n\nSubs: " + (
|
if (series_metadata?.is_simulcast == true) appendLine("Simulcast")
|
||||||
series_metadata?.subtitle_locales?.sortedBy { it.getLocale() }
|
appendLine()
|
||||||
?.joinToString { it.getLocale() }
|
|
||||||
?: movie_metadata?.subtitle_locales?.sortedBy { it.getLocale() }
|
append("Audio: ")
|
||||||
?.joinToString { it.getLocale() } ?: ""
|
appendLine(
|
||||||
|
(series_metadata?.audio_locales ?: audio_locales ?: listOf(audio_locale ?: "-"))
|
||||||
|
.sortedBy { it.getLocale() }
|
||||||
|
.joinToString { it.getLocale() },
|
||||||
)
|
)
|
||||||
description = desc
|
appendLine()
|
||||||
|
|
||||||
|
append("Subs: ")
|
||||||
|
append(
|
||||||
|
(
|
||||||
|
subtitle_locales ?: series_metadata?.subtitle_locales
|
||||||
|
?: movie_metadata?.subtitle_locales
|
||||||
|
)
|
||||||
|
?.sortedBy { it.getLocale() }
|
||||||
|
?.joinToString { it.getLocale() },
|
||||||
|
)
|
||||||
|
}.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun List<Video>.sort(): List<Video> {
|
override fun List<Video>.sort(): List<Video> {
|
||||||
@ -506,15 +565,23 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
this.apply {
|
this.apply {
|
||||||
key = PREF_USE_LOCAL_TOKEN_KEY
|
key = PREF_USE_LOCAL_TOKEN_KEY
|
||||||
title = PREF_USE_LOCAL_TOKEN_TITLE
|
title = PREF_USE_LOCAL_TOKEN_TITLE
|
||||||
summary = runBlocking {
|
mainScope.launch(Dispatchers.IO) {
|
||||||
withContext(Dispatchers.IO) { getTokenDetail() }
|
getTokenDetail().let {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
summary = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setDefaultValue(false)
|
setDefaultValue(false)
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
val new = newValue as Boolean
|
val new = newValue as Boolean
|
||||||
preferences.edit().putBoolean(key, new).commit().also {
|
preferences.edit().putBoolean(key, new).commit().also {
|
||||||
summary = runBlocking {
|
mainScope.launch(Dispatchers.IO) {
|
||||||
withContext(Dispatchers.IO) { getTokenDetail(true) }
|
getTokenDetail(true).let {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
summary = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,12 +596,12 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getTokenDetail(force: Boolean = false): String {
|
private fun getTokenDetail(force: Boolean = false): String {
|
||||||
return try {
|
return runCatching {
|
||||||
val storedToken = tokenInterceptor.getAccessToken(force)
|
val storedToken = tokenInterceptor.getAccessToken(force)
|
||||||
"Token location: " + storedToken.bucket?.substringAfter("/")?.substringBefore("/")
|
"Token location: " + storedToken.bucket?.substringAfter("/")?.substringBefore("/")
|
||||||
} catch (e: Exception) {
|
}.getOrElse {
|
||||||
tokenInterceptor.removeToken()
|
tokenInterceptor.removeToken()
|
||||||
"Error: ${e.localizedMessage ?: "Something Went Wrong"}"
|
"Error: ${it.localizedMessage ?: "Something Went Wrong"}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user