Fix no sources while migrating alongside UI and code cleanup (#2155)

This commit is contained in:
AntsyLich
2025-05-31 16:11:49 +06:00
committed by GitHub
parent a4df33caf9
commit 5919f34fc9
4 changed files with 47 additions and 33 deletions

View File

@@ -13,7 +13,7 @@ import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import mihon.feature.migration.MigrateMangaConfigScreen import mihon.feature.migration.config.MigrationConfigScreen
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
@@ -38,7 +38,7 @@ data class MigrateMangaScreen(
navigateUp = navigator::pop, navigateUp = navigator::pop,
title = state.source!!.name, title = state.source!!.name,
state = state, state = state,
onClickItem = { navigator.push(MigrateMangaConfigScreen(it.id)) }, onClickItem = { navigator.push(MigrationConfigScreen(it.id)) },
onClickCover = { navigator.push(MangaScreen(it.id)) }, onClickCover = { navigator.push(MangaScreen(it.id)) },
) )

View File

@@ -59,7 +59,7 @@ import eu.kanade.tachiyomi.util.system.toShareIntent
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import logcat.LogPriority import logcat.LogPriority
import mihon.feature.migration.MigrateMangaConfigScreen import mihon.feature.migration.config.MigrationConfigScreen
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
@@ -163,7 +163,7 @@ class MangaScreen(
successState.manga.favorite successState.manga.favorite
}, },
onMigrateClicked = { onMigrateClicked = {
navigator.push(MigrateMangaConfigScreen(successState.manga.id)) navigator.push(MigrationConfigScreen(successState.manga.id))
}.takeIf { successState.manga.favorite }, }.takeIf { successState.manga.favorite },
onEditNotesClicked = { navigator.push(MangaNotesScreen(manga = successState.manga)) }, onEditNotesClicked = { navigator.push(MangaNotesScreen(manga = successState.manga)) },
onMultiBookmarkClicked = screenModel::bookmarkChapters, onMultiBookmarkClicked = screenModel::bookmarkChapters,

View File

