Add option to skip migration config
(cherry picked from commit 8714653a2f3b1a1f536494bcefbe66e7a7bbb4f7) Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
This commit is contained in:
parent
5ab24620ec
commit
2236e94f50
6 changed files with 168 additions and 37 deletions
|
|
@ -78,6 +78,8 @@ class SourcePreferences(
|
||||||
deserializer = { value: Int -> MigrationFlag.fromBit(value) },
|
deserializer = { value: Int -> MigrationFlag.fromBit(value) },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun skipMigrationConfig() = preferenceStore.getBoolean(Preference.appStateKey("skip_migration_config"), false)
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
fun globalSearchPinnedState() = preferenceStore.getEnum(
|
fun globalSearchPinnedState() = preferenceStore.getEnum(
|
||||||
Preference.appStateKey("global_search_pinned_toggle_state"),
|
Preference.appStateKey("global_search_pinned_toggle_state"),
|
||||||
|
|
@ -124,8 +126,6 @@ class SourcePreferences(
|
||||||
|
|
||||||
fun useSourceWithMost() = preferenceStore.getBoolean("use_source_with_most", false)
|
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 hideNotFoundMigration() = preferenceStore.getBoolean("hide_not_found_migration", false)
|
||||||
|
|
||||||
fun showOnlyUpdatesMigration() = preferenceStore.getBoolean("show_only_updates_migration", false)
|
fun showOnlyUpdatesMigration() = preferenceStore.getBoolean("show_only_updates_migration", false)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
object SettingsBrowseScreen : SearchableSettings {
|
object SettingsBrowseScreen : SearchableSettings {
|
||||||
|
@Suppress("unused")
|
||||||
private fun readResolve(): Any = SettingsBrowseScreen
|
private fun readResolve(): Any = SettingsBrowseScreen
|
||||||
|
|
||||||
@ReadOnlyComposable
|
@ReadOnlyComposable
|
||||||
|
|
@ -171,16 +172,14 @@ object SettingsBrowseScreen : SearchableSettings {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun getMigrationCategory(sourcePreferences: SourcePreferences): Preference.PreferenceGroup {
|
fun getMigrationCategory(sourcePreferences: SourcePreferences): Preference.PreferenceGroup {
|
||||||
val skipPreMigration by sourcePreferences.skipPreMigration().collectAsState()
|
|
||||||
val migrationSources by sourcePreferences.migrationSources().collectAsState()
|
|
||||||
return Preference.PreferenceGroup(
|
return Preference.PreferenceGroup(
|
||||||
stringResource(SYMR.strings.migration),
|
stringResource(MR.strings.browseSettingsScreen_migrationCategoryHeader),
|
||||||
enabled = skipPreMigration || migrationSources.isNotEmpty(),
|
enabled = sourcePreferences.skipMigrationConfig().isSet(),
|
||||||
preferenceItems = persistentListOf(
|
preferenceItems = persistentListOf(
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
preference = sourcePreferences.skipPreMigration(),
|
preference = sourcePreferences.skipMigrationConfig(),
|
||||||
title = stringResource(SYMR.strings.skip_pre_migration),
|
title = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigTitle),
|
||||||
subtitle = stringResource(SYMR.strings.pref_skip_pre_migration_summary),
|
subtitle = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigSubtitle),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ class MigrationBottomSheetDialogState(
|
||||||
}
|
}
|
||||||
sourceGroup.bindToPreference(preferences.useSourceWithMost())
|
sourceGroup.bindToPreference(preferences.useSourceWithMost())
|
||||||
|
|
||||||
skipStep.isChecked = preferences.skipPreMigration().get()
|
skipStep.isChecked = preferences.skipMigrationConfig().get()
|
||||||
hideNotFoundManga.isChecked = preferences.hideNotFoundMigration().get()
|
hideNotFoundManga.isChecked = preferences.hideNotFoundMigration().get()
|
||||||
onlyShowUpdates.isChecked = preferences.showOnlyUpdatesMigration().get()
|
onlyShowUpdates.isChecked = preferences.showOnlyUpdatesMigration().get()
|
||||||
skipStep.setOnCheckedChangeListener { _, isChecked ->
|
skipStep.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
|
@ -157,7 +157,7 @@ class MigrationBottomSheetDialogState(
|
||||||
}
|
}
|
||||||
|
|
||||||
migrateBtn.setOnClickListener {
|
migrateBtn.setOnClickListener {
|
||||||
preferences.skipPreMigration().set(skipStep.isChecked)
|
preferences.skipMigrationConfig().set(skipStep.isChecked)
|
||||||
preferences.hideNotFoundMigration().set(hideNotFoundManga.isChecked)
|
preferences.hideNotFoundMigration().set(hideNotFoundManga.isChecked)
|
||||||
preferences.showOnlyUpdatesMigration().set(onlyShowUpdates.isChecked)
|
preferences.showOnlyUpdatesMigration().set(onlyShowUpdates.isChecked)
|
||||||
onStartMigration.value(
|
onStartMigration.value(
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,13 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.SmallExtendedFloatingActionButton
|
import androidx.compose.material3.SmallExtendedFloatingActionButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.ui.browse.migration.advanced.process.MigrationType
|
||||||
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.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
|
||||||
import kotlinx.coroutines.flow.update
|
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
|
||||||
|
|
@ -82,6 +82,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import tachiyomi.presentation.core.icons.FlagEmoji
|
import tachiyomi.presentation.core.icons.FlagEmoji
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import tachiyomi.presentation.core.util.shouldExpandFAB
|
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
|
||||||
|
|
@ -99,6 +100,7 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { ScreenModel() }
|
val screenModel = rememberScreenModel { ScreenModel() }
|
||||||
// KMK -->
|
// KMK -->
|
||||||
var searchQuery by remember { mutableStateOf("") }
|
var searchQuery by remember { mutableStateOf("") }
|
||||||
|
|
@ -107,6 +109,44 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
}
|
}
|
||||||
// KMK <--
|
// KMK <--
|
||||||
val state by screenModel.state.collectAsState()
|
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
|
val (selectedSources, availableSources) = state.sources
|
||||||
// KMK -->
|
// KMK -->
|
||||||
.filter { sources ->
|
.filter { sources ->
|
||||||
|
|
@ -173,9 +213,7 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
|
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
|
||||||
onClick = {
|
onClick = {
|
||||||
screenModel.saveSources()
|
screenModel.saveSources()
|
||||||
// KMK -->
|
continueMigration(openSheet = true)
|
||||||
screenModel.onMigrationSheet(true)
|
|
||||||
// KMK <--
|
|
||||||
},
|
},
|
||||||
expanded = lazyListState.shouldExpandFAB(),
|
expanded = lazyListState.shouldExpandFAB(),
|
||||||
)
|
)
|
||||||
|
|
@ -263,20 +301,24 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// KMK -->
|
|
||||||
val migrationSheetOpen by screenModel.migrationSheetOpen.collectAsState()
|
|
||||||
if (migrationSheetOpen) {
|
if (migrationSheetOpen) {
|
||||||
|
MigrationConfigScreenSheet(
|
||||||
|
preferences = screenModel.sourcePreferences,
|
||||||
|
onDismissRequest = { migrationSheetOpen = false },
|
||||||
|
onStartMigration = {
|
||||||
|
migrationSheetOpen = false
|
||||||
|
continueMigration(openSheet = false)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KMK -->
|
||||||
|
if (migrationBottomSheetDialog) {
|
||||||
MigrationBottomSheetDialog(
|
MigrationBottomSheetDialog(
|
||||||
onDismissRequest = { screenModel.onMigrationSheet(false) },
|
onDismissRequest = { migrationBottomSheetDialog = false },
|
||||||
onStartMigration = { extraParam ->
|
onStartMigration = { extraParam ->
|
||||||
screenModel.onMigrationSheet(false)
|
migrationBottomSheetDialog = false
|
||||||
navigator.replace(
|
continueMigrationBottom(openSheet = false, extraParam)
|
||||||
// KMK -->
|
|
||||||
MigrationListScreen(
|
|
||||||
MigrationProcedureConfig(MigrationType.MangaList(mangaIds), extraParam),
|
|
||||||
),
|
|
||||||
// KMK <--
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -379,8 +421,8 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ScreenModel(
|
private class ScreenModel(
|
||||||
|
val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val sourcePreferences: SourcePreferences = Injekt.get(),
|
|
||||||
) : StateScreenModel<ScreenModel.State>(State()) {
|
) : StateScreenModel<ScreenModel.State>(State()) {
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
|
|
@ -390,19 +432,14 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
screenModelScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
|
val skipMigrationConfig = sourcePreferences.skipMigrationConfig().get()
|
||||||
|
mutableState.update { it.copy(skipMigrationConfig = skipMigrationConfig) }
|
||||||
|
if (skipMigrationConfig) return@launchIO
|
||||||
initSources()
|
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<Long, Int> /* KMK <-- */ ->
|
private val sourcesComparator = { includedSources: /* KMK --> */ Map<Long, Int> /* KMK <-- */ ->
|
||||||
compareBy<MigrationSource>(
|
compareBy<MigrationSource>(
|
||||||
// KMK -->
|
// KMK -->
|
||||||
|
|
@ -505,6 +542,8 @@ class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
data class State(
|
data class State(
|
||||||
|
val isLoading: Boolean = true,
|
||||||
|
val skipMigrationConfig: Boolean = false,
|
||||||
val sources: List<MigrationSource> = emptyList(),
|
val sources: List<MigrationSource> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1015,4 +1015,10 @@
|
||||||
<string name="migrationConfigScreen.selectEnabledLabel">Select enabled sources</string>
|
<string name="migrationConfigScreen.selectEnabledLabel">Select enabled sources</string>
|
||||||
<string name="migrationConfigScreen.selectPinnedLabel">Select pinned sources</string>
|
<string name="migrationConfigScreen.selectPinnedLabel">Select pinned sources</string>
|
||||||
<string name="migrationConfigScreen.continueButtonText">Continue</string>
|
<string name="migrationConfigScreen.continueButtonText">Continue</string>
|
||||||
|
<string name="migrationConfigScreen.skipMigrationConfigTitle">Skip migration config</string>
|
||||||
|
<string name="migrationConfigScreen.skipMigrationConfigSubtitle">To show this screen again in the future, disable skipping in Settings → Browse</string>
|
||||||
|
|
||||||
|
<string name="browseSettingsScreen.migrationCategoryHeader">Migration</string>
|
||||||
|
<string name="browseSettingsScreen.skipMigrationConfigTitle">Skip migration config</string>
|
||||||
|
<string name="browseSettingsScreen.skipMigrationConfigSubtitle">Use last used sources and preferences for migration</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue