Fix: crash upon open RecommendsScreen if source is removed

This commit is contained in:
Cuong-Tran 2025-01-24 13:17:17 +07:00
parent 7e16b56911
commit 343cd3727c
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
9 changed files with 47 additions and 21 deletions

View file

@ -63,6 +63,7 @@ import eu.kanade.tachiyomi.ui.webview.WebViewScreen
import eu.kanade.tachiyomi.util.system.toast
import exh.md.follows.MangaDexFollowsScreen
import exh.source.isEhBasedSource
import exh.source.isMdBasedSource
import exh.ui.smartsearch.SmartSearchScreen
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
@ -408,7 +409,7 @@ data class BrowseSourceScreen(
// KMK -->
onSavedSearchPressDesc = stringResource(KMR.strings.saved_searches_delete),
// KMK <--
openMangaDexRandom = if (screenModel.sourceIsMangaDex) {
openMangaDexRandom = if (screenModel.source.isMdBasedSource()) {
{
screenModel.onMangaDexRandom {
navigator.replace(
@ -422,7 +423,7 @@ data class BrowseSourceScreen(
} else {
null
},
openMangaDexFollows = if (screenModel.sourceIsMangaDex) {
openMangaDexFollows = if (screenModel.source.isMdBasedSource()) {
{
navigator.replace(MangaDexFollowsScreen(sourceId))
}

View file

@ -31,7 +31,6 @@ import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.util.removeCovers
import exh.metadata.metadata.RaisedSearchMetadata
import exh.source.getMainSource
import exh.source.mangaDexSourceIds
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@ -125,8 +124,6 @@ open class BrowseSourceScreenModel(
val startExpanded by uiPreferences.expandFilters().asState(screenModelScope)
private val filterSerializer = FilterSerializer()
val sourceIsMangaDex = sourceId in mangaDexSourceIds
// SY <--
init {

View file

@ -7,6 +7,7 @@ import exh.recs.sources.RecommendationPagingSource
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.runBlocking
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -15,12 +16,25 @@ class BrowseRecommendsScreenModel(
sourceId: Long,
private val recommendationSourceName: String,
private val getManga: GetManga = Injekt.get(),
// KMK -->
sourceManager: SourceManager = Injekt.get(),
// KMK <--
) : BrowseSourceScreenModel(sourceId, null) {
val manga = runBlocking { getManga.await(mangaId) }!!
// KMK -->
val source_ = sourceManager.get(sourceId)
?.let { it as CatalogueSource }
// KMK <--
val recommendationSource: RecommendationPagingSource
get() = RecommendationPagingSource.createSources(manga, source as CatalogueSource).first {
get() = RecommendationPagingSource.createSources(
manga,
// KMK -->
source_,
// KMK <--
).first {
it::class.qualifiedName == recommendationSourceName
}

View file

@ -37,7 +37,10 @@ open class RecommendsScreenModel(
internal val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
) : StateScreenModel<RecommendsScreenModel.State>(State()) {
val source = sourceManager.getOrStub(sourceId) as CatalogueSource
val source = sourceManager.get(sourceId)
// KMK -->
?.let { it as CatalogueSource }
// KMK <--
private val coroutineDispatcher = Dispatchers.IO.limitedParallelism(5)

View file

@ -21,7 +21,7 @@ import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.sy.SYMR
class AniListPagingSource(manga: Manga, source: CatalogueSource) : TrackerRecommendationPagingSource(
class AniListPagingSource(manga: Manga, source: CatalogueSource?) : TrackerRecommendationPagingSource(
"https://graphql.anilist.co/", source, manga,
) {
override val name: String

View file

@ -23,7 +23,7 @@ import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.sy.SYMR
abstract class MangaUpdatesPagingSource(manga: Manga, source: CatalogueSource) : TrackerRecommendationPagingSource(
abstract class MangaUpdatesPagingSource(manga: Manga, source: CatalogueSource?) : TrackerRecommendationPagingSource(
"https://api.mangaupdates.com/v1/", source, manga,
) {
override val name: String
@ -98,14 +98,14 @@ abstract class MangaUpdatesPagingSource(manga: Manga, source: CatalogueSource) :
}
}
class MangaUpdatesCommunityPagingSource(manga: Manga, source: CatalogueSource) : MangaUpdatesPagingSource(manga, source) {
class MangaUpdatesCommunityPagingSource(manga: Manga, source: CatalogueSource?) : MangaUpdatesPagingSource(manga, source) {
override val category: StringResource
get() = SYMR.strings.community_recommendations
override val recommendationJsonObjectName: String
get() = "recommendations"
}
class MangaUpdatesSimilarPagingSource(manga: Manga, source: CatalogueSource) : MangaUpdatesPagingSource(manga, source) {
class MangaUpdatesSimilarPagingSource(manga: Manga, source: CatalogueSource?) : MangaUpdatesPagingSource(manga, source) {
override val category: StringResource
get() = SYMR.strings.similar_titles
override val recommendationJsonObjectName: String

View file

@ -17,7 +17,7 @@ import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.sy.SYMR
class MyAnimeListPagingSource(manga: Manga, source: CatalogueSource) : TrackerRecommendationPagingSource(
class MyAnimeListPagingSource(manga: Manga, source: CatalogueSource?) : TrackerRecommendationPagingSource(
"https://api.jikan.moe/v4/", source, manga,
) {
override val name: String

View file

@ -26,7 +26,7 @@ import uy.kohesive.injekt.injectLazy
* General class for recommendation sources.
*/
abstract class RecommendationPagingSource(
source: CatalogueSource,
source: CatalogueSource?,
protected val manga: Manga,
) : SourcePagingSource(source) {
// Display name
@ -44,7 +44,7 @@ abstract class RecommendationPagingSource(
open val associatedSourceId: Long? = null
companion object {
fun createSources(manga: Manga, source: CatalogueSource): List<RecommendationPagingSource> {
fun createSources(manga: Manga, source: CatalogueSource?): List<RecommendationPagingSource> {
return buildList {
add(AniListPagingSource(manga, source))
add(MangaUpdatesCommunityPagingSource(manga, source))
@ -52,12 +52,23 @@ abstract class RecommendationPagingSource(
add(MyAnimeListPagingSource(manga, source))
// Only include MangaDex if the delegate sources are enabled and the source is MD-based
if (source.isMdBasedSource() && Injekt.get<DelegateSourcePreferences>().delegateSources().get()) {
if (
// KMK -->
source != null &&
// KMK <--
source.isMdBasedSource() &&
Injekt.get<DelegateSourcePreferences>().delegateSources().get()
) {
add(MangaDexSimilarPagingSource(manga, source.getMainSource() as MangaDex))
}
// Only include Comick if the source manga is from there
if (source.isComickSource()) {
if (
// KMK -->
source != null &&
// KMK <--
source.isComickSource()
) {
add(ComickPagingSource(manga, source))
}
}.sortedWith(compareBy({ it.name }, { it.category.resourceId }))
@ -70,7 +81,7 @@ abstract class RecommendationPagingSource(
*/
abstract class TrackerRecommendationPagingSource(
protected val endpoint: String,
source: CatalogueSource,
source: CatalogueSource?,
manga: Manga,
) : RecommendationPagingSource(source, manga) {
private val getTracks: GetTracks by injectLazy()

View file

@ -10,27 +10,27 @@ import exh.metadata.metadata.RaisedSearchMetadata
import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.source.repository.SourcePagingSourceType
class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) :
class SourceSearchPagingSource(/* KMK --> */ override val /* KMK <-- */source: CatalogueSource, val query: String, val filters: FilterList) :
SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.getSearchManga(currentPage, query, filters)
}
}
class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) {
class SourcePopularPagingSource(/* KMK --> */ override val /* KMK <-- */source: CatalogueSource) : SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.getPopularManga(currentPage)
}
}
class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) {
class SourceLatestPagingSource(/* KMK --> */ override val /* KMK <-- */source: CatalogueSource) : SourcePagingSource(source) {
override suspend fun requestNextPage(currentPage: Int): MangasPage {
return source.getLatestUpdates(currentPage)
}
}
abstract class SourcePagingSource(
protected open val source: CatalogueSource,
protected open val source: CatalogueSource?,
) : SourcePagingSourceType() {
abstract suspend fun requestNextPage(currentPage: Int): MangasPage