Adapt source implementation for TachiyomiX 1.6 (#3243)
This commit is contained in:
@@ -120,7 +120,7 @@ class ExtensionsScreenModel(
|
||||
when (extension) {
|
||||
is Extension.Installed -> extension.sources.any { source ->
|
||||
source.name.contains(subquery, ignoreCase = true) ||
|
||||
(source as? HttpSource)?.baseUrl?.contains(subquery, ignoreCase = true) == true ||
|
||||
(source as? HttpSource)?.getHomeUrl()?.contains(subquery, ignoreCase = true) == true ||
|
||||
source.id == subquery.toLongOrNull()
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -99,7 +99,8 @@ class ExtensionDetailsScreenModel(
|
||||
|
||||
val urls = extension.sources
|
||||
.filterIsInstance<HttpSource>()
|
||||
.mapNotNull { it.baseUrl.takeUnless { url -> url.isEmpty() } }
|
||||
.flatMap { listOf(it.baseUrl, it.getHomeUrl()) }
|
||||
.filter { it.isNotEmpty() }
|
||||
.distinct()
|
||||
|
||||
val cleared = urls.sumOf {
|
||||
|
||||
+5
-5
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
||||
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
|
||||
import kotlinx.coroutines.flow.update
|
||||
@@ -21,8 +21,8 @@ class MigrateSearchScreenModel(
|
||||
|
||||
private val migrationSources by lazy { sourcePreferences.migrationSources.get() }
|
||||
|
||||
override val sortComparator = { map: Map<CatalogueSource, SearchItemResult> ->
|
||||
compareBy<CatalogueSource>(
|
||||
override val sortComparator = { map: Map<Source, SearchItemResult> ->
|
||||
compareBy<Source>(
|
||||
{ (map[it] as? SearchItemResult.Success)?.isEmpty ?: true },
|
||||
{ migrationSources.indexOf(it.id) },
|
||||
)
|
||||
@@ -41,7 +41,7 @@ class MigrateSearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEnabledSources(): List<CatalogueSource> {
|
||||
return migrationSources.mapNotNull { sourceManager.get(it) as? CatalogueSource }
|
||||
override fun getEnabledSources(): List<Source> {
|
||||
return migrationSources.mapNotNull { sourceManager.get(it) }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ data class MigrateSourceSearchScreen(
|
||||
val source = screenModel.source as? HttpSource ?: return@BrowseSourceContent
|
||||
navigator.push(
|
||||
WebViewScreen(
|
||||
url = source.baseUrl,
|
||||
url = source.getHomeUrl(),
|
||||
initialTitle = source.name,
|
||||
sourceId = source.id,
|
||||
),
|
||||
|
||||
@@ -44,7 +44,6 @@ import eu.kanade.presentation.category.components.ChangeCategoryDialog
|
||||
import eu.kanade.presentation.manga.DuplicateMangaDialog
|
||||
import eu.kanade.presentation.util.AssistContentScreen
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
|
||||
@@ -111,7 +110,7 @@ data class BrowseSourceScreen(
|
||||
val source = screenModel.source as? HttpSource ?: return@f
|
||||
navigator.push(
|
||||
WebViewScreen(
|
||||
url = source.baseUrl,
|
||||
url = source.getHomeUrl(),
|
||||
initialTitle = source.name,
|
||||
sourceId = source.id,
|
||||
),
|
||||
@@ -119,7 +118,7 @@ data class BrowseSourceScreen(
|
||||
}
|
||||
|
||||
LaunchedEffect(screenModel.source) {
|
||||
assistUrl = (screenModel.source as? HttpSource)?.baseUrl
|
||||
assistUrl = (screenModel.source as? HttpSource)?.getHomeUrl()
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
@@ -166,7 +165,7 @@ data class BrowseSourceScreen(
|
||||
Text(text = stringResource(MR.strings.popular))
|
||||
},
|
||||
)
|
||||
if ((screenModel.source as CatalogueSource).supportsLatest) {
|
||||
if (screenModel.source.supportsLatest) {
|
||||
FilterChip(
|
||||
selected = state.listing == Listing.Latest,
|
||||
onClick = {
|
||||
|
||||
+12
-23
@@ -20,7 +20,6 @@ import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.track.interactor.AddTracks
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
@@ -74,22 +73,20 @@ class BrowseSourceScreenModel(
|
||||
val source = sourceManager.getOrStub(sourceId)
|
||||
|
||||
init {
|
||||
if (source is CatalogueSource) {
|
||||
mutableState.update {
|
||||
var query: String? = null
|
||||
var listing = it.listing
|
||||
mutableState.update {
|
||||
var query: String? = null
|
||||
var listing = it.listing
|
||||
|
||||
if (listing is Listing.Search) {
|
||||
query = listing.query
|
||||
listing = Listing.Search(query, source.getFilterList())
|
||||
}
|
||||
|
||||
it.copy(
|
||||
listing = listing,
|
||||
filters = source.getFilterList(),
|
||||
toolbarQuery = query,
|
||||
)
|
||||
if (listing is Listing.Search) {
|
||||
query = listing.query
|
||||
listing = Listing.Search(query, source.getFilterList())
|
||||
}
|
||||
|
||||
it.copy(
|
||||
listing = listing,
|
||||
filters = source.getFilterList(),
|
||||
toolbarQuery = query,
|
||||
)
|
||||
}
|
||||
|
||||
if (!getIncognitoState.await(source.id)) {
|
||||
@@ -129,8 +126,6 @@ class BrowseSourceScreenModel(
|
||||
}
|
||||
|
||||
fun resetFilters() {
|
||||
if (source !is CatalogueSource) return
|
||||
|
||||
mutableState.update { it.copy(filters = source.getFilterList()) }
|
||||
}
|
||||
|
||||
@@ -139,8 +134,6 @@ class BrowseSourceScreenModel(
|
||||
}
|
||||
|
||||
fun setFilters(filters: FilterList) {
|
||||
if (source !is CatalogueSource) return
|
||||
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
filters = filters,
|
||||
@@ -149,8 +142,6 @@ class BrowseSourceScreenModel(
|
||||
}
|
||||
|
||||
fun search(query: String? = null, filters: FilterList? = null) {
|
||||
if (source !is CatalogueSource) return
|
||||
|
||||
val input = state.value.listing as? Listing.Search
|
||||
?: Listing.Search(query = null, filters = source.getFilterList())
|
||||
|
||||
@@ -166,8 +157,6 @@ class BrowseSourceScreenModel(
|
||||
}
|
||||
|
||||
fun searchGenre(genreName: String) {
|
||||
if (source !is CatalogueSource) return
|
||||
|
||||
val defaultFilters = source.getFilterList()
|
||||
var genreExists = false
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.source.globalsearch
|
||||
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
||||
class GlobalSearchScreenModel(
|
||||
initialQuery: String = "",
|
||||
@@ -18,7 +18,7 @@ class GlobalSearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEnabledSources(): List<CatalogueSource> {
|
||||
override fun getEnabledSources(): List<Source> {
|
||||
return super.getEnabledSources()
|
||||
.filter { state.value.sourceFilter != SourceFilter.PinnedOnly || "${it.id}" in pinnedSources }
|
||||
}
|
||||
|
||||
+9
-10
@@ -8,7 +8,7 @@ import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.async
|
||||
@@ -52,8 +52,8 @@ abstract class SearchScreenModel(
|
||||
|
||||
protected var extensionFilter: String? = null
|
||||
|
||||
open val sortComparator = { map: Map<CatalogueSource, SearchItemResult> ->
|
||||
compareBy<CatalogueSource>(
|
||||
open val sortComparator = { map: Map<Source, SearchItemResult> ->
|
||||
compareBy<Source>(
|
||||
{ (map[it] as? SearchItemResult.Success)?.isEmpty ?: true },
|
||||
{ "${it.id}" !in pinnedSources },
|
||||
{ "${it.name.lowercase()} (${it.lang})" },
|
||||
@@ -79,8 +79,8 @@ abstract class SearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
open fun getEnabledSources(): List<CatalogueSource> {
|
||||
return sourceManager.getCatalogueSources()
|
||||
open fun getEnabledSources(): List<Source> {
|
||||
return sourceManager.getAll()
|
||||
.filter { it.lang in enabledLanguages && "${it.id}" !in disabledSources }
|
||||
.sortedWith(
|
||||
compareBy(
|
||||
@@ -90,7 +90,7 @@ abstract class SearchScreenModel(
|
||||
)
|
||||
}
|
||||
|
||||
private fun getSelectedSources(): List<CatalogueSource> {
|
||||
private fun getSelectedSources(): List<Source> {
|
||||
val enabledSources = getEnabledSources()
|
||||
|
||||
val filter = extensionFilter
|
||||
@@ -101,7 +101,6 @@ abstract class SearchScreenModel(
|
||||
return extensionManager.installedExtensionsFlow.value
|
||||
.filter { it.pkgName == filter }
|
||||
.flatMap { it.sources }
|
||||
.filterIsInstance<CatalogueSource>()
|
||||
.filter { it in enabledSources }
|
||||
}
|
||||
|
||||
@@ -179,7 +178,7 @@ abstract class SearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateItems(items: Map<CatalogueSource, SearchItemResult>) {
|
||||
private fun updateItems(items: Map<Source, SearchItemResult>) {
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
items = items
|
||||
@@ -188,7 +187,7 @@ abstract class SearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateItem(source: CatalogueSource, result: SearchItemResult) {
|
||||
private fun updateItem(source: Source, result: SearchItemResult) {
|
||||
updateItems(state.value.items + (source to result))
|
||||
}
|
||||
|
||||
@@ -209,7 +208,7 @@ abstract class SearchScreenModel(
|
||||
val searchQuery: String? = null,
|
||||
val sourceFilter: SourceFilter = SourceFilter.PinnedOnly,
|
||||
val onlyShowHasResults: Boolean = false,
|
||||
val items: Map<CatalogueSource, SearchItemResult> = mapOf(),
|
||||
val items: Map<Source, SearchItemResult> = mapOf(),
|
||||
val dialog: Dialog? = null,
|
||||
) {
|
||||
val progress: Int = items.count { it.value !is SearchItemResult.Loading }
|
||||
|
||||
@@ -3,14 +3,13 @@ package eu.kanade.tachiyomi.ui.deeplink
|
||||
import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.manga.model.toSManga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.online.ResolvableSource
|
||||
import eu.kanade.tachiyomi.source.online.UriType
|
||||
import kotlinx.coroutines.flow.update
|
||||
import mihon.domain.manga.model.toDomainManga
|
||||
import mihon.domain.source.interactor.UpdateMangaFromRemote
|
||||
import tachiyomi.core.common.util.lang.launchIO
|
||||
import tachiyomi.domain.chapter.interactor.GetChapterByUrlAndMangaId
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
@@ -25,12 +24,12 @@ class DeepLinkScreenModel(
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val getChapterByUrlAndMangaId: GetChapterByUrlAndMangaId = Injekt.get(),
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
private val updateMangaFromRemote: UpdateMangaFromRemote = Injekt.get(),
|
||||
) : StateScreenModel<DeepLinkScreenModel.State>(State.Loading) {
|
||||
|
||||
init {
|
||||
screenModelScope.launchIO {
|
||||
val source = sourceManager.getCatalogueSources()
|
||||
val source = sourceManager.getAll()
|
||||
.filterIsInstance<ResolvableSource>()
|
||||
.firstOrNull { it.getUriType(query) != UriType.Unknown }
|
||||
|
||||
@@ -61,13 +60,11 @@ class DeepLinkScreenModel(
|
||||
private suspend fun getChapterFromSChapter(sChapter: SChapter, manga: Manga, source: Source): Chapter? {
|
||||
val localChapter = getChapterByUrlAndMangaId.await(sChapter.url, manga.id)
|
||||
|
||||
return if (localChapter == null) {
|
||||
val sourceChapters = source.getChapterList(manga.toSManga())
|
||||
val newChapters = syncChaptersWithSource.await(sourceChapters, manga, source, false)
|
||||
newChapters.find { it.url == sChapter.url }
|
||||
} else {
|
||||
localChapter
|
||||
}
|
||||
return localChapter
|
||||
?: updateMangaFromRemote(manga, fetchChapters = true)
|
||||
.getOrElse { return null }
|
||||
.newChapters
|
||||
.find { it.url == sChapter.url }
|
||||
}
|
||||
|
||||
sealed interface State {
|
||||
|
||||
@@ -16,13 +16,11 @@ import eu.kanade.core.util.addOrRemove
|
||||
import eu.kanade.core.util.insertSeparators
|
||||
import eu.kanade.domain.chapter.interactor.GetAvailableScanlators
|
||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.manga.interactor.GetExcludedScanlators
|
||||
import eu.kanade.domain.manga.interactor.SetExcludedScanlators
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.chaptersFiltered
|
||||
import eu.kanade.domain.manga.model.downloadedFilter
|
||||
import eu.kanade.domain.manga.model.toSManga
|
||||
import eu.kanade.domain.track.interactor.AddTracks
|
||||
import eu.kanade.domain.track.interactor.RefreshTracks
|
||||
import eu.kanade.domain.track.interactor.TrackChapter
|
||||
@@ -36,14 +34,12 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||
import eu.kanade.tachiyomi.data.track.TrackerManager
|
||||
import eu.kanade.tachiyomi.network.HttpException
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.util.chapter.getNextUnread
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -54,13 +50,13 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import logcat.LogPriority
|
||||
import mihon.domain.chapter.interactor.FilterChaptersForDownload
|
||||
import mihon.domain.source.interactor.UpdateMangaFromRemote
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.preference.CheckboxState
|
||||
import tachiyomi.core.common.preference.TriState
|
||||
import tachiyomi.core.common.preference.mapAsCheckboxState
|
||||
import tachiyomi.core.common.util.lang.launchIO
|
||||
import tachiyomi.core.common.util.lang.launchNonCancellable
|
||||
import tachiyomi.core.common.util.lang.withIOContext
|
||||
import tachiyomi.core.common.util.lang.withUIContext
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.category.interactor.GetCategories
|
||||
@@ -111,13 +107,13 @@ class MangaScreenModel(
|
||||
private val setReadStatus: SetReadStatus = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val addTracks: AddTracks = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
private val mangaRepository: MangaRepository = Injekt.get(),
|
||||
private val filterChaptersForDownload: FilterChaptersForDownload = Injekt.get(),
|
||||
private val updateMangaFromRemote: UpdateMangaFromRemote = Injekt.get(),
|
||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||
) : StateScreenModel<MangaScreenModel.State>(State.Loading) {
|
||||
|
||||
@@ -237,11 +233,11 @@ class MangaScreenModel(
|
||||
|
||||
// Fetch info-chapters when needed
|
||||
if (screenModelScope.isActive) {
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { if (needRefreshInfo) fetchMangaFromSource() },
|
||||
async { if (needRefreshChapter) fetchChaptersFromSource() },
|
||||
fetchAllFromSource(
|
||||
manualFetch = false,
|
||||
fetchDetails = needRefreshInfo,
|
||||
fetchChapters = needRefreshChapter,
|
||||
)
|
||||
fetchFromSourceTasks.awaitAll()
|
||||
}
|
||||
|
||||
// Initial loading finished
|
||||
@@ -252,38 +248,54 @@ class MangaScreenModel(
|
||||
fun fetchAllFromSource(manualFetch: Boolean = true) {
|
||||
screenModelScope.launch {
|
||||
updateSuccessState { it.copy(isRefreshingData = true) }
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { fetchMangaFromSource(manualFetch) },
|
||||
async { fetchChaptersFromSource(manualFetch) },
|
||||
fetchAllFromSource(
|
||||
manualFetch = manualFetch,
|
||||
fetchDetails = true,
|
||||
fetchChapters = true,
|
||||
)
|
||||
fetchFromSourceTasks.awaitAll()
|
||||
updateSuccessState { it.copy(isRefreshingData = false) }
|
||||
}
|
||||
}
|
||||
|
||||
// Manga info - start
|
||||
|
||||
/**
|
||||
* Fetch manga information from source.
|
||||
*/
|
||||
private suspend fun fetchMangaFromSource(manualFetch: Boolean = false) {
|
||||
private suspend fun fetchAllFromSource(
|
||||
manualFetch: Boolean,
|
||||
fetchDetails: Boolean,
|
||||
fetchChapters: Boolean,
|
||||
) {
|
||||
val state = successState ?: return
|
||||
try {
|
||||
withIOContext {
|
||||
val networkManga = state.source.getMangaDetails(state.manga.toSManga())
|
||||
updateManga.awaitUpdateFromSource(state.manga, networkManga, manualFetch)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
// Ignore early hints "errors" that aren't handled by OkHttp
|
||||
if (e is HttpException && e.code == 103) return
|
||||
withUIContext {
|
||||
val update = updateMangaFromRemote(
|
||||
source = state.source,
|
||||
manga = state.manga,
|
||||
fetchDetails = fetchDetails,
|
||||
fetchChapters = fetchChapters,
|
||||
manualFetch = manualFetch,
|
||||
)
|
||||
.getOrThrow()
|
||||
|
||||
if (manualFetch) {
|
||||
downloadNewChapters(update.newChapters)
|
||||
}
|
||||
}
|
||||
} catch (_: CancellationException) {
|
||||
// ignore
|
||||
} catch (e: Exception) {
|
||||
val message = if (e is NoChaptersException) {
|
||||
context.stringResource(MR.strings.no_chapters_error)
|
||||
} else {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
with(context) { e.formattedMessage }
|
||||
}
|
||||
|
||||
logcat(LogPriority.ERROR, e)
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(message = with(context) { e.formattedMessage })
|
||||
snackbarHostState.showSnackbar(message = message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Manga info - start
|
||||
|
||||
fun toggleFavorite() {
|
||||
toggleFavorite(
|
||||
onRemoved = {
|
||||
@@ -548,42 +560,6 @@ class MangaScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests an updated list of chapters from the source.
|
||||
*/
|
||||
private suspend fun fetchChaptersFromSource(manualFetch: Boolean = false) {
|
||||
val state = successState ?: return
|
||||
try {
|
||||
withIOContext {
|
||||
val chapters = state.source.getChapterList(state.manga.toSManga())
|
||||
|
||||
val newChapters = syncChaptersWithSource.await(
|
||||
chapters,
|
||||
state.manga,
|
||||
state.source,
|
||||
manualFetch,
|
||||
)
|
||||
|
||||
if (manualFetch) {
|
||||
downloadNewChapters(newChapters)
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
val message = if (e is NoChaptersException) {
|
||||
context.stringResource(MR.strings.no_chapters_error)
|
||||
} else {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
with(context) { e.formattedMessage }
|
||||
}
|
||||
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(message = message)
|
||||
}
|
||||
val newManga = mangaRepository.getMangaById(mangaId)
|
||||
updateSuccessState { it.copy(manga = newManga, isRefreshingData = false) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the swipe action is [LibraryPreferences.ChapterSwipeAction.Disabled]
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user