Deal with SY for the coroutine function changes
This commit is contained in:
@@ -21,6 +21,7 @@ import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||
import exh.metadata.metadata.base.insertFlatMetadata
|
||||
import exh.savedsearches.JsonSavedSearch
|
||||
import exh.util.cancellable
|
||||
import exh.util.executeOnIO
|
||||
import exh.util.jobScheduler
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
@@ -51,7 +52,7 @@ object DebugFunctions {
|
||||
|
||||
fun resetAgedFlagInEXHManga() {
|
||||
runBlocking {
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().await()
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
|
||||
|
||||
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
|
||||
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
|
||||
@@ -60,7 +61,7 @@ object DebugFunctions {
|
||||
}.toList()
|
||||
|
||||
allManga.forEach { manga ->
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
// remove age flag
|
||||
meta.aged = false
|
||||
db.insertFlatMetadata(meta.flatten()).await()
|
||||
@@ -74,7 +75,7 @@ object DebugFunctions {
|
||||
fun resetEHGalleriesForUpdater() {
|
||||
throttleManager.resetThrottle()
|
||||
runBlocking {
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().await()
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
|
||||
|
||||
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
|
||||
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
|
||||
@@ -104,7 +105,7 @@ object DebugFunctions {
|
||||
fun getEHMangaListWithAgedFlagInfo(): String {
|
||||
val galleries = mutableListOf(String())
|
||||
runBlocking {
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().await()
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
|
||||
|
||||
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
|
||||
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
|
||||
@@ -113,7 +114,7 @@ object DebugFunctions {
|
||||
}.toList()
|
||||
|
||||
allManga.forEach { manga ->
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
galleries += "Aged: ${meta.aged}\t Title: ${manga.title}"
|
||||
}
|
||||
}
|
||||
@@ -123,7 +124,7 @@ object DebugFunctions {
|
||||
fun countAgedFlagInEXHManga(): Int {
|
||||
var agedAmount = 0
|
||||
runBlocking {
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().await()
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().executeAsBlocking()
|
||||
|
||||
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
|
||||
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
|
||||
@@ -132,7 +133,7 @@ object DebugFunctions {
|
||||
}.toList()
|
||||
|
||||
allManga.forEach { manga ->
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
|
||||
if (meta.aged) {
|
||||
// remove age flag
|
||||
agedAmount++
|
||||
|
||||
@@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.util.lang.await
|
||||
import exh.util.executeOnIO
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -33,13 +33,13 @@ class EHentaiUpdateHelper(context: Context) {
|
||||
val chainsFlow = flowOf(chapters)
|
||||
.map { chapterList ->
|
||||
chapterList.flatMap { chapter ->
|
||||
db.getChapters(chapter.url).await().mapNotNull { it.manga_id }
|
||||
db.getChapters(chapter.url).executeOnIO().mapNotNull { it.manga_id }
|
||||
}.distinct()
|
||||
}
|
||||
.map { mangaIds ->
|
||||
mangaIds
|
||||
.mapNotNull { mangaId ->
|
||||
(db.getManga(mangaId).await() ?: return@mapNotNull null) to db.getChapters(mangaId).await()
|
||||
(db.getManga(mangaId).executeOnIO() ?: return@mapNotNull null) to db.getChapters(mangaId).executeOnIO()
|
||||
}
|
||||
.map {
|
||||
ChapterChain(it.first, it.second)
|
||||
|
||||
@@ -28,6 +28,7 @@ import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||
import exh.metadata.metadata.base.insertFlatMetadata
|
||||
import exh.util.cancellable
|
||||
import exh.util.executeOnIO
|
||||
import exh.util.jobScheduler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -136,7 +137,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||
val startTime = System.currentTimeMillis()
|
||||
|
||||
logger.d("Finding manga with metadata...")
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().await()
|
||||
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
|
||||
|
||||
logger.d("Filtering manga and raising metadata...")
|
||||
val curTime = System.currentTimeMillis()
|
||||
@@ -145,7 +146,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).await()
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()
|
||||
?: return@mapNotNull null
|
||||
|
||||
val raisedMeta = meta.raise<EHentaiSearchMetadata>()
|
||||
@@ -155,7 +156,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
val chapter = db.getChapters(manga.id!!).await().minByOrNull {
|
||||
val chapter = db.getChapters(manga.id!!).executeOnIO().minByOrNull {
|
||||
it.date_upload
|
||||
}
|
||||
|
||||
@@ -265,16 +266,16 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||
try {
|
||||
val updatedManga = source.getMangaDetails(manga.toMangaInfo())
|
||||
manga.copyFrom(updatedManga.toSManga())
|
||||
db.insertManga(manga).await()
|
||||
db.insertManga(manga).executeOnIO()
|
||||
|
||||
val newChapters = source.getChapterList(manga.toMangaInfo())
|
||||
.map { it.toSChapter() }
|
||||
|
||||
val (new, _) = syncChaptersWithSource(db, newChapters, manga, source) // Not suspending, but does block, maybe fix this?
|
||||
return new to db.getChapters(manga).await()
|
||||
return new to db.getChapters(manga).executeOnIO()
|
||||
} catch (t: Throwable) {
|
||||
if (t is EHentai.GalleryNotFoundException) {
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>()
|
||||
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>()
|
||||
if (meta != null) {
|
||||
// Age dead galleries
|
||||
logger.d("Aged %s - notfound", manga.id)
|
||||
|
||||
@@ -84,13 +84,13 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
|
||||
// Validate library state
|
||||
status.value = FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_verifying_library), context = context)
|
||||
val libraryManga = db.getLibraryMangas().await()
|
||||
val libraryManga = db.getLibraryMangas().executeOnIO()
|
||||
val seenManga = HashSet<Long>(libraryManga.size)
|
||||
libraryManga.forEach {
|
||||
if (it.source != EXH_SOURCE_ID && it.source != EH_SOURCE_ID) return@forEach
|
||||
|
||||
if (it.id in seenManga) {
|
||||
val inCategories = db.getCategoriesForManga(it).await()
|
||||
val inCategories = db.getCategoriesForManga(it).executeOnIO()
|
||||
status.value = FavoritesSyncStatus.BadLibraryState.MangaInMultipleCategories(it, inCategories, context)
|
||||
|
||||
logger.w(context.getString(R.string.favorites_sync_manga_multiple_categories_error, it.id))
|
||||
|
||||
@@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import exh.md.handlers.serializers.FollowPage
|
||||
import exh.md.handlers.serializers.FollowsIndividualSerializer
|
||||
import exh.md.handlers.serializers.FollowsPageSerializer
|
||||
@@ -17,8 +18,6 @@ import exh.md.utils.FollowStatus
|
||||
import exh.md.utils.MdUtil
|
||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||
import exh.util.floor
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.FormBody
|
||||
@@ -122,7 +121,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
title = manga.title
|
||||
mdUrl = manga.url
|
||||
thumbnail_url = manga.thumbnail_url
|
||||
follow_status = FollowStatus.fromInt(result.followType)?.int
|
||||
follow_status = FollowStatus.fromInt(result.followType).int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +129,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
* Change the status of a manga
|
||||
*/
|
||||
suspend fun updateFollowStatus(mangaID: String, followStatus: FollowStatus): Boolean {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val response: Response =
|
||||
if (followStatus == FollowStatus.UNFOLLOWED) {
|
||||
client.newCall(
|
||||
@@ -153,12 +152,12 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
.await()
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) { response.body?.string().isNullOrEmpty() }
|
||||
withIOContext { response.body?.string().isNullOrEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateReadingProgress(track: Track): Boolean {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val mangaID = MdUtil.getMangaId(track.tracking_url)
|
||||
val formBody = FormBody.Builder()
|
||||
.add("chapter", track.last_chapter_read.toString())
|
||||
@@ -178,12 +177,12 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
)
|
||||
).await().body?.close()
|
||||
|
||||
withContext(Dispatchers.IO) { response.body?.string().isNullOrEmpty() }
|
||||
withIOContext { response.body?.string().isNullOrEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateRating(track: Track): Boolean {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val mangaID = MdUtil.getMangaId(track.tracking_url)
|
||||
val response = client.newCall(
|
||||
GET(
|
||||
@@ -193,7 +192,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
)
|
||||
.await()
|
||||
|
||||
withContext(Dispatchers.IO) { response.body?.string().isNullOrEmpty() }
|
||||
withIOContext { response.body?.string().isNullOrEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +200,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
* fetch all manga from all possible pages
|
||||
*/
|
||||
suspend fun fetchAllFollows(forceHd: Boolean): List<Pair<SManga, MangaDexSearchMetadata>> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val listManga = mutableListOf<Pair<SManga, MangaDexSearchMetadata>>()
|
||||
val response = client.newCall(followsListRequest()).await()
|
||||
val mangasPage = followsParseMangaPage(response, forceHd)
|
||||
@@ -215,7 +214,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
}
|
||||
|
||||
suspend fun fetchTrackingInfo(url: String): Track {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val request = GET(
|
||||
"${MdUtil.apiUrl}${MdUtil.followsMangaApi}" + MdUtil.getMangaId(url),
|
||||
headers,
|
||||
|
||||
@@ -10,10 +10,9 @@ import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.model.toMangaInfo
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import eu.kanade.tachiyomi.util.lang.runAsObservable
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import exh.md.handlers.serializers.ApiCovers
|
||||
import exh.md.utils.MdUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
@@ -25,12 +24,12 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
|
||||
// TODO make use of this
|
||||
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<SChapter>> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val response = client.newCall(apiRequest(manga.toSManga())).await()
|
||||
val covers = getCovers(manga, forceLatestCovers)
|
||||
val parser = ApiMangaParser(lang)
|
||||
|
||||
val jsonData = withContext(Dispatchers.IO) { response.body!!.string() }
|
||||
val jsonData = withIOContext { response.body!!.string() }
|
||||
if (response.code != 200) {
|
||||
XLog.tag("MangaHandler").enableStackTrace(2).e("error from MangaDex with response code ${response.code} \n body: \n$jsonData")
|
||||
throw Exception("Error from MangaDex Response code ${response.code} ")
|
||||
@@ -55,7 +54,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
}
|
||||
|
||||
suspend fun getMangaIdFromChapterId(urlChapterId: String): Int {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val request = GET(MdUtil.apiUrl + MdUtil.newApiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK)
|
||||
val response = client.newCall(request).await()
|
||||
ApiMangaParser(lang).chapterParseForMangaId(response)
|
||||
@@ -63,7 +62,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
}
|
||||
|
||||
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long): MangaInfo {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val response = client.newCall(apiRequest(manga.toSManga())).await()
|
||||
val covers = getCovers(manga, forceLatestCovers)
|
||||
ApiMangaParser(lang).parseToManga(manga, response, covers, sourceId)
|
||||
@@ -100,7 +99,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
}
|
||||
|
||||
suspend fun fetchChapterList(manga: SManga): List<SChapter> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val response = client.newCall(apiRequest(manga)).await()
|
||||
ApiMangaParser(lang).chapterListParse(response)
|
||||
}
|
||||
@@ -115,7 +114,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
}
|
||||
|
||||
suspend fun fetchRandomMangaId(): String {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withIOContext {
|
||||
val response = client.newCall(randomMangaRequest()).await()
|
||||
ApiMangaParser(lang).randomMangaIdParse(response)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import exh.md.similar.sql.models.MangaSimilarImpl
|
||||
@@ -28,7 +29,6 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import okio.source
|
||||
@@ -149,7 +149,7 @@ class SimilarUpdateService(
|
||||
/**
|
||||
* Method that updates the similar database for manga
|
||||
*/
|
||||
private suspend fun updateSimilar() = withContext(Dispatchers.IO) {
|
||||
private suspend fun updateSimilar() = withIOContext {
|
||||
val response = client
|
||||
.newCall(GET(similarUrl))
|
||||
.await()
|
||||
@@ -157,7 +157,7 @@ class SimilarUpdateService(
|
||||
throw Exception("Error trying to download similar file")
|
||||
}
|
||||
val destinationFile = File(filesDir, "neko-similar.json")
|
||||
val buffer = withContext(Dispatchers.IO) { destinationFile.sink().buffer() }
|
||||
val buffer = withIOContext { destinationFile.sink().buffer() }
|
||||
|
||||
// write json to file
|
||||
response.body?.byteStream()?.source()?.use { input ->
|
||||
|
||||
@@ -8,15 +8,13 @@ import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SMangaImpl
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.NoResultsException
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
||||
import eu.kanade.tachiyomi.util.lang.asObservable
|
||||
import eu.kanade.tachiyomi.util.lang.runAsObservable
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import exh.log.maybeInjectEHLogger
|
||||
import exh.util.MangaType
|
||||
import exh.util.mangaType
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
@@ -32,6 +30,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
|
||||
@@ -55,7 +54,7 @@ class MyAnimeList : API("https://api.jikan.moe/v3/") {
|
||||
.toString()
|
||||
|
||||
val response = client.newCall(GET(apiUrl)).await()
|
||||
val body = withContext(Dispatchers.IO) { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val body = withIOContext { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val data = Json.decodeFromString<JsonObject>(body)
|
||||
val recommendations = data["recommendations"] as? JsonArray
|
||||
return recommendations?.filterIsInstance<JsonObject>()?.map { rec ->
|
||||
@@ -79,7 +78,7 @@ class MyAnimeList : API("https://api.jikan.moe/v3/") {
|
||||
.toString()
|
||||
|
||||
val response = client.newCall(GET(url)).await()
|
||||
val body = withContext(Dispatchers.IO) { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val body = withIOContext { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val data = Json.decodeFromString<JsonObject>(body)
|
||||
val results = data["results"] as? JsonArray
|
||||
if (results.isNullOrEmpty()) {
|
||||
@@ -167,7 +166,7 @@ class Anilist : API("https://graphql.anilist.co/") {
|
||||
val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
||||
|
||||
val response = client.newCall(POST(endpoint, body = payloadBody)).await()
|
||||
val body = withContext(Dispatchers.IO) { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val body = withIOContext { response.body?.string() } ?: throw Exception("Null Response")
|
||||
val data = Json.decodeFromString<JsonObject>(body)["data"] as? JsonObject ?: throw Exception("Unexpected response")
|
||||
|
||||
val media = data["Page"]?.jsonObject?.get("media")?.jsonArray
|
||||
@@ -203,7 +202,7 @@ open class RecommendsPager(
|
||||
private var preferredApi: API = API.MYANIMELIST
|
||||
) : Pager() {
|
||||
override fun requestNext(): Observable<MangasPage> {
|
||||
return flow {
|
||||
return runAsObservable({
|
||||
if (smart) preferredApi = if (manga.mangaType() != MangaType.TYPE_MANGA) API.ANILIST else preferredApi
|
||||
|
||||
val apiList = API_MAP.toList().sortedByDescending { it.first == preferredApi }
|
||||
@@ -223,19 +222,17 @@ open class RecommendsPager(
|
||||
.firstOrNull { it.isNotEmpty() }
|
||||
.orEmpty()
|
||||
|
||||
val page = MangasPage(recs, false)
|
||||
emit(page)
|
||||
}
|
||||
.onEach {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (it.mangas.isNotEmpty()) {
|
||||
onPageReceived(it)
|
||||
} else {
|
||||
throw NoResultsException()
|
||||
}
|
||||
}
|
||||
}.asObservable()
|
||||
MangasPage(recs, false)
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext {
|
||||
if (it.mangas.isNotEmpty()) {
|
||||
onPageReceived(it)
|
||||
} else {
|
||||
throw NoResultsException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.lang.await
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import exh.util.executeOnIO
|
||||
import info.debatty.java.stringsimilarity.NormalizedLevenshtein
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
@@ -170,11 +171,11 @@ class SmartSearchEngine(
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = db.getManga(sManga.url, sourceId).await()
|
||||
var localManga = db.getManga(sManga.url, sourceId).executeOnIO()
|
||||
if (localManga == null) {
|
||||
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
val result = db.insertManga(newManga).await()
|
||||
val result = db.insertManga(newManga).executeOnIO()
|
||||
newManga.id = result.insertedId()
|
||||
localManga = newManga
|
||||
}
|
||||
|
||||
@@ -7,29 +7,26 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.elvishew.xlog.XLog
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ConfiguringDialogController : DialogController() {
|
||||
private var materialDialog: MaterialDialog? = null
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
val scope = MainScope()
|
||||
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
if (savedViewState == null) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
scope.launchIO {
|
||||
try {
|
||||
EHConfigurator(activity!!).configureAll()
|
||||
launchUI {
|
||||
activity?.toast(activity?.getString(R.string.eh_settings_successfully_uploaded))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
launchUI {
|
||||
activity?.let {
|
||||
MaterialDialog(it)
|
||||
.title(R.string.eh_settings_configuration_failed)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package exh.ui.base
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
@@ -11,14 +12,13 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import nucleus.presenter.Presenter
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
open class CoroutinePresenter<V>(
|
||||
scope: CoroutineScope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
scope: CoroutineScope = MainScope()
|
||||
) : Presenter<V>(), CoroutineScope by scope {
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated("Use launchInView, Flow.inView, Flow.mapView")
|
||||
@@ -26,19 +26,19 @@ open class CoroutinePresenter<V>(
|
||||
return super.getView()
|
||||
}
|
||||
|
||||
fun launchInView(block: (CoroutineScope, V) -> Unit) = launch(Dispatchers.Main) {
|
||||
fun launchInView(block: (CoroutineScope, V) -> Unit) = launchUI {
|
||||
view?.let { block.invoke(this, it) }
|
||||
}
|
||||
|
||||
inline fun <F> Flow<F>.inView(crossinline block: (V, F) -> Unit) = onEach {
|
||||
withContext(Dispatchers.Main) {
|
||||
withUIContext {
|
||||
view?.let { view -> block(view, it) }
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <F, P> Flow<F>.mapView(crossinline block: (V, F) -> P): Flow<P> {
|
||||
return mapNotNull {
|
||||
withContext(Dispatchers.Main) {
|
||||
withUIContext {
|
||||
view?.let { view -> block(view, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.jakewharton.rxrelay.ReplayRelay
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import exh.GalleryAddEvent
|
||||
import exh.GalleryAdder
|
||||
import exh.util.trimOrNull
|
||||
@@ -14,7 +15,6 @@ import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
@@ -65,7 +65,7 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
|
||||
|
||||
splitGalleries.forEachIndexed { i, s ->
|
||||
ensureActive()
|
||||
val result = withContext(Dispatchers.IO) { galleryAdder.addGallery(context, s, true) }
|
||||
val result = withIOContext { galleryAdder.addGallery(context, s, true) }
|
||||
if (result is GalleryAddEvent.Success) {
|
||||
succeeded.add(s)
|
||||
} else {
|
||||
|
||||
@@ -21,12 +21,11 @@ import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
||||
import exh.source.DelegatedHttpSource
|
||||
import exh.util.melt
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
@@ -188,7 +187,7 @@ class BrowserActionActivity : AppCompatActivity() {
|
||||
currentLoopId = null
|
||||
validateCurrentLoopId = null
|
||||
XLog.tag("BrowserActionActivity").enableStackTrace(2).e(IllegalStateException("Captcha solve failure!"))
|
||||
withContext(Dispatchers.Main) {
|
||||
withUIContext {
|
||||
binding.webview.evaluateJavascript(SOLVE_UI_SCRIPT_HIDE, null)
|
||||
MaterialDialog(this@BrowserActionActivity)
|
||||
.title(R.string.captcha_solve_failure)
|
||||
|
||||
@@ -12,12 +12,12 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.plus
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartSearchBinding, SmartSearchPresenter>() {
|
||||
@@ -52,7 +52,7 @@ class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartS
|
||||
.onEach { results ->
|
||||
if (results is SmartSearchPresenter.SearchResults.Found) {
|
||||
val transaction = MangaController(results.manga, true, smartSearchConfig).withFadeTransaction()
|
||||
withContext(Dispatchers.Main) {
|
||||
withUIContext {
|
||||
router.replaceTopController(transaction)
|
||||
}
|
||||
} else {
|
||||
@@ -63,7 +63,7 @@ class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartS
|
||||
}
|
||||
|
||||
val transaction = BrowseSourceController(source, smartSearchConfig.origTitle, smartSearchConfig).withFadeTransaction()
|
||||
withContext(Dispatchers.Main) {
|
||||
withUIContext {
|
||||
router.replaceTopController(transaction)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,9 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.util.lang.launchNow
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import exh.source.getMainSource
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@@ -37,7 +36,7 @@ class MangadexLogoutDialog(bundle: Bundle? = null) : DialogController(bundle) {
|
||||
.positiveButton(R.string.logout) {
|
||||
launchNow {
|
||||
source?.let { source ->
|
||||
val loggedOut = withContext(Dispatchers.IO) { source.logout() }
|
||||
val loggedOut = withIOContext { source.logout() }
|
||||
|
||||
if (loggedOut) {
|
||||
trackManager.mdList.logout()
|
||||
|
||||
Reference in New Issue
Block a user