@@ -48,6 +48,17 @@ object LocaleHelper {
return Locale.forLanguageTag(normalizedLang).displayName return Locale.forLanguageTag(normalizedLang).displayName
} }
fun getShortDisplayName(lang: String?, uppercase: Boolean = false): String {
return when (lang) {
null -> ""
"es-419" -> "es-la"
"zh-CN" -> "zh-hans"
"zh-TW" -> "zh-hant"
else -> lang
}
.let { if (uppercase) it.uppercase(Locale.ENGLISH) else it }
}
/** /**
* Returns display name of a string language code. * Returns display name of a string language code.
* *

View File

@@ -1,4 +1,4 @@
package mihon.feature.migration package mihon.feature.migration.config
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -28,7 +28,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -47,7 +46,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreen import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreen
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.flow.update
import sh.calvin.reorderable.ReorderableCollectionItemScope import sh.calvin.reorderable.ReorderableCollectionItemScope
import sh.calvin.reorderable.ReorderableItem import sh.calvin.reorderable.ReorderableItem
import sh.calvin.reorderable.ReorderableLazyListState import sh.calvin.reorderable.ReorderableLazyListState
@@ -58,7 +57,6 @@ import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.Pill import tachiyomi.presentation.core.components.Pill
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
@@ -67,7 +65,7 @@ import tachiyomi.presentation.core.util.shouldExpandFAB
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() { class MigrationConfigScreen(private val mangaId: Long) : Screen() {
@Composable @Composable
override fun Content() { override fun Content() {
@@ -118,7 +116,10 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) }, text = { Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) },
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) }, icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
onClick = { navigator.replace(MigrateSearchScreen(mangaId)) }, onClick = {
screenModel.saveSources()
navigator.replace(MigrateSearchScreen(mangaId))
},
expanded = lazyListState.shouldExpandFAB(), expanded = lazyListState.shouldExpandFAB(),
) )
}, },
@@ -162,9 +163,8 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
SourceItemContainer( SourceItemContainer(
firstItem = index == 0, firstItem = index == 0,
lastItem = index == (sources.size - 1), lastItem = index == (sources.size - 1),
source = item.source, source = item,
showLanguage = showLanguage, showLanguage = showLanguage,
isSelected = item.isSelected,
dragEnabled = selectedSourceList && sources.size > 1, dragEnabled = selectedSourceList && sources.size > 1,
state = reorderableState, state = reorderableState,
key = { if (selectedSourceList) it.id else "available-${it.id}" }, key = { if (selectedSourceList) it.id else "available-${it.id}" },
@@ -180,12 +180,11 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
private fun LazyItemScope.SourceItemContainer( private fun LazyItemScope.SourceItemContainer(
firstItem: Boolean, firstItem: Boolean,
lastItem: Boolean, lastItem: Boolean,
source: Source, source: MigrationSource,
showLanguage: Boolean, showLanguage: Boolean,
isSelected: Boolean,
dragEnabled: Boolean, dragEnabled: Boolean,
state: ReorderableLazyListState, state: ReorderableLazyListState,
key: (Source) -> Any, key: (MigrationSource) -> Any,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
val shape = remember(firstItem, lastItem) { val shape = remember(firstItem, lastItem) {
@@ -208,7 +207,6 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
SourceItem( SourceItem(
source = source, source = source,
showLanguage = showLanguage, showLanguage = showLanguage,
isSelected = isSelected,
dragEnabled = dragEnabled, dragEnabled = dragEnabled,
scope = this@ReorderableItem, scope = this@ReorderableItem,
onClick = onClick, onClick = onClick,
@@ -223,9 +221,8 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
@Composable @Composable
private fun SourceItem( private fun SourceItem(
source: Source, source: MigrationSource,
showLanguage: Boolean, showLanguage: Boolean,
isSelected: Boolean,
dragEnabled: Boolean, dragEnabled: Boolean,
scope: ReorderableCollectionItemScope, scope: ReorderableCollectionItemScope,
onClick: () -> Unit, onClick: () -> Unit,
@@ -236,7 +233,7 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small), horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
SourceIcon(source = source) SourceIcon(source = source.source)
Text( Text(
text = source.name, text = source.name,
maxLines = 1, maxLines = 1,
@@ -246,7 +243,7 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
) )
if (showLanguage) { if (showLanguage) {
Pill( Pill(
text = LocaleHelper.getLocalizedDisplayName(source.lang), text = LocaleHelper.getShortDisplayName(source.shortLanguage, uppercase = true),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
) )
} }
@@ -268,9 +265,7 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
colors = ListItemDefaults.colors( colors = ListItemDefaults.colors(
containerColor = Color.Transparent, containerColor = Color.Transparent,
), ),
modifier = Modifier modifier = Modifier.clickable(onClick = onClick),
.clickable(onClick = onClick)
.alpha(if (isSelected) 1f else DISABLED_ALPHA),
) )
} }
@@ -288,22 +283,18 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
private val sourcesComparator = { includedSources: List<Long> -> private val sourcesComparator = { includedSources: List<Long> ->
compareBy<MigrationSource>( compareBy<MigrationSource>(
{ !it.isSelected }, { !it.isSelected },
{ includedSources.indexOf(it.source.id) }, { includedSources.indexOf(it.id) },
{ with(it.source) { "$name (${LocaleHelper.getLocalizedDisplayName(lang)})" } }, { with(it) { "$name ($shortLanguage)" } },
) )
} }
private fun updateSources(save: Boolean = true, action: (List<MigrationSource>) -> List<MigrationSource>) { private fun updateSources(save: Boolean = true, action: (List<MigrationSource>) -> List<MigrationSource>) {
val state = mutableState.updateAndGet { state -> mutableState.update { state ->
val updatedSources = action(state.sources) val updatedSources = action(state.sources)
val includedSources = updatedSources.mapNotNull { if (!it.isSelected) null else it.id } val includedSources = updatedSources.mapNotNull { if (!it.isSelected) null else it.id }
state.copy(sources = updatedSources.sortedWith(sourcesComparator(includedSources))) state.copy(sources = updatedSources.sortedWith(sourcesComparator(includedSources)))
} }
if (!save) return if (save) saveSources()
state.sources
.filter { source -> source.isSelected }
.map { source -> source.source.id }
.let { sources -> sourcePreferences.migrationSources().set(sources) }
} }
private fun initSources() { private fun initSources() {
@@ -374,6 +365,13 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
} }
} }
fun saveSources() {
state.value.sources
.filter { source -> source.isSelected }
.map { source -> source.source.id }
.let { sources -> sourcePreferences.migrationSources().set(sources) }
}
data class State( data class State(
val sources: List<MigrationSource> = emptyList(), val sources: List<MigrationSource> = emptyList(),
) )
@@ -390,7 +388,12 @@ class MigrateMangaConfigScreen(private val mangaId: Long) : Screen() {
val source: Source, val source: Source,
val isSelected: Boolean, val isSelected: Boolean,
) { ) {
val id = source.id val id: Long
val visualName = source.visualName inline get() = source.id
val name: String
inline get() = source.name
val shortLanguage: String = LocaleHelper.getShortDisplayName(source.lang)
} }
} }