From 95fef0d01950097c1fb50a8ebfa73cedd5f5e9cb Mon Sep 17 00:00:00 2001 From: "Cuong M. Tran" Date: Wed, 12 Jun 2024 13:11:07 +0700 Subject: [PATCH] Option to not show Related titles by default but using a button to open that screen --- .../java/eu/kanade/domain/ui/UiPreferences.kt | 2 + .../browse/RelatedMangasScreen.kt | 14 +-- .../RelatedMangasComfortableGrid.kt | 2 + .../components/RelatedMangasCompactGrid.kt | 2 + .../browse/components/RelatedMangasList.kt | 3 + .../kanade/presentation/manga/MangaScreen.kt | 99 +++++++++++++------ .../components/OutlineButtonWithArrow.kt | 64 ++++++++++++ .../screen/SettingsAppearanceScreen.kt | 8 ++ .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 5 + .../tachiyomi/ui/manga/MangaScreenModel.kt | 94 +++++++++++------- .../commonMain/resources/MR/base/strings.xml | 4 +- 11 files changed, 220 insertions(+), 77 deletions(-) create mode 100644 app/src/main/java/eu/kanade/presentation/manga/components/OutlineButtonWithArrow.kt diff --git a/app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt b/app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt index a2c89e201..02161458b 100644 --- a/app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt +++ b/app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt @@ -45,6 +45,8 @@ class UiPreferences( fun feedTabInFront() = preferenceStore.getBoolean("latest_tab_position", false) + fun expandRelatedTitles() = preferenceStore.getBoolean("expand_related_titles", true) + fun recommendsInOverflow() = preferenceStore.getBoolean("recommends_in_overflow", true) fun mergeInOverflow() = preferenceStore.getBoolean("merge_in_overflow", true) diff --git a/app/src/main/java/eu/kanade/presentation/browse/RelatedMangasScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/RelatedMangasScreen.kt index a0782f936..501cd5cd5 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/RelatedMangasScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/RelatedMangasScreen.kt @@ -17,19 +17,19 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.ArrowForward import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.capitalize +import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.unit.dp import eu.kanade.presentation.browse.components.RelatedMangasComfortableGrid import eu.kanade.presentation.browse.components.RelatedMangasCompactGrid import eu.kanade.presentation.browse.components.RelatedMangasList import eu.kanade.tachiyomi.ui.manga.RelatedManga -import exh.util.capitalize import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.MR @@ -115,12 +115,14 @@ fun RelatedMangaTitle( onClick: () -> Unit, onLongClick: (() -> Unit)?, modifier: Modifier = Modifier, + showArrow: Boolean = true, ) { Row( modifier = modifier .padding( start = MaterialTheme.padding.medium, - end = MaterialTheme.padding.extraSmall, + end = MaterialTheme.padding.small, + top = MaterialTheme.padding.small, ) .fillMaxWidth() .let { @@ -130,7 +132,7 @@ fun RelatedMangaTitle( it.combinedClickable(onClick = onClick, onLongClick = onLongClick) } }, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = if (showArrow) Arrangement.SpaceBetween else Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { Column( @@ -140,14 +142,14 @@ fun RelatedMangaTitle( ), ) { Text( - text = title.capitalize(), + text = title.capitalize(Locale.current), style = MaterialTheme.typography.titleMedium, ) if (subtitle != null) { Text(text = subtitle) } } - IconButton(onClick = onClick) { + if (showArrow) { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) } } diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt index f17ca3dc8..7c5a9e67c 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State @@ -56,6 +57,7 @@ fun RelatedMangasComfortableGrid( header(key = "$related#content") { RelatedMangasLoadingItem() } } else { val relatedManga = related as RelatedManga.Success + header(key = "${related.keyword}#divider") { HorizontalDivider() } header(key = "${related.keyword}#header") { RelatedMangaTitle( title = if (relatedManga.keyword.isNotBlank()) { diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt index 89e1f25b2..b288484f4 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State @@ -56,6 +57,7 @@ fun RelatedMangasCompactGrid( header(key = "$related#content") { RelatedMangasLoadingItem() } } else { val relatedManga = related as RelatedManga.Success + header(key = "${related.keyword}#divider") { HorizontalDivider() } header(key = "${related.keyword}#header") { RelatedMangaTitle( title = if (relatedManga.keyword.isNotBlank()) { diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt index 9c105428a..044ec1d46 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State @@ -39,6 +40,7 @@ fun RelatedMangasList( relatedMangas.forEach { related -> val isLoading = related is RelatedManga.Loading if (isLoading) { + item(key = "$related#divider") { HorizontalDivider() } stickyHeader(key = "$related#header") { RelatedMangaTitle( title = stringResource(MR.strings.loading), @@ -51,6 +53,7 @@ fun RelatedMangasList( item(key = "$related#content") { RelatedMangasLoadingItem() } } else { val relatedManga = related as RelatedManga.Success + item(key = "${related.keyword}#divider") { HorizontalDivider() } stickyHeader(key = "${related.keyword}#header") { RelatedMangaTitle( title = if (relatedManga.keyword.isNotBlank()) { diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index 48a9e093e..035d489fd 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -26,6 +26,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState @@ -51,6 +52,7 @@ import androidx.compose.ui.util.fastAll import androidx.compose.ui.util.fastAny import androidx.compose.ui.util.fastMap import eu.kanade.domain.source.service.SourcePreferences +import eu.kanade.domain.ui.UiPreferences import eu.kanade.presentation.browse.RelatedMangaTitle import eu.kanade.presentation.components.relativeDateText import eu.kanade.presentation.manga.components.ChapterDownloadAction @@ -63,6 +65,7 @@ import eu.kanade.presentation.manga.components.MangaInfoBox import eu.kanade.presentation.manga.components.MangaInfoButtons import eu.kanade.presentation.manga.components.MangaToolbar import eu.kanade.presentation.manga.components.MissingChapterCountListItem +import eu.kanade.presentation.manga.components.OutlinedButtonWithArrow import eu.kanade.presentation.manga.components.PagePreviewItems import eu.kanade.presentation.manga.components.PagePreviews import eu.kanade.presentation.manga.components.RelatedMangas @@ -382,6 +385,7 @@ private fun MangaScreenSmallImpl( // SY <-- // KMK --> val relatedMangasEnabled = Injekt.get().relatedMangas().get() + val expandRelatedMangas = Injekt.get().expandRelatedTitles().get() // KMK <-- val internalOnBackPressed = { @@ -578,26 +582,40 @@ private fun MangaScreenSmallImpl( // KMK --> if (state.source !is StubSource && relatedMangasEnabled) { - item( - key = MangaScreenItem.RELATED_TITLES, - contentType = MangaScreenItem.RELATED_TITLES, - ) { - Column { - RelatedMangaTitle( - title = stringResource(KMR.strings.pref_source_related_mangas), - subtitle = null, - onClick = onRelatedMangasScreenClick, - onLongClick = null, - ) - if (state.relatedMangasSorted == null || state.relatedMangasSorted.isNotEmpty()) { - RelatedMangas( - relatedMangas = state.relatedMangasSorted, - getMangaState = getMangaState, - onMangaClick = onRelatedMangaClick, - onMangaLongClick = onRelatedMangaLongClick, + if (expandRelatedMangas) { + item { HorizontalDivider() } + item( + key = MangaScreenItem.RELATED_TITLES, + contentType = MangaScreenItem.RELATED_TITLES, + ) { + Column { + RelatedMangaTitle( + title = stringResource(KMR.strings.pref_source_related_mangas), + subtitle = null, + onClick = onRelatedMangasScreenClick, + onLongClick = null, ) + if (state.relatedMangasSorted?.isNotEmpty() != false) { + RelatedMangas( + relatedMangas = state.relatedMangasSorted, + getMangaState = getMangaState, + onMangaClick = onRelatedMangaClick, + onMangaLongClick = onRelatedMangaLongClick, + ) + } } } + item { HorizontalDivider() } + } else { + item( + key = MangaScreenItem.RELATED_TITLES, + contentType = MangaScreenItem.RELATED_TITLES, + ) { + OutlinedButtonWithArrow( + text = stringResource(KMR.strings.pref_source_related_mangas), + onClick = onRelatedMangasScreenClick, + ) + } } } // KMK <-- @@ -747,6 +765,7 @@ private fun MangaScreenLargeImpl( // SY <-- // KMK --> val relatedMangasEnabled = Injekt.get().relatedMangas().get() + val expandRelatedMangas = Injekt.get().expandRelatedTitles().get() // KMK <-- val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues() @@ -947,22 +966,38 @@ private fun MangaScreenLargeImpl( ) { // KMK --> if (state.source !is StubSource && relatedMangasEnabled) { - item( - key = MangaScreenItem.RELATED_TITLES, - contentType = MangaScreenItem.RELATED_TITLES, - ) { - Column { - RelatedMangaTitle( - title = stringResource(KMR.strings.pref_source_related_mangas), - subtitle = null, + if (expandRelatedMangas) { + item { HorizontalDivider() } + item( + key = MangaScreenItem.RELATED_TITLES, + contentType = MangaScreenItem.RELATED_TITLES, + ) { + Column { + RelatedMangaTitle( + title = stringResource(KMR.strings.pref_source_related_mangas), + subtitle = null, + onClick = onRelatedMangasScreenClick, + onLongClick = null, + ) + if (state.relatedMangasSorted?.isNotEmpty() != false) { + RelatedMangas( + relatedMangas = state.relatedMangasSorted, + getMangaState = getMangaState, + onMangaClick = onRelatedMangaClick, + onMangaLongClick = onRelatedMangaLongClick, + ) + } + } + } + item { HorizontalDivider() } + } else { + item( + key = MangaScreenItem.RELATED_TITLES, + contentType = MangaScreenItem.RELATED_TITLES, + ) { + OutlinedButtonWithArrow( + text = stringResource(KMR.strings.pref_source_related_mangas), onClick = onRelatedMangasScreenClick, - onLongClick = null, - ) - RelatedMangas( - relatedMangas = state.relatedMangasSorted, - getMangaState = getMangaState, - onMangaClick = onRelatedMangaClick, - onMangaLongClick = onRelatedMangaLongClick ) } } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/OutlineButtonWithArrow.kt b/app/src/main/java/eu/kanade/presentation/manga/components/OutlineButtonWithArrow.kt new file mode 100644 index 000000000..cedd670f7 --- /dev/null +++ b/app/src/main/java/eu/kanade/presentation/manga/components/OutlineButtonWithArrow.kt @@ -0,0 +1,64 @@ +package eu.kanade.presentation.manga.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowForward +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import tachiyomi.presentation.core.components.material.padding + +@Composable +fun OutlinedButtonWithArrow( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + icon: ImageVector = Icons.AutoMirrored.Filled.ArrowForward, +) { + OutlinedButton( + onClick = onClick, + modifier = modifier + .fillMaxWidth() + .padding(MaterialTheme.padding.small), + colors = ButtonDefaults.outlinedButtonColors(), + shape = RoundedCornerShape(8.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = text.uppercase(), + ) + Spacer(modifier = Modifier.width(4.dp)) + Icon( + imageVector = icon, + contentDescription = "Arrow" + ) + } + } +} + +@Preview(showBackground = true) +@Composable +fun OutlinedButtonWithArrowPreview() { + OutlinedButtonWithArrow( + text = "Click Me", + onClick = { /* Do nothing */ } + ) +} diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt index 4866cfae9..7a8a020e2 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt @@ -13,6 +13,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow import com.materialkolor.PaletteStyle import eu.kanade.core.preference.asState +import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.model.TabletUiMode import eu.kanade.domain.ui.model.ThemeMode @@ -196,6 +197,7 @@ object SettingsAppearanceScreen : SearchableSettings { @Composable fun getForkGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup { val previewsRowCount by uiPreferences.previewsRowCount().collectAsState() + val sourcePreferences = remember { Injekt.get() } return Preference.PreferenceGroup( stringResource(SYMR.strings.pref_category_fork), @@ -204,6 +206,12 @@ object SettingsAppearanceScreen : SearchableSettings { pref = uiPreferences.expandFilters(), title = stringResource(SYMR.strings.toggle_expand_search_filters), ), + Preference.PreferenceItem.SwitchPreference( + pref = uiPreferences.expandRelatedTitles(), + title = stringResource(KMR.strings.pref_expand_related_titles), + subtitle = stringResource(KMR.strings.pref_expand_related_titles_summary), + enabled = sourcePreferences.relatedMangas().get(), + ), Preference.PreferenceItem.SwitchPreference( pref = uiPreferences.recommendsInOverflow(), title = stringResource(SYMR.strings.put_recommends_in_overflow), diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index df83b40d9..5c03946fc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalHapticFeedback import androidx.core.net.toUri import cafe.adriel.voyager.core.model.rememberScreenModel +import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.navigator.currentOrThrow @@ -90,6 +91,7 @@ import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch import logcat.LogPriority import tachiyomi.core.common.i18n.stringResource +import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchUI import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withNonCancellableContext @@ -282,6 +284,9 @@ class MangaScreen( // KMK --> getMangaState = { screenModel.getManga(initialManga = it) }, onRelatedMangasScreenClick = { + if (successState.isRelatedMangasFetched == null) { + screenModel.screenModelScope.launchIO { screenModel.fetchRelatedMangasFromSource(onDemand = true) } + } navigator.push( RelatedMangasScreen( mangaScreenModel = screenModel, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 6389a475b..f709bb6ac 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -172,8 +172,9 @@ class MangaScreenModel( private val downloadPreferences: DownloadPreferences = Injekt.get(), private val libraryPreferences: LibraryPreferences = Injekt.get(), readerPreferences: ReaderPreferences = Injekt.get(), - uiPreferences: UiPreferences = Injekt.get(), + private val uiPreferences: UiPreferences = Injekt.get(), // KMK --> + private val sourcePreferences: SourcePreferences = Injekt.get(), private val trackPreferences: TrackPreferences = Injekt.get(), private val trackChapter: TrackChapter = Injekt.get(), // KMK <-- @@ -461,18 +462,14 @@ class MangaScreenModel( // Fetch info-chapters when needed if (screenModelScope.isActive) { - // KMK --> - launch { - fetchRelatedMangasFromSource(onFinish = { - updateSuccessState { it.copy(isFetchingRelatedMangas = false) } - }) - } - // KMK <-- val fetchFromSourceTasks = listOf( async { syncTrackers() }, async { if (needRefreshInfo) fetchMangaFromSource() }, async { if (needRefreshChapter) fetchChaptersFromSource() }, ) + // KMK --> + launch { fetchRelatedMangasFromSource() } + // KMK <-- fetchFromSourceTasks.awaitAll() } @@ -1115,7 +1112,7 @@ class MangaScreenModel( val isLocal = manga.isLocal() // SY --> val isExhManga = manga.isEhBasedManga() - val enabledLanguages = Injekt.get().enabledLanguages().get() + val enabledLanguages = sourcePreferences.enabledLanguages().get() .filterNot { it in listOf("all", "other") } // SY <-- return map { chapter -> @@ -1219,10 +1216,26 @@ class MangaScreenModel( } // KMK --> + /** + * Set the fetching related mangas status. + * @param state + * - false: started & fetching + * - true: finished + */ + private fun setRelatedMangasFetchedStatus(state: Boolean) { + updateSuccessState { it.copy(isRelatedMangasFetched = state) } + } + /** * Requests an list of related mangas from the source. */ - private suspend fun fetchRelatedMangasFromSource(onFinish: () -> Unit) { + internal suspend fun fetchRelatedMangasFromSource(onDemand: Boolean = false, onFinish: (() -> Unit)? = null) { + val expandRelatedTitles = uiPreferences.expandRelatedTitles().get() + if (!onDemand && !expandRelatedTitles) return + + // start fetching related mangas + setRelatedMangasFetchedStatus(false) + fun exceptionHandler(e: Throwable) { logcat(LogPriority.ERROR, e) val message = with(context) { e.formattedMessage } @@ -1232,33 +1245,36 @@ class MangaScreenModel( } } val state = successState ?: return - val relatedMangasEnabled = Injekt.get().relatedMangas().get() - try { - if (state.source !is StubSource) { - if (relatedMangasEnabled) { - state.source.getRelatedMangaList(state.manga.toSManga(), { e -> exceptionHandler(e) }) { pair, _ -> - /* Push found related mangas into collection */ - val relatedManga = RelatedManga.Success.fromPair(pair) { mangaList -> - mangaList.map { - networkToLocalManga.await(it.toDomainManga(state.source.id)) - } - } + val relatedMangasEnabled = sourcePreferences.relatedMangas().get() - updateSuccessState { successState -> - val relatedMangaCollection = - successState.relatedMangaCollection - ?.toMutableStateList() - ?.apply { add(relatedManga) } - ?: listOf(relatedManga) - successState.copy(relatedMangaCollection = relatedMangaCollection) + try { + if (state.source !is StubSource && relatedMangasEnabled) { + state.source.getRelatedMangaList(state.manga.toSManga(), { e -> exceptionHandler(e) }) { pair, _ -> + /* Push found related mangas into collection */ + val relatedManga = RelatedManga.Success.fromPair(pair) { mangaList -> + mangaList.map { + networkToLocalManga.await(it.toDomainManga(state.source.id)) } } + + updateSuccessState { successState -> + val relatedMangaCollection = + successState.relatedMangaCollection + ?.toMutableStateList() + ?.apply { add(relatedManga) } + ?: listOf(relatedManga) + successState.copy(relatedMangaCollection = relatedMangaCollection) + } } } } catch (e: Exception) { exceptionHandler(e) } finally { - onFinish() + if (onFinish != null) { + onFinish() + } else { + setRelatedMangasFetchedStatus(true) + } } } // KMK <-- @@ -1870,7 +1886,13 @@ class MangaScreenModel( val previewsRowCount: Int, // SY <-- // KMK --> - val isFetchingRelatedMangas: Boolean = true, + /** + * status of fetching related mangas + * - null: not started + * - false: started & fetching + * - true: finished + */ + val isRelatedMangasFetched: Boolean? = null, /** * a list of */ @@ -1888,8 +1910,8 @@ class MangaScreenModel( ?.sorted(manga) ?.removeDuplicates(manga) ?.filter { it.isVisible() } - ?.isLoading(isFetchingRelatedMangas) - ?: if (!isFetchingRelatedMangas) emptyList() else null + ?.isLoading(isRelatedMangasFetched) + ?: if (isRelatedMangasFetched == true) emptyList() else null // KMK <-- val processedChapters by lazy { @@ -2051,12 +2073,8 @@ sealed interface RelatedManga { } } - internal fun List.isLoading(isFetchingRelatedMangas: Boolean): List { - return if (isFetchingRelatedMangas) { - this + listOf(Loading) - } else { - this - } + internal fun List.isLoading(isRelatedMangaFetched: Boolean?): List { + return if (isRelatedMangaFetched == false) this + listOf(Loading) else this } } } diff --git a/i18n-kmk/src/commonMain/resources/MR/base/strings.xml b/i18n-kmk/src/commonMain/resources/MR/base/strings.xml index fc1ab18de..233c9ddb2 100644 --- a/i18n-kmk/src/commonMain/resources/MR/base/strings.xml +++ b/i18n-kmk/src/commonMain/resources/MR/base/strings.xml @@ -12,6 +12,8 @@ Details page theme based on cover Theme style Theme animate + Expand Related titles + If turned off, related titles won\'t automatically load & show expanded Unofficial @@ -58,7 +60,7 @@ Change Logs - Related titles + Related Titles Show related titles while viewing entry More like these...