Add option to skip migration config

This commit is contained in:
AntsyLich
2025-06-02 11:07:02 +06:00
parent 2b126f1ff5
commit 8714653a2f
5 changed files with 155 additions and 2 deletions

View File

@ -66,4 +66,6 @@ class SourcePreferences(
serializer = { MigrationFlag.toBit(it) },
deserializer = { value: Int -> MigrationFlag.fromBit(value) },
)
fun skipMigrationConfig() = preferenceStore.getBoolean(Preference.appStateKey("skip_migration_config"), false)
}

View File

@ -71,6 +71,22 @@ object SettingsBrowseScreen : SearchableSettings {
Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.parental_controls_info)),
),
),
getMigrationCategory(sourcePreferences),
)
}
@Composable
fun getMigrationCategory(sourcePreferences: SourcePreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
stringResource(MR.strings.browseSettingsScreen_migrationCategoryHeader),
enabled = sourcePreferences.skipMigrationConfig().isSet(),
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
preference = sourcePreferences.skipMigrationConfig(),
title = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigTitle),
subtitle = stringResource(MR.strings.browseSettingsScreen_skipMigrationConfigSubtitle),
),
),
)
}
}

View File

@ -22,10 +22,14 @@ import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
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
import androidx.compose.ui.graphics.Color
@ -61,6 +65,7 @@ import tachiyomi.presentation.core.components.material.ExtendedFloatingActionBut
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.util.shouldExpandFAB
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -70,8 +75,28 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
val screenModel = rememberScreenModel { ScreenModel() }
val state by screenModel.state.collectAsState()
var migrationSheetOpen by rememberSaveable { mutableStateOf(false) }
fun continueMigration(openSheet: Boolean) {
if (openSheet) {
migrationSheetOpen = true
return
}
navigator.replace(MigrateSearchScreen(mangaId))
}
if (state.isLoading) {
LaunchedEffect(state.skipMigrationConfig) {
if (state.skipMigrationConfig) continueMigration(openSheet = false)
}
LoadingScreen()
return
}
val (selectedSources, availableSources) = state.sources.partition { it.isSelected }
val showLanguage by remember(state) {
derivedStateOf {
@ -118,7 +143,7 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
onClick = {
screenModel.saveSources()
navigator.replace(MigrateSearchScreen(mangaId))
continueMigration(openSheet = true)
},
expanded = lazyListState.shouldExpandFAB(),
)
@ -174,6 +199,17 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
}
}
}
if (migrationSheetOpen) {
MigrationConfigScreenSheet(
preferences = screenModel.sourcePreferences,
onDismissRequest = { migrationSheetOpen = false },
onStartMigration = {
migrationSheetOpen = false
continueMigration(openSheet = false)
},
)
}
}
@Composable
@ -270,13 +306,17 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
}
private class ScreenModel(
val sourcePreferences: SourcePreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(),
) : StateScreenModel<ScreenModel.State>(State()) {
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) }
}
}
@ -373,6 +413,8 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
}
data class State(
val isLoading: Boolean = true,
val skipMigrationConfig: Boolean = false,
val sources: List<MigrationSource> = emptyList(),
)

View File

@ -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),
)
}

View File

@ -1004,4 +1004,10 @@
<string name="migrationConfigScreen.selectEnabledLabel">Select enabled sources</string>
<string name="migrationConfigScreen.selectPinnedLabel">Select pinned sources</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>