mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Avoid using global scope where appropriate
Also fixes the crash in tracking when an exception is thrown during a refresh.
This commit is contained in:
		@@ -8,8 +8,7 @@ import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.jsonMime
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
import kotlinx.serialization.json.buildJsonObject
 | 
			
		||||
import kotlinx.serialization.json.contentOrNull
 | 
			
		||||
@@ -30,7 +29,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
    private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 | 
			
		||||
 | 
			
		||||
    suspend fun addLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val query =
 | 
			
		||||
                """
 | 
			
		||||
            |mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus) {
 | 
			
		||||
@@ -65,7 +64,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun updateLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val query =
 | 
			
		||||
                """
 | 
			
		||||
            |mutation UpdateManga(${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}score: Int) {
 | 
			
		||||
@@ -92,7 +91,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun search(search: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val query =
 | 
			
		||||
                """
 | 
			
		||||
            |query Search(${'$'}query: String) {
 | 
			
		||||
@@ -143,7 +142,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun findLibManga(track: Track, userid: Int): Track? {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val query =
 | 
			
		||||
                """
 | 
			
		||||
            |query (${'$'}id: Int!, ${'$'}manga_id: Int!) {
 | 
			
		||||
@@ -209,7 +208,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getCurrentUser(): Pair<Int, String> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val query =
 | 
			
		||||
                """
 | 
			
		||||
            |query User {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,7 @@ import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.serialization.decodeFromString
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
@@ -33,7 +32,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 | 
			
		||||
 | 
			
		||||
    suspend fun addLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val body = FormBody.Builder()
 | 
			
		||||
                .add("rating", track.score.toInt().toString())
 | 
			
		||||
                .add("status", track.toBangumiStatus())
 | 
			
		||||
@@ -45,7 +44,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun updateLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            // read status update
 | 
			
		||||
            val sbody = FormBody.Builder()
 | 
			
		||||
                .add("status", track.toBangumiStatus())
 | 
			
		||||
@@ -69,7 +68,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun search(search: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}"
 | 
			
		||||
                .toUri()
 | 
			
		||||
                .buildUpon()
 | 
			
		||||
@@ -117,7 +116,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun findLibManga(track: Track): Track? {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            authClient.newCall(GET("$apiUrl/subject/${track.media_id}"))
 | 
			
		||||
                .await()
 | 
			
		||||
                .parseAs<JsonObject>()
 | 
			
		||||
@@ -126,7 +125,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun statusLibManga(track: Track): Track? {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val urlUserRead = "$apiUrl/collection/${track.media_id}"
 | 
			
		||||
            val requestUserRead = Request.Builder()
 | 
			
		||||
                .url(urlUserRead)
 | 
			
		||||
@@ -147,7 +146,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun accessToken(code: String): OAuth {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            client.newCall(accessTokenRequest(code))
 | 
			
		||||
                .await()
 | 
			
		||||
                .parseAs()
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,7 @@ import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.jsonMime
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
import kotlinx.serialization.json.buildJsonObject
 | 
			
		||||
import kotlinx.serialization.json.int
 | 
			
		||||
@@ -31,7 +30,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 | 
			
		||||
 | 
			
		||||
    suspend fun addLibManga(track: Track, userId: String): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val data = buildJsonObject {
 | 
			
		||||
                putJsonObject("data") {
 | 
			
		||||
                    put("type", "libraryEntries")
 | 
			
		||||
@@ -76,7 +75,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun updateLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val data = buildJsonObject {
 | 
			
		||||
                putJsonObject("data") {
 | 
			
		||||
                    put("type", "libraryEntries")
 | 
			
		||||
@@ -110,7 +109,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun search(query: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            authClient.newCall(GET(algoliaKeyUrl))
 | 
			
		||||
                .await()
 | 
			
		||||
                .parseAs<JsonObject>()
 | 
			
		||||
@@ -122,7 +121,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun algoliaSearch(key: String, query: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val jsonObject = buildJsonObject {
 | 
			
		||||
                put("params", "query=$query$algoliaFilter")
 | 
			
		||||
            }
 | 
			
		||||
@@ -151,7 +150,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun findLibManga(track: Track, userId: String): Track? {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "${baseUrl}library-entries".toUri().buildUpon()
 | 
			
		||||
                .encodedQuery("filter[manga_id]=${track.media_id}&filter[user_id]=$userId")
 | 
			
		||||
                .appendQueryParameter("include", "manga")
 | 
			
		||||
@@ -172,7 +171,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getLibManga(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "${baseUrl}library-entries".toUri().buildUpon()
 | 
			
		||||
                .encodedQuery("filter[id]=${track.media_id}")
 | 
			
		||||
                .appendQueryParameter("include", "manga")
 | 
			
		||||
@@ -193,7 +192,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun login(username: String, password: String): OAuth {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val formBody: RequestBody = FormBody.Builder()
 | 
			
		||||
                .add("username", username)
 | 
			
		||||
                .add("password", password)
 | 
			
		||||
@@ -208,7 +207,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getCurrentUser(): String {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "${baseUrl}users".toUri().buildUpon()
 | 
			
		||||
                .encodedQuery("filter[self]=true")
 | 
			
		||||
                .build()
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,9 @@ import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import eu.kanade.tachiyomi.util.PkceUtil
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.coroutines.async
 | 
			
		||||
import kotlinx.coroutines.awaitAll
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
import kotlinx.serialization.json.boolean
 | 
			
		||||
import kotlinx.serialization.json.contentOrNull
 | 
			
		||||
@@ -33,7 +32,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 | 
			
		||||
 | 
			
		||||
    suspend fun getAccessToken(authCode: String): OAuth {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val formBody: RequestBody = FormBody.Builder()
 | 
			
		||||
                .add("client_id", clientId)
 | 
			
		||||
                .add("code", authCode)
 | 
			
		||||
@@ -47,7 +46,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getCurrentUser(): String {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val request = Request.Builder()
 | 
			
		||||
                .url("$baseApiUrl/users/@me")
 | 
			
		||||
                .get()
 | 
			
		||||
@@ -60,7 +59,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun search(query: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "$baseApiUrl/manga".toUri().buildUpon()
 | 
			
		||||
                .appendQueryParameter("q", query)
 | 
			
		||||
                .appendQueryParameter("nsfw", "true")
 | 
			
		||||
@@ -82,7 +81,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getMangaDetails(id: Int): TrackSearch {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "$baseApiUrl/manga".toUri().buildUpon()
 | 
			
		||||
                .appendPath(id.toString())
 | 
			
		||||
                .appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
 | 
			
		||||
@@ -113,7 +112,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getListItem(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val formBody: RequestBody = FormBody.Builder()
 | 
			
		||||
                .add("status", track.toMyAnimeListStatus() ?: "reading")
 | 
			
		||||
                .build()
 | 
			
		||||
@@ -129,7 +128,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun addItemToList(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val formBody: RequestBody = FormBody.Builder()
 | 
			
		||||
                .add("status", "reading")
 | 
			
		||||
                .add("score", "0")
 | 
			
		||||
@@ -146,7 +145,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun updateItem(track: Track): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val formBody: RequestBody = FormBody.Builder()
 | 
			
		||||
                .add("status", track.toMyAnimeListStatus() ?: "reading")
 | 
			
		||||
                .add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
 | 
			
		||||
@@ -188,7 +187,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun findListItems(query: String, offset: Int = 0): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val json = getListPage(offset)
 | 
			
		||||
            val obj = json.jsonObject
 | 
			
		||||
 | 
			
		||||
@@ -215,7 +214,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun getListPage(offset: Int): JsonObject {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon()
 | 
			
		||||
                .appendQueryParameter("fields", "list_status")
 | 
			
		||||
                .appendQueryParameter("limit", listPaginationAmount.toString())
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,8 @@ import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.jsonMime
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import kotlinx.serialization.json.JsonArray
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
import kotlinx.serialization.json.buildJsonObject
 | 
			
		||||
@@ -30,7 +29,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
    private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 | 
			
		||||
 | 
			
		||||
    suspend fun addLibManga(track: Track, user_id: String): Track {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val payload = buildJsonObject {
 | 
			
		||||
                putJsonObject("user_rate") {
 | 
			
		||||
                    put("user_id", user_id)
 | 
			
		||||
@@ -54,7 +53,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
    suspend fun updateLibManga(track: Track, user_id: String): Track = addLibManga(track, user_id)
 | 
			
		||||
 | 
			
		||||
    suspend fun search(search: String): List<TrackSearch> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val url = "$apiUrl/mangas".toUri().buildUpon()
 | 
			
		||||
                .appendQueryParameter("order", "popularity")
 | 
			
		||||
                .appendQueryParameter("search", search)
 | 
			
		||||
@@ -98,7 +97,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun findLibManga(track: Track, user_id: String): Track? {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            val urlMangas = "$apiUrl/mangas".toUri().buildUpon()
 | 
			
		||||
                .appendPath(track.media_id.toString())
 | 
			
		||||
                .build()
 | 
			
		||||
@@ -138,7 +137,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun accessToken(code: String): OAuth {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            client.newCall(accessTokenRequest(code))
 | 
			
		||||
                .await()
 | 
			
		||||
                .parseAs()
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,7 @@ import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class GithubUpdateChecker {
 | 
			
		||||
@@ -23,7 +22,7 @@ class GithubUpdateChecker {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun checkForUpdate(): UpdateResult {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            networkService.client
 | 
			
		||||
                .newCall(GET("https://api.github.com/repos/$repo/releases/latest"))
 | 
			
		||||
                .await()
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,7 @@ import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import eu.kanade.tachiyomi.network.await
 | 
			
		||||
import eu.kanade.tachiyomi.network.parseAs
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withIOContext
 | 
			
		||||
import kotlinx.serialization.json.JsonArray
 | 
			
		||||
import kotlinx.serialization.json.int
 | 
			
		||||
import kotlinx.serialization.json.jsonObject
 | 
			
		||||
@@ -24,7 +23,7 @@ internal class ExtensionGithubApi {
 | 
			
		||||
    private val preferences: PreferencesHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    suspend fun findExtensions(): List<Extension.Available> {
 | 
			
		||||
        return withContext(Dispatchers.IO) {
 | 
			
		||||
        return withIOContext {
 | 
			
		||||
            networkService.client
 | 
			
		||||
                .newCall(GET("${REPO_URL_PREFIX}index.min.json"))
 | 
			
		||||
                .await()
 | 
			
		||||
 
 | 
			
		||||
@@ -55,13 +55,13 @@ class SearchPresenter(
 | 
			
		||||
 | 
			
		||||
        replacingMangaRelay.call(true)
 | 
			
		||||
 | 
			
		||||
        launchIO {
 | 
			
		||||
        presenterScope.launchIO {
 | 
			
		||||
            val chapters = source.getChapterList(manga.toMangaInfo())
 | 
			
		||||
                .map { it.toSChapter() }
 | 
			
		||||
 | 
			
		||||
            migrateMangaInternal(source, chapters, prevManga, manga, replace)
 | 
			
		||||
        }.invokeOnCompletion {
 | 
			
		||||
            launchUI { replacingMangaRelay.call(false) }
 | 
			
		||||
            presenterScope.launchUI { replacingMangaRelay.call(false) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
 | 
			
		||||
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchIO
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withUIContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.removeCovers
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.asFlow
 | 
			
		||||
@@ -213,12 +213,12 @@ open class BrowseSourcePresenter(
 | 
			
		||||
     * @param mangas the list of manga to initialize.
 | 
			
		||||
     */
 | 
			
		||||
    fun initializeMangas(mangas: List<Manga>) {
 | 
			
		||||
        launchIO {
 | 
			
		||||
        presenterScope.launchIO {
 | 
			
		||||
            mangas.asFlow()
 | 
			
		||||
                .filter { it.thumbnail_url == null && !it.initialized }
 | 
			
		||||
                .map { getMangaDetails(it) }
 | 
			
		||||
                .onEach {
 | 
			
		||||
                    launchUI {
 | 
			
		||||
                    withUIContext {
 | 
			
		||||
                        @Suppress("DEPRECATION")
 | 
			
		||||
                        view?.onMangaInitialized(it)
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -292,7 +292,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
 | 
			
		||||
            setSelectedNavItem(startScreenId)
 | 
			
		||||
        } else if (shouldHandleExitConfirmation()) {
 | 
			
		||||
            // Exit confirmation (resets after 2 seconds)
 | 
			
		||||
            launchUI { resetExitConfirmation() }
 | 
			
		||||
            lifecycleScope.launchUI { resetExitConfirmation() }
 | 
			
		||||
        } else if (backstackSize == 1 || !router.handleBack()) {
 | 
			
		||||
            // Regular back
 | 
			
		||||
            super.onBackPressed()
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
 | 
			
		||||
import eu.kanade.tachiyomi.util.isLocal
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.await
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchIO
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withUIContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.prepUpdateCover
 | 
			
		||||
import eu.kanade.tachiyomi.util.removeCovers
 | 
			
		||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
 | 
			
		||||
@@ -161,7 +161,7 @@ class MangaPresenter(
 | 
			
		||||
     */
 | 
			
		||||
    fun fetchMangaFromSource(manualFetch: Boolean = false) {
 | 
			
		||||
        if (fetchMangaJob?.isActive == true) return
 | 
			
		||||
        fetchMangaJob = launchIO {
 | 
			
		||||
        fetchMangaJob = presenterScope.launchIO {
 | 
			
		||||
            try {
 | 
			
		||||
                val networkManga = source.getMangaDetails(manga.toMangaInfo())
 | 
			
		||||
                val sManga = networkManga.toSManga()
 | 
			
		||||
@@ -170,9 +170,9 @@ class MangaPresenter(
 | 
			
		||||
                manga.initialized = true
 | 
			
		||||
                db.insertManga(manga).await()
 | 
			
		||||
 | 
			
		||||
                launchUI { view?.onFetchMangaInfoDone() }
 | 
			
		||||
                withUIContext { view?.onFetchMangaInfoDone() }
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                launchUI { view?.onFetchMangaInfoError(e) }
 | 
			
		||||
                withUIContext { view?.onFetchMangaInfoError(e) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -360,9 +360,9 @@ class MangaPresenter(
 | 
			
		||||
                    downloadNewChapters(newChapters)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                launchUI { view?.onFetchChaptersDone() }
 | 
			
		||||
                withUIContext { view?.onFetchChaptersDone() }
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                launchUI { view?.onFetchChaptersError(e) }
 | 
			
		||||
                withUIContext { view?.onFetchChaptersError(e) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,12 @@ import eu.kanade.tachiyomi.data.track.TrackService
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.await
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchIO
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withUIContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.async
 | 
			
		||||
import kotlinx.coroutines.awaitAll
 | 
			
		||||
import kotlinx.coroutines.supervisorScope
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
@@ -59,20 +60,22 @@ class TrackPresenter(
 | 
			
		||||
    fun refresh() {
 | 
			
		||||
        refreshJob?.cancel()
 | 
			
		||||
        refreshJob = launchIO {
 | 
			
		||||
            try {
 | 
			
		||||
                trackList
 | 
			
		||||
                    .filter { it.track != null }
 | 
			
		||||
                    .map {
 | 
			
		||||
                        async {
 | 
			
		||||
                            val track = it.service.refresh(it.track!!)
 | 
			
		||||
                            db.insertTrack(track).await()
 | 
			
		||||
            supervisorScope {
 | 
			
		||||
                try {
 | 
			
		||||
                    trackList
 | 
			
		||||
                        .filter { it.track != null }
 | 
			
		||||
                        .map {
 | 
			
		||||
                            async {
 | 
			
		||||
                                val track = it.service.refresh(it.track!!)
 | 
			
		||||
                                db.insertTrack(track).await()
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    .awaitAll()
 | 
			
		||||
                        .awaitAll()
 | 
			
		||||
 | 
			
		||||
                view?.onRefreshDone()
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                view?.onRefreshError(e)
 | 
			
		||||
                    withUIContext { view?.onRefreshDone() }
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
                    withUIContext { view?.onRefreshError(e) }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -82,9 +85,9 @@ class TrackPresenter(
 | 
			
		||||
        searchJob = launchIO {
 | 
			
		||||
            try {
 | 
			
		||||
                val results = service.search(query)
 | 
			
		||||
                launchUI { view?.onSearchResults(results) }
 | 
			
		||||
                withUIContext { view?.onSearchResults(results) }
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                launchUI { view?.onSearchResultsError(e) }
 | 
			
		||||
                withUIContext { view?.onSearchResultsError(e) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -97,7 +100,7 @@ class TrackPresenter(
 | 
			
		||||
                    service.bind(item)
 | 
			
		||||
                    db.insertTrack(item).await()
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
                    launchUI { context.toast(e.message) }
 | 
			
		||||
                    withUIContext { context.toast(e.message) }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -114,9 +117,9 @@ class TrackPresenter(
 | 
			
		||||
            try {
 | 
			
		||||
                service.update(track)
 | 
			
		||||
                db.insertTrack(track).await()
 | 
			
		||||
                view?.onRefreshDone()
 | 
			
		||||
                withUIContext { view?.onRefreshDone() }
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                launchUI { view?.onRefreshError(e) }
 | 
			
		||||
                withUIContext { view?.onRefreshError(e) }
 | 
			
		||||
 | 
			
		||||
                // Restart on error to set old values
 | 
			
		||||
                fetchTrackings()
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackService
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchIO
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.withUIContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
@@ -46,11 +46,11 @@ class TrackLoginDialog(
 | 
			
		||||
            try {
 | 
			
		||||
                service.login(user, pass)
 | 
			
		||||
                dialog?.dismiss()
 | 
			
		||||
                launchUI { view?.context?.toast(R.string.login_success) }
 | 
			
		||||
                withUIContext { view?.context?.toast(R.string.login_success) }
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                binding?.login?.progress = -1
 | 
			
		||||
                binding?.login?.setText(R.string.unknown_error)
 | 
			
		||||
                launchUI { e.message?.let { view?.context?.toast(it) } }
 | 
			
		||||
                withUIContext { e.message?.let { view?.context?.toast(it) } }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.GlobalScope
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
 | 
			
		||||
fun launchUI(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
    GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block)
 | 
			
		||||
@@ -15,3 +16,13 @@ fun launchIO(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
 | 
			
		||||
fun launchNow(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
    GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED, block)
 | 
			
		||||
 | 
			
		||||
fun CoroutineScope.launchUI(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
    launch(Dispatchers.Main, block = block)
 | 
			
		||||
 | 
			
		||||
fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
    launch(Dispatchers.IO, block = block)
 | 
			
		||||
 | 
			
		||||
suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block)
 | 
			
		||||
 | 
			
		||||
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.IO, block)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user