diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index b775fd1e8..f65ac8099 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -50,7 +50,6 @@ import nl.adaptivity.xmlutil.serialization.XML import okhttp3.Response import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE import tachiyomi.core.metadata.comicinfo.ComicInfo -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.launchNow import tachiyomi.core.util.lang.withIOContext @@ -380,7 +379,7 @@ class Downloader( if (page.imageUrl.isNullOrEmpty()) { page.status = Page.State.LOAD_PAGE try { - page.imageUrl = download.source.fetchImageUrl(page).awaitSingle() + page.imageUrl = download.source.getImageUrl(page) } catch (e: Throwable) { page.status = Page.State.ERROR } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt index 6baabe493..c31c7401d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt @@ -54,7 +54,7 @@ import exh.util.nullIfBlank import exh.util.trimAll import exh.util.trimOrNull import exh.util.urlImportFetchSearchManga -import kotlinx.serialization.decodeFromString +import exh.util.urlImportFetchSearchMangaSuspend import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.add @@ -456,27 +456,44 @@ class EHentai( } private fun Observable.checkValid(): Observable = map { - if (exh && it.mangas.isEmpty() && preferences.igneousVal().get().equals("mystery", true)) { - throw Exception("Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu") - } else { - it - } + it.checkValid() } + private fun T.checkValid(): MangasPage = + if (exh && mangas.isEmpty() && preferences.igneousVal().get().equals("mystery", true)) { + throw Exception("Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu") + } else { + this + } + override fun fetchLatestUpdates(page: Int): Observable { - return super.fetchLatestUpdates(page).checkValid() + return super.fetchLatestUpdates(page).checkValid() + } + + override suspend fun getLatestUpdates(page: Int): MangasPage { + return super.getLatestUpdates(page).checkValid() } override fun fetchPopularManga(page: Int): Observable { - return super.fetchPopularManga(page).checkValid() + return super.fetchPopularManga(page).checkValid() + } + + override suspend fun getPopularManga(page: Int): MangasPage { + return super.getPopularManga(page).checkValid() } // Support direct URL importing override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters).checkValid() + super.fetchSearchManga(page, query, filters).checkValid() } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters).checkValid() + } + } + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val toplist = ToplistOption.values()[filters.firstNotNullOfOrNull { (it as? ToplistOptions)?.state } ?: 0] if (toplist != ToplistOption.NONE) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt index b8988f648..92a3d1ca3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt @@ -159,6 +159,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : return mangaHandler.getMangaFromChapterId(id)?.let { MdUtil.buildMangaUrl(it) } } + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int): Observable { val request = delegate.latestUpdatesRequest(page) val url = request.url.newBuilder() @@ -171,6 +172,16 @@ class MangaDex(delegate: HttpSource, val context: Context) : } } + override suspend fun getLatestUpdates(page: Int): MangasPage { + val request = delegate.latestUpdatesRequest(page) + val url = request.url.newBuilder() + .removeAllQueryParameters("includeFutureUpdates") + .build() + + val response = client.newCall(request.newBuilder().url(url).build()).awaitSuccess() + return delegate.latestUpdatesParse(response) + } + @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails")) override fun fetchMangaDetails(manga: SManga): Observable { return mangaHandler.fetchMangaDetailsObservable(manga, id) @@ -198,22 +209,25 @@ class MangaDex(delegate: HttpSource, val context: Context) : return pageHandler.fetchPageList(chapter, usePort443Only(), dataSaver(), delegate) } - override fun fetchImage(page: Page): Observable { - val call = pageHandler.getImageCall(page) - return call?.asObservableSuccess() ?: super.fetchImage(page) - } - override suspend fun getImage(page: Page): Response { val call = pageHandler.getImageCall(page) return call?.awaitSuccess() ?: super.getImage(page) } + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page): Observable { return pageHandler.fetchImageUrl(page) { + @Suppress("DEPRECATION") super.fetchImageUrl(it) } } + override suspend fun getImageUrl(page: Page): String { + return pageHandler.getImageUrl(page) { + super.getImageUrl(page) + } + } + // MetadataSource methods override val metaClass: KClass = MangaDexSearchMetadata::class diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt index b197ecfd9..b2d073cc4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt @@ -61,15 +61,20 @@ class MergedSource : HttpSource() { @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList")) override fun fetchChapterList(manga: SManga) = throw UnsupportedOperationException() override suspend fun getChapterList(manga: SManga) = throw UnsupportedOperationException() - override fun fetchImage(page: Page) = throw UnsupportedOperationException() override suspend fun getImage(page: Page): Response = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page) = throw UnsupportedOperationException() + override suspend fun getImageUrl(page: Page) = throw UnsupportedOperationException() @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList")) override fun fetchPageList(chapter: SChapter) = throw UnsupportedOperationException() override suspend fun getPageList(chapter: SChapter) = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int) = throw UnsupportedOperationException() + override suspend fun getLatestUpdates(page: Int) = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int) = throw UnsupportedOperationException() + override suspend fun getPopularManga(page: Int) = throw UnsupportedOperationException() override suspend fun getMangaDetails(manga: SManga): SManga { return withIOContext { diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt index fa4633445..cbe4a7f97 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt @@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.source.PagePreviewInfo import eu.kanade.tachiyomi.source.PagePreviewPage import eu.kanade.tachiyomi.source.PagePreviewSource import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource @@ -22,9 +23,9 @@ import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.trimOrNull import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import okhttp3.CacheControl import okhttp3.Response @@ -52,9 +53,15 @@ class NHentai(delegate: HttpSource, val context: Context) : // Support direct URL importing override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt index 5c00c4443..98853c6f4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt @@ -5,6 +5,7 @@ import android.net.Uri import androidx.core.net.toUri import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -15,6 +16,7 @@ import exh.metadata.metadata.EightMusesSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -28,11 +30,18 @@ class EightMuses(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response.asJsoup()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt index 2de327ecc..ce63b5fbf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt @@ -4,6 +4,7 @@ import android.content.Context import android.net.Uri import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -14,6 +15,7 @@ import exh.metadata.metadata.HBrowseSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -27,11 +29,18 @@ class HBrowse(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response.asJsoup()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt index dc14a971b..f5b1eb48f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt @@ -19,6 +19,7 @@ import exh.source.DelegatedHttpSource import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import rx.Observable @@ -39,6 +40,7 @@ class Pururin(delegate: HttpSource, val context: Context) : override fun newMetaInstance() = PururinSearchMetadata() // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { val trimmedIdQuery = query.trim().removePrefix("id:") val newQuery = if ((trimmedIdQuery.toIntOrNull() ?: -1) >= 0) { @@ -48,7 +50,19 @@ class Pururin(delegate: HttpSource, val context: Context) : } return urlImportFetchSearchManga(context, newQuery) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) + } + } + + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + val trimmedIdQuery = query.trim().removePrefix("id:") + val newQuery = if ((trimmedIdQuery.toIntOrNull() ?: -1) >= 0) { + "$baseUrl/gallery/$trimmedIdQuery/-" + } else { + query + } + return urlImportFetchSearchMangaSuspend(context, newQuery) { + super.getSearchManga(page, query, filters,) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt index 63c1f25bb..0babef369 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt @@ -19,6 +19,7 @@ import exh.source.DelegatedHttpSource import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import rx.Observable import java.text.SimpleDateFormat @@ -34,11 +35,18 @@ class Tsumino(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun mapUrlToMangaUrl(uri: Uri): String? { val lcFirstPathSegment = uri.pathSegments.firstOrNull()?.lowercase(Locale.ROOT) ?: return null if (lcFirstPathSegment != "read" && lcFirstPathSegment != "book" && lcFirstPathSegment != "entry") { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt index 898377f0e..66736f390 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga @@ -143,7 +142,7 @@ abstract class SearchScreenModel( try { val page = withContext(coroutineDispatcher) { - source.fetchSearchManga(1, query, source.getFilterList()).awaitSingle() + source.getSearchManga(1, query, source.getFilterList()) } val titles = page.mangas.map { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 54e359ba7..53a3bbb0e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.suspendCancellableCoroutine -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.withIOContext import uy.kohesive.injekt.Injekt @@ -211,7 +210,7 @@ internal class HttpPageLoader( try { if (page.imageUrl.isNullOrEmpty()) { page.status = Page.State.LOAD_PAGE - page.imageUrl = source.fetchImageUrl(page).awaitSingle() + page.imageUrl = source.getImageUrl(page) } val imageUrl = page.imageUrl!! diff --git a/app/src/main/java/exh/md/handlers/BilibiliHandler.kt b/app/src/main/java/exh/md/handlers/BilibiliHandler.kt index 080d52d7b..86e245ef7 100644 --- a/app/src/main/java/exh/md/handlers/BilibiliHandler.kt +++ b/app/src/main/java/exh/md/handlers/BilibiliHandler.kt @@ -1,7 +1,6 @@ package exh.md.handlers import eu.kanade.tachiyomi.network.POST -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.parseAs @@ -22,6 +21,7 @@ import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import rx.Observable +import tachiyomi.core.util.lang.runAsObservable import uy.kohesive.injekt.injectLazy import java.util.concurrent.TimeUnit @@ -154,12 +154,13 @@ class BilibiliHandler(currentClient: OkHttpClient) { .mapIndexed { i, page -> Page(i, page.path, "") } } + suspend fun getImageUrl(page: Page): String { + val response = client.newCall(imageUrlRequest(page)).awaitSuccess() + return imageUrlParse(response) + } + fun fetchImageUrl(page: Page): Observable { - return client.newCall(imageUrlRequest(page)) - .asObservableSuccess() - .map { - imageUrlParse(it) - } + return runAsObservable { getImageUrl(page) } } private fun imageUrlRequest(page: Page): Request { diff --git a/app/src/main/java/exh/md/handlers/PageHandler.kt b/app/src/main/java/exh/md/handlers/PageHandler.kt index cf5ddd5a0..14f06c412 100644 --- a/app/src/main/java/exh/md/handlers/PageHandler.kt +++ b/app/src/main/java/exh/md/handlers/PageHandler.kt @@ -134,4 +134,13 @@ class PageHandler( else -> superMethod(page) } } + + suspend fun getImageUrl(page: Page, superMethod: suspend (Page) -> String): String { + return when { + page.url.contains("/bfs/comic/") -> { + bilibiliHandler.getImageUrl(page) + } + else -> superMethod(page) + } + } } diff --git a/app/src/main/java/exh/util/DataSaver.kt b/app/src/main/java/exh/util/DataSaver.kt index e84626337..a9f4ab2c1 100644 --- a/app/src/main/java/exh/util/DataSaver.kt +++ b/app/src/main/java/exh/util/DataSaver.kt @@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource import okhttp3.Response -import rx.Observable import tachiyomi.core.preference.Preference interface DataSaver { @@ -22,15 +21,6 @@ interface DataSaver { } } - fun HttpSource.fetchImage(page: Page, dataSaver: DataSaver): Observable { - val imageUrl = page.imageUrl ?: return fetchImage(page) - page.imageUrl = dataSaver.compress(imageUrl) - return fetchImage(page) - .doOnNext { - page.imageUrl = imageUrl - } - } - suspend fun HttpSource.getImage(page: Page, dataSaver: DataSaver): Response { val imageUrl = page.imageUrl ?: return getImage(page) page.imageUrl = dataSaver.compress(imageUrl) diff --git a/app/src/main/java/exh/util/SearchOverride.kt b/app/src/main/java/exh/util/SearchOverride.kt index d1647ba16..7a68f3751 100644 --- a/app/src/main/java/exh/util/SearchOverride.kt +++ b/app/src/main/java/exh/util/SearchOverride.kt @@ -35,3 +35,29 @@ fun UrlImportableSource.urlImportFetchSearchManga(context: Context, query: Strin } else -> fail() } + + +/** + * A version of fetchSearchManga that supports URL importing + */ +suspend fun UrlImportableSource.urlImportFetchSearchMangaSuspend(context: Context, query: String, fail: suspend () -> MangasPage): MangasPage = + when { + query.startsWith("http://") || query.startsWith("https://") -> { + val res = galleryAdder.addGallery( + context = context, + url = query, + fav = false, + forceSource = this + ) + + MangasPage( + if (res is GalleryAddEvent.Success) { + listOf(res.manga.toSManga()) + } else { + emptyList() + }, + false, + ) + } + else -> fail() + } diff --git a/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt index 4cbb34812..e6eec02f4 100755 --- a/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt @@ -58,6 +58,15 @@ fun Call.asObservable(): Observable { } } +fun Call.asObservableSuccess(): Observable { + return asObservable().doOnNext { response -> + if (!response.isSuccessful) { + response.close() + throw HttpException(response.code) + } + } +} + // Based on https://github.com/gildor/kotlin-coroutines-okhttp @OptIn(ExperimentalCoroutinesApi::class) private suspend fun Call.await(callStack: Array): Response { @@ -95,6 +104,9 @@ suspend fun Call.await(): Response { return await(callStack) } +/** + * @since extensions-lib 1.5 + */ suspend fun Call.awaitSuccess(): Response { val callStack = Exception().stackTrace.run { copyOfRange(1, size) } val response = await(callStack) @@ -105,15 +117,6 @@ suspend fun Call.awaitSuccess(): Response { return response } -fun Call.asObservableSuccess(): Observable { - return asObservable().doOnNext { response -> - if (!response.isSuccessful) { - response.close() - throw HttpException(response.code) - } - } -} - fun OkHttpClient.newCachelessCallWithProgress(request: Request, listener: ProgressListener): Call { val progressClient = newBuilder() .cache(null) diff --git a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt index 9b9c7d9a0..998c75f33 100644 --- a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt @@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MetadataMangasPage import eu.kanade.tachiyomi.source.model.SManga import exh.metadata.metadata.RaisedSearchMetadata -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.withIOContext import tachiyomi.domain.source.repository.SourcePagingSourceType @@ -15,19 +14,19 @@ class SourceSearchPagingSource(source: CatalogueSource, val query: String, val f source, ) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchSearchManga(currentPage, query, filters).awaitSingle() + return source.getSearchManga(currentPage, query, filters) } } class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchPopularManga(currentPage).awaitSingle() + return source.getPopularManga(currentPage) } } class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchLatestUpdates(currentPage).awaitSingle() + return source.getLatestUpdates(currentPage) } } diff --git a/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt b/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt index 38d38ef57..8b5f67ef5 100644 --- a/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt +++ b/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt @@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga -import rx.Observable class StubSource( override val id: Long, @@ -14,36 +13,16 @@ class StubSource( private val isInvalid: Boolean = name.isBlank() || lang.isBlank() - override suspend fun getMangaDetails(manga: SManga): SManga { + override suspend fun getMangaDetails(manga: SManga): SManga = throw SourceNotInstalledException() - } - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails")) - override fun fetchMangaDetails(manga: SManga): Observable { - return Observable.error(SourceNotInstalledException()) - } - - override suspend fun getChapterList(manga: SManga): List { + override suspend fun getChapterList(manga: SManga): List = throw SourceNotInstalledException() - } - - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList")) - override fun fetchChapterList(manga: SManga): Observable> { - return Observable.error(SourceNotInstalledException()) - } - - override suspend fun getPageList(chapter: SChapter): List { + override suspend fun getPageList(chapter: SChapter): List = throw SourceNotInstalledException() - } - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList")) - override fun fetchPageList(chapter: SChapter): Observable> { - return Observable.error(SourceNotInstalledException()) - } - - override fun toString(): String { - return if (isInvalid.not()) "$name (${lang.uppercase()})" else id.toString() - } + override fun toString(): String = + if (isInvalid.not()) "$name (${lang.uppercase()})" else id.toString() } class SourceNotInstalledException : Exception() diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt index f9e416def..937fa28a9 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.source import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import rx.Observable +import tachiyomi.core.util.lang.awaitSingle interface CatalogueSource : Source { @@ -17,30 +18,63 @@ interface CatalogueSource : Source { val supportsLatest: Boolean /** - * Returns an observable containing a page with a list of manga. + * Get a page with a list of manga. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. */ - fun fetchPopularManga(page: Int): Observable + @Suppress("DEPRECATION") + suspend fun getPopularManga(page: Int): MangasPage { + return fetchPopularManga(page).awaitSingle() + } /** - * Returns an observable containing a page with a list of manga. + * Get a page with a list of manga. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. * @param query the search query. * @param filters the list of filters to apply. */ - fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable + @Suppress("DEPRECATION") + suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return fetchSearchManga(page, query, filters).awaitSingle() + } /** - * Returns an observable containing a page with a list of latest manga updates. + * Get a page with a list of latest manga updates. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. */ - fun fetchLatestUpdates(page: Int): Observable + @Suppress("DEPRECATION") + suspend fun getLatestUpdates(page: Int): MangasPage { + return fetchLatestUpdates(page).awaitSingle() + } /** * Returns the list of filters for the source. */ fun getFilterList(): FilterList + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getPopularManga"), + ) + fun fetchPopularManga(page: Int): Observable = + throw IllegalStateException("Not used") + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getSearchManga"), + ) + fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + throw IllegalStateException("Not used") + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getLatestUpdates"), + ) + fun fetchLatestUpdates(page: Int): Observable = + throw IllegalStateException("Not used") } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt index d42885f80..e6a019ecc 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt @@ -1,6 +1,19 @@ package eu.kanade.tachiyomi.source +import android.app.Application +import android.content.SharedPreferences +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + interface ConfigurableSource : Source { + /** + * Gets instance of [SharedPreferences] scoped to the specific source. + * + * @since extensions-lib 1.5 + */ + fun getPreferences(): SharedPreferences = + Injekt.get().getSharedPreferences("source_$id", 0x0000) + fun setupPreferenceScreen(screen: PreferenceScreen) } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt index f140eda74..83fcd7962 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt @@ -27,7 +27,7 @@ interface Source { /** * Get the updated details for a manga. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param manga the manga to update. * @return the updated manga. */ @@ -39,7 +39,7 @@ interface Source { /** * Get all the available chapters for a manga. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param manga the manga to update. * @return the chapters for the manga. */ @@ -52,7 +52,7 @@ interface Source { * Get the list of pages a chapter has. Pages should be returned * in the expected order; the index is ignored. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param chapter the chapter. * @return the pages for the chapter. */ @@ -61,41 +61,24 @@ interface Source { return fetchPageList(chapter).awaitSingle() } - /** - * Returns an observable with the updated details for a manga. - * - * @param manga the manga to update. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getMangaDetails"), ) - fun fetchMangaDetails(manga: SManga): Observable = throw IllegalStateException( - "Not used", - ) + fun fetchMangaDetails(manga: SManga): Observable = + throw IllegalStateException("Not used") - /** - * Returns an observable with all the available chapters for a manga. - * - * @param manga the manga to update. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getChapterList"), ) - fun fetchChapterList(manga: SManga): Observable> = throw IllegalStateException( - "Not used", - ) + fun fetchChapterList(manga: SManga): Observable> = + throw IllegalStateException("Not used") - /** - * Returns an observable with the list of pages a chapter has. Pages should be returned - * in the expected order; the index is ignored. - * - * @param chapter the chapter. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getPageList"), ) - fun fetchPageList(chapter: SChapter): Observable> = Observable.empty() + fun fetchPageList(chapter: SChapter): Observable> = + throw IllegalStateException("Not used") } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt index 10b741132..677516cb3 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt @@ -21,6 +21,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import rx.Observable +import tachiyomi.core.util.lang.awaitSingle import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.net.URI @@ -30,6 +31,7 @@ import java.security.MessageDigest /** * A simple implementation for sources from a website. */ +@Suppress("unused") abstract class HttpSource : CatalogueSource { /** @@ -108,6 +110,7 @@ abstract class HttpSource : CatalogueSource { * @param versionId [Int] the version ID of the source * @return a unique ID for the source */ + @Suppress("MemberVisibilityCanBePrivate") protected fun generateId(name: String, lang: String, versionId: Int): Long { val key = "${name.lowercase()}/$lang/$versionId" val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) @@ -231,11 +234,18 @@ abstract class HttpSource : CatalogueSource { abstract fun latestUpdatesParse(response: Response): MangasPage /** - * Returns an observable with the updated details for a manga. Normally it's not needed to - * override this method. + * Get the updated details for a manga. + * Normally it's not needed to override this method. * - * @param manga the manga to be updated. + * @param manga the manga to update. + * @return the updated manga. */ + @Suppress("DEPRECATION") + override suspend fun getMangaDetails(manga: SManga): SManga { + return fetchMangaDetails(manga).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails")) override fun fetchMangaDetails(manga: SManga): Observable { return client.newCall(mangaDetailsRequest(manga)) .asObservableSuccess() @@ -262,11 +272,23 @@ abstract class HttpSource : CatalogueSource { protected abstract fun mangaDetailsParse(response: Response): SManga /** - * Returns an observable with the updated chapter list for a manga. Normally it's not needed to - * override this method. If a manga is licensed an empty chapter list observable is returned + * Get all the available chapters for a manga. + * Normally it's not needed to override this method. * - * @param manga the manga to look for chapters. + * @param manga the manga to update. + * @return the chapters for the manga. + * @throws LicensedMangaChaptersException if a manga is licensed and therefore no chapters are available. */ + @Suppress("DEPRECATION") + override suspend fun getChapterList(manga: SManga): List { + if (manga.status == SManga.LICENSED) { + throw LicensedMangaChaptersException() + } + + return fetchChapterList(manga).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList")) override fun fetchChapterList(manga: SManga): Observable> { return if (manga.status != SManga.LICENSED) { client.newCall(chapterListRequest(manga)) @@ -297,10 +319,18 @@ abstract class HttpSource : CatalogueSource { protected abstract fun chapterListParse(response: Response): List /** - * Returns an observable with the page list for a chapter. + * Get the list of pages a chapter has. Pages should be returned + * in the expected order; the index is ignored. * - * @param chapter the chapter whose page list has to be fetched. + * @param chapter the chapter. + * @return the pages for the chapter. */ + @Suppress("DEPRECATION") + override suspend fun getPageList(chapter: SChapter): List { + return fetchPageList(chapter).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList")) override fun fetchPageList(chapter: SChapter): Observable> { return client.newCall(pageListRequest(chapter)) .asObservableSuccess() @@ -330,8 +360,15 @@ abstract class HttpSource : CatalogueSource { * Returns an observable with the page containing the source url of the image. If there's any * error, it will return null instead of throwing an exception. * + * @since extensions-lib 1.5 * @param page the page whose source image has to be fetched. */ + @Suppress("DEPRECATION") + open suspend fun getImageUrl(page: Page): String { + return fetchImageUrl(page).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) open fun fetchImageUrl(page: Page): Observable { return client.newCall(imageUrlRequest(page)) .asObservableSuccess() @@ -355,26 +392,14 @@ abstract class HttpSource : CatalogueSource { */ protected abstract fun imageUrlParse(response: Response): String - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - /* SY --> */ - open /* SY <-- */ fun fetchImage(page: Page): Observable { - // images will be cached or saved manually, so don't take up network cache - return client.newCachelessCallWithProgress(imageRequest(page), page) - .asObservableSuccess() - } - /** * Returns the response of the source image. + * Typically does not need to be overridden. * + * @since extensions-lib 1.5 * @param page the page whose source image has to be downloaded. */ - /* SY --> */ - open /* SY <-- */ suspend fun getImage(page: Page): Response { - // images will be cached or saved manually, so don't take up network cache + open suspend fun getImage(page: Page): Response { return client.newCachelessCallWithProgress(imageRequest(page), page) .awaitSuccess() } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt deleted file mode 100755 index 76c68e882..000000000 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt +++ /dev/null @@ -1,25 +0,0 @@ -package eu.kanade.tachiyomi.source.online - -import eu.kanade.tachiyomi.source.model.Page -import rx.Observable - -fun HttpSource.fetchAllImageUrlsFromPageList(pages: List): Observable { - return Observable.from(pages) - .filter { !it.imageUrl.isNullOrEmpty() } - .mergeWith(fetchRemainingImageUrlsFromPageList(pages)) -} - -private fun HttpSource.fetchRemainingImageUrlsFromPageList(pages: List): Observable { - return Observable.from(pages) - .filter { it.imageUrl.isNullOrEmpty() } - .concatMap { getImageUrl(it) } -} - -private fun HttpSource.getImageUrl(page: Page): Observable { - page.status = Page.State.LOAD_PAGE - return fetchImageUrl(page) - .doOnError { page.status = Page.State.ERROR } - .onErrorReturn { null } - .doOnNext { page.imageUrl = it } - .map { page } -} diff --git a/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt b/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt index ad105d248..1de09d68d 100644 --- a/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt +++ b/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt @@ -146,11 +146,17 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int): Observable { ensureDelegateCompatible() return delegate.fetchPopularManga(page) } + override suspend fun getPopularManga(page: Int): MangasPage { + ensureDelegateCompatible() + return delegate.getPopularManga(page) + } + /** * Returns an observable containing a page with a list of manga. Normally it's not needed to * override this method. @@ -159,21 +165,33 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * @param query the search query. * @param filters the list of filters to apply. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { ensureDelegateCompatible() return delegate.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + ensureDelegateCompatible() + return delegate.getSearchManga(page, query, filters) + } + /** * Returns an observable containing a page with a list of latest manga updates. * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int): Observable { ensureDelegateCompatible() return delegate.fetchLatestUpdates(page) } + override suspend fun getLatestUpdates(page: Int): MangasPage { + ensureDelegateCompatible() + return delegate.getLatestUpdates(page) + } + /** * Returns an observable with the updated details for a manga. Normally it's not needed to * override this method. @@ -250,19 +268,15 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * * @param page the page whose source image has to be fetched. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page): Observable { ensureDelegateCompatible() return delegate.fetchImageUrl(page) } - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - override fun fetchImage(page: Page): Observable { + override suspend fun getImageUrl(page: Page): String { ensureDelegateCompatible() - return delegate.fetchImage(page) + return delegate.getImageUrl(page) } /** diff --git a/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt b/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt index 43dc38dcf..5c8675a3d 100644 --- a/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt +++ b/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt @@ -149,8 +149,11 @@ class EnhancedHttpSource( * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int) = source().fetchPopularManga(page) + override suspend fun getPopularManga(page: Int) = source().getPopularManga(page) + /** * Returns an observable containing a page with a list of manga. Normally it's not needed to * override this method. @@ -159,16 +162,23 @@ class EnhancedHttpSource( * @param query the search query. * @param filters the list of filters to apply. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = source().fetchSearchManga(page, query, filters) + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList) = + source().getSearchManga(page, query, filters) + /** * Returns an observable containing a page with a list of latest manga updates. * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int) = source().fetchLatestUpdates(page) + override suspend fun getLatestUpdates(page: Int) = source().getLatestUpdates(page) + /** * Returns an observable with the updated details for a manga. Normally it's not needed to * override this method. @@ -224,14 +234,10 @@ class EnhancedHttpSource( * * @param page the page whose source image has to be fetched. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page) = source().fetchImageUrl(page) - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - override fun fetchImage(page: Page) = source().fetchImage(page) + override suspend fun getImageUrl(page: Page) = source().getImageUrl(page) /** * Returns the response of the source image. diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt index e1d9fbf8e..8dd747227 100755 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt @@ -20,7 +20,6 @@ import net.lingala.zip4j.ZipFile import net.lingala.zip4j.model.ZipParameters import nl.adaptivity.xmlutil.AndroidXmlReader import nl.adaptivity.xmlutil.serialization.XML -import rx.Observable import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE import tachiyomi.core.metadata.comicinfo.ComicInfo import tachiyomi.core.metadata.comicinfo.copyFromComicInfo @@ -72,11 +71,11 @@ actual class LocalSource( override val supportsLatest: Boolean = true // Browse related - override fun fetchPopularManga(page: Int) = fetchSearchManga(page, "", POPULAR_FILTERS) + override suspend fun getPopularManga(page: Int) = getSearchManga(page, "", POPULAR_FILTERS) - override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS) + override suspend fun getLatestUpdates(page: Int) = getSearchManga(page, "", LATEST_FILTERS) - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { val baseDirsFiles = fileSystem.getFilesInBaseDirectories() val lastModifiedLimit by lazy { if (filters === LATEST_FILTERS) System.currentTimeMillis() - LATEST_THRESHOLD else 0L } // SY --> @@ -153,7 +152,7 @@ actual class LocalSource( } } - return Observable.just(MangasPage(mangas.toList(), false)) + return MangasPage(mangas.toList(), false) } // SY -->