From 2236e94f5073ff878cde5aed0b74b396e9d2222f Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Mon, 2 Jun 2025 11:07:02 +0600 Subject: [PATCH] Add option to skip migration config (cherry picked from commit 8714653a2f3b1a1f536494bcefbe66e7a7bbb4f7) Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com> --- .../source/service/SourcePreferences.kt | 4 +- .../settings/screen/SettingsBrowseScreen.kt | 13 ++- .../design/MigrationBottomSheetDialog.kt | 4 +- .../migration/config/MigrationConfigScreen.kt | 91 +++++++++++++------ .../config/MigrationConfigScreenSheet.kt | 87 ++++++++++++++++++ .../moko-resources/base/strings.xml | 6 ++ 6 files changed, 168 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/mihon/feature/migration/config/MigrationConfigScreenSheet.kt diff --git a/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt b/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt index 85dba78a2..2c3ca0115 100644 --- a/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt +++ b/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt @@ -78,6 +78,8 @@ class SourcePreferences( deserializer = { value: Int -> MigrationFlag.fromBit(value) }, ) + fun skipMigrationConfig() = preferenceStore.getBoolean(Preference.appStateKey("skip_migration_config"), false) + // KMK --> fun globalSearchPinnedState() = preferenceStore.getEnum( Preference.appStateKey("global_search_pinned_toggle_state"), @@ -124,8 +126,6 @@ class SourcePreferences( fun useSourceWithMost() = preferenceStore.getBoolean("use_source_with_most", false) - fun skipPreMigration() = preferenceStore.getBoolean(Preference.appStateKey("skip_pre_migration"), false) - fun hideNotFoundMigration() = preferenceStore.getBoolean("hide_not_found_migration", false) fun showOnlyUpdatesMigration() = preferenceStore.getBoolean("show_only_updates_migration", false) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt index db932297e..5d1898529 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt @@ -30,6 +30,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get object SettingsBrowseScreen : SearchableSettings { + @Suppress("unused") private fun readResolve(): Any = SettingsBrowseScreen @ReadOnlyComposable @@ -171,16 +172,14 @@ object SettingsBrowseScreen : SearchableSettings { @Composable fun getMigrationCategory(sourcePreferences: SourcePreferences): Preference.PreferenceGroup { - val skipPreMigration by sourcePreferences.skipPreMigration().collectAsState() - val migrationSources by sourcePreferences.migrationSources().collectAsState() return Preference.PreferenceGroup( - stringResource(SYMR.strings.migration), - enabled = skipPreMigration || migrationSources.isNotEmpty(), + stringResource(MR.strings.browseSettingsScreen_migrationCategoryHeader), + enabled = sourcePreferences.skipMigrationConfig().isSet(), preferenceItems = persistentListOf( Preference.PreferenceItem.SwitchPreference( - preference = sourcePreferences.skipPreMigration(), - title = stringResource(SYMR.strings.skip_pre_migration), - subtitle = stringResource(SYMR.strings.pref_skip_pre_migration_summary), + preference = sourcePreferences.skipMigrationConfig(), + title = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigTitle), + subtitle = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigSubtitle), ), ), ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/design/MigrationBottomSheetDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/design/MigrationBottomSheetDialog.kt index 15f3f96eb..e15cbf839 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/design/MigrationBottomSheetDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/design/MigrationBottomSheetDialog.kt @@ -144,7 +144,7 @@ class MigrationBottomSheetDialogState( } sourceGroup.bindToPreference(preferences.useSourceWithMost()) - skipStep.isChecked = preferences.skipPreMigration().get() + skipStep.isChecked = preferences.skipMigrationConfig().get() hideNotFoundManga.isChecked = preferences.hideNotFoundMigration().get() onlyShowUpdates.isChecked = preferences.showOnlyUpdatesMigration().get() skipStep.setOnCheckedChangeListener { _, isChecked -> @@ -157,7 +157,7 @@ class MigrationBottomSheetDialogState( } migrateBtn.setOnClickListener { - preferences.skipPreMigration().set(skipStep.isChecked) + preferences.skipMigrationConfig().set(skipStep.isChecked) preferences.hideNotFoundMigration().set(hideNotFoundManga.isChecked) preferences.showOnlyUpdatesMigration().set(onlyShowUpdates.isChecked) onStartMigration.value( diff --git a/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreen.kt b/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreen.kt index ba90416fe..e532d0701 100644 --- a/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreen.kt +++ b/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreen.kt @@ -30,11 +30,13 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SmallExtendedFloatingActionButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -63,8 +65,6 @@ import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationProcedu import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationType import eu.kanade.tachiyomi.util.system.LocaleHelper import kotlinx.collections.immutable.persistentListOf -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import sh.calvin.reorderable.ReorderableCollectionItemScope import sh.calvin.reorderable.ReorderableItem @@ -82,6 +82,7 @@ import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.icons.FlagEmoji +import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.util.shouldExpandFAB import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -99,6 +100,7 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { @Composable override fun Content() { val navigator = LocalNavigator.currentOrThrow + val screenModel = rememberScreenModel { ScreenModel() } // KMK --> var searchQuery by remember { mutableStateOf("") } @@ -107,6 +109,44 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { } // KMK <-- val state by screenModel.state.collectAsState() + + var migrationSheetOpen by rememberSaveable { mutableStateOf(false) } + // KMK --> + var migrationBottomSheetDialog by rememberSaveable { mutableStateOf(false) } + + fun continueMigrationBottom(openSheet: Boolean, extraParam: String? = null) { + if (openSheet) { + migrationBottomSheetDialog = true + return + } + navigator.replace( + // KMK --> + MigrationListScreen( + MigrationProcedureConfig(MigrationType.MangaList(mangaIds), extraParam), + ), + // KMK <-- + ) + } + // KMK <-- + + fun continueMigration(openSheet: Boolean) { + if (openSheet) { + migrationSheetOpen = true + return + } + // KMK --> + continueMigrationBottom(true) + // KMK <-- + } + + if (state.isLoading) { + LaunchedEffect(state.skipMigrationConfig) { + if (state.skipMigrationConfig) continueMigration(openSheet = false) + } + LoadingScreen() + return + } + val (selectedSources, availableSources) = state.sources // KMK --> .filter { sources -> @@ -173,9 +213,7 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) }, onClick = { screenModel.saveSources() - // KMK --> - screenModel.onMigrationSheet(true) - // KMK <-- + continueMigration(openSheet = true) }, expanded = lazyListState.shouldExpandFAB(), ) @@ -263,20 +301,24 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { } } - // KMK --> - val migrationSheetOpen by screenModel.migrationSheetOpen.collectAsState() if (migrationSheetOpen) { + MigrationConfigScreenSheet( + preferences = screenModel.sourcePreferences, + onDismissRequest = { migrationSheetOpen = false }, + onStartMigration = { + migrationSheetOpen = false + continueMigration(openSheet = false) + }, + ) + } + + // KMK --> + if (migrationBottomSheetDialog) { MigrationBottomSheetDialog( - onDismissRequest = { screenModel.onMigrationSheet(false) }, + onDismissRequest = { migrationBottomSheetDialog = false }, onStartMigration = { extraParam -> - screenModel.onMigrationSheet(false) - navigator.replace( - // KMK --> - MigrationListScreen( - MigrationProcedureConfig(MigrationType.MangaList(mangaIds), extraParam), - ), - // KMK <-- - ) + migrationBottomSheetDialog = false + continueMigrationBottom(openSheet = false, extraParam) }, ) } @@ -379,8 +421,8 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { } private class ScreenModel( + val sourcePreferences: SourcePreferences = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), - private val sourcePreferences: SourcePreferences = Injekt.get(), ) : StateScreenModel(State()) { // KMK --> @@ -390,19 +432,14 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { init { screenModelScope.launchIO { + val skipMigrationConfig = sourcePreferences.skipMigrationConfig().get() + mutableState.update { it.copy(skipMigrationConfig = skipMigrationConfig) } + if (skipMigrationConfig) return@launchIO initSources() + mutableState.update { it.copy(isLoading = false) } } } - // KMK --> - private val _migrationSheetOpen = MutableStateFlow(false) - val migrationSheetOpen = _migrationSheetOpen.asStateFlow() - - fun onMigrationSheet(isOpen: Boolean) { - _migrationSheetOpen.value = isOpen - } - // KMK <-- - private val sourcesComparator = { includedSources: /* KMK --> */ Map /* KMK <-- */ -> compareBy( // KMK --> @@ -505,6 +542,8 @@ class MigrationConfigScreen(private val mangaIds: List) : Screen() { } data class State( + val isLoading: Boolean = true, + val skipMigrationConfig: Boolean = false, val sources: List = emptyList(), ) diff --git a/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreenSheet.kt b/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreenSheet.kt new file mode 100644 index 000000000..a53aa56d3 --- /dev/null +++ b/app/src/main/java/mihon/feature/migration/config/MigrationConfigScreenSheet.kt @@ -0,0 +1,87 @@ +package mihon.feature.migration.config + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import eu.kanade.domain.source.service.SourcePreferences +import eu.kanade.presentation.components.AdaptiveSheet +import tachiyomi.core.common.preference.toggle +import tachiyomi.i18n.MR +import tachiyomi.presentation.core.components.material.Button +import tachiyomi.presentation.core.components.material.padding +import tachiyomi.presentation.core.i18n.stringResource +import tachiyomi.presentation.core.util.collectAsState + +@Composable +fun MigrationConfigScreenSheet( + preferences: SourcePreferences, + onDismissRequest: () -> Unit, + onStartMigration: () -> Unit, +) { + val skipMigrationConfig by preferences.skipMigrationConfig().collectAsState() + AdaptiveSheet(onDismissRequest = onDismissRequest) { + Column(modifier = Modifier.fillMaxWidth()) { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + MigrationSheetItem( + title = stringResource(MR.strings.migrationConfigScreen_skipMigrationConfigTitle), + subtitle = stringResource(MR.strings.migrationConfigScreen_skipMigrationConfigSubtitle), + action = { + Switch( + checked = skipMigrationConfig, + onCheckedChange = null, + ) + }, + onClick = { preferences.skipMigrationConfig().toggle() }, + ) + } + HorizontalDivider() + Button( + onClick = onStartMigration, + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = MaterialTheme.padding.medium, + vertical = MaterialTheme.padding.small, + ), + ) { + Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) + } + } + } +} + +@Composable +private fun MigrationSheetItem( + title: String, + subtitle: String?, + action: @Composable () -> Unit, + onClick: () -> Unit, +) { + ListItem( + headlineContent = { Text(text = title) }, + supportingContent = subtitle?.let { { Text(text = subtitle) } }, + trailingContent = action, + colors = ListItemDefaults.colors(containerColor = Color.Transparent), + modifier = Modifier.clickable(onClick = onClick), + ) +} diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index 287e49541..8e31f41be 100644 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -1015,4 +1015,10 @@ Select enabled sources Select pinned sources Continue + Skip migration config + To show this screen again in the future, disable skipping in Settings → Browse + + Migration + Skip migration config + Use last used sources and preferences for migration