mirror of
https://github.com/mihonapp/mihon.git
synced 2025-10-15 07:39:42 +02:00
Add more migration config options and remove skipping option (#2193)
This commit is contained in:
@@ -22,8 +22,6 @@ class SourcePreferences(
|
||||
|
||||
fun enabledLanguages() = preferenceStore.getStringSet("source_languages", LocaleHelper.getDefaultEnabledLanguages())
|
||||
|
||||
fun migrationSources() = preferenceStore.getLongArray("migration_sources", emptyList())
|
||||
|
||||
fun disabledSources() = preferenceStore.getStringSet("hidden_catalogues", emptySet())
|
||||
|
||||
fun incognitoExtensions() = preferenceStore.getStringSet("incognito_extensions", emptySet())
|
||||
@@ -60,12 +58,20 @@ class SourcePreferences(
|
||||
false,
|
||||
)
|
||||
|
||||
fun migrationSources() = preferenceStore.getLongArray("migration_sources", emptyList())
|
||||
|
||||
fun migrationFlags() = preferenceStore.getObjectFromInt(
|
||||
key = "migrate_flags",
|
||||
key = "migration_flags",
|
||||
defaultValue = MigrationFlag.entries.toSet(),
|
||||
serializer = { MigrationFlag.toBit(it) },
|
||||
deserializer = { value: Int -> MigrationFlag.fromBit(value) },
|
||||
)
|
||||
|
||||
fun skipMigrationConfig() = preferenceStore.getBoolean(Preference.appStateKey("skip_migration_config"), false)
|
||||
fun migrationDeepSearchMode() = preferenceStore.getBoolean("migration_deep_search", false)
|
||||
|
||||
fun migrationPrioritizeByChapters() = preferenceStore.getBoolean("migration_prioritize_by_chapters", false)
|
||||
|
||||
fun migrationHideUnmatched() = preferenceStore.getBoolean("migration_hide_unmatched", false)
|
||||
|
||||
fun migrationHideWithoutUpdates() = preferenceStore.getBoolean("migration_hide_without_updates", false)
|
||||
}
|
||||
|
@@ -71,22 +71,6 @@ 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),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ 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
|
||||
@@ -81,18 +80,11 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
|
||||
|
||||
var migrationSheetOpen by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
fun continueMigration(openSheet: Boolean) {
|
||||
if (openSheet) {
|
||||
migrationSheetOpen = true
|
||||
return
|
||||
}
|
||||
fun continueMigration(openSheet: Boolean, extraSearchQuery: String?) {
|
||||
navigator.replace(MigrateSearchScreen(mangaId))
|
||||
}
|
||||
|
||||
if (state.isLoading) {
|
||||
LaunchedEffect(state.skipMigrationConfig) {
|
||||
if (state.skipMigrationConfig) continueMigration(openSheet = false)
|
||||
}
|
||||
LoadingScreen()
|
||||
return
|
||||
}
|
||||
@@ -143,7 +135,7 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
|
||||
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
|
||||
onClick = {
|
||||
screenModel.saveSources()
|
||||
continueMigration(openSheet = true)
|
||||
continueMigration(openSheet = true, extraSearchQuery = null)
|
||||
},
|
||||
expanded = lazyListState.shouldExpandFAB(),
|
||||
)
|
||||
@@ -204,9 +196,9 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
|
||||
MigrationConfigScreenSheet(
|
||||
preferences = screenModel.sourcePreferences,
|
||||
onDismissRequest = { migrationSheetOpen = false },
|
||||
onStartMigration = {
|
||||
onStartMigration = { extraSearchQuery ->
|
||||
migrationSheetOpen = false
|
||||
continueMigration(openSheet = false)
|
||||
continueMigration(openSheet = false, extraSearchQuery = extraSearchQuery)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -312,9 +304,6 @@ class MigrationConfigScreen(private val mangaId: Long) : 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) }
|
||||
}
|
||||
@@ -414,7 +403,6 @@ class MigrationConfigScreen(private val mangaId: Long) : Screen() {
|
||||
|
||||
data class State(
|
||||
val isLoading: Boolean = true,
|
||||
val skipMigrationConfig: Boolean = false,
|
||||
val sources: List<MigrationSource> = emptyList(),
|
||||
)
|
||||
|
||||
|
@@ -3,60 +3,166 @@ 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.FlowRow
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Check
|
||||
import androidx.compose.material.icons.outlined.Warning
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
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 mihon.domain.migration.models.MigrationFlag
|
||||
import mihon.feature.common.utils.getLabel
|
||||
import tachiyomi.core.common.preference.Preference
|
||||
import tachiyomi.core.common.preference.getAndSet
|
||||
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.theme.active
|
||||
import tachiyomi.presentation.core.theme.header
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
|
||||
@Composable
|
||||
fun MigrationConfigScreenSheet(
|
||||
preferences: SourcePreferences,
|
||||
onDismissRequest: () -> Unit,
|
||||
onStartMigration: () -> Unit,
|
||||
onStartMigration: (extraSearchQuery: String?) -> Unit,
|
||||
) {
|
||||
val skipMigrationConfig by preferences.skipMigrationConfig().collectAsState()
|
||||
var extraSearchQuery by rememberSaveable { mutableStateOf("") }
|
||||
val migrationFlags by preferences.migrationFlags().collectAsState()
|
||||
AdaptiveSheet(onDismissRequest = onDismissRequest) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = false)
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(top = MaterialTheme.padding.medium),
|
||||
) {
|
||||
MigrationSheetItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_skipMigrationConfigTitle),
|
||||
subtitle = stringResource(MR.strings.migrationConfigScreen_skipMigrationConfigSubtitle),
|
||||
action = {
|
||||
Switch(
|
||||
checked = skipMigrationConfig,
|
||||
onCheckedChange = null,
|
||||
Text(
|
||||
text = stringResource(MR.strings.migrationConfigScreen_dataToMigrateHeader),
|
||||
style = MaterialTheme.typography.header,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = MaterialTheme.padding.extraSmall)
|
||||
.padding(horizontal = MaterialTheme.padding.medium),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(MaterialTheme.padding.extraSmall))
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = MaterialTheme.padding.medium)
|
||||
.padding(bottom = MaterialTheme.padding.extraSmall),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||
) {
|
||||
MigrationFlag.entries.forEach { flag ->
|
||||
if (flag == MigrationFlag.REMOVE_DOWNLOAD) return@forEach
|
||||
val selected = flag in migrationFlags
|
||||
FilterChip(
|
||||
selected = selected,
|
||||
onClick = {
|
||||
preferences.migrationFlags().getAndSet {
|
||||
if (selected) {
|
||||
it - flag
|
||||
} else {
|
||||
it + flag
|
||||
}
|
||||
}
|
||||
},
|
||||
label = { Text(stringResource(flag.getLabel())) },
|
||||
leadingIcon = {
|
||||
if (selected) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Check,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
val removeDownloads = MigrationFlag.REMOVE_DOWNLOAD in migrationFlags
|
||||
MigrationSheetSwitchItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_removeDownloadsTitle),
|
||||
subtitle = null,
|
||||
checked = removeDownloads,
|
||||
onClick = {
|
||||
preferences.migrationFlags().getAndSet {
|
||||
if (removeDownloads) {
|
||||
it - MigrationFlag.REMOVE_DOWNLOAD
|
||||
} else {
|
||||
it + MigrationFlag.REMOVE_DOWNLOAD
|
||||
}
|
||||
}
|
||||
},
|
||||
onClick = { preferences.skipMigrationConfig().toggle() },
|
||||
)
|
||||
MigrationSheetDividerItem()
|
||||
OutlinedTextField(
|
||||
value = extraSearchQuery,
|
||||
onValueChange = { extraSearchQuery = it },
|
||||
label = { Text(stringResource(MR.strings.migrationConfigScreen_additionalSearchQueryLabel)) },
|
||||
placeholder = {
|
||||
Text(stringResource(MR.strings.migrationConfigScreen_additionalSearchQueryPlaceholder))
|
||||
},
|
||||
supportingText = {
|
||||
Text(stringResource(MR.strings.migrationConfigScreen_additionalSearchQuerySupportingText))
|
||||
},
|
||||
singleLine = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.extraSmall,
|
||||
),
|
||||
)
|
||||
MigrationSheetSwitchItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_hideUnmatchedTitle),
|
||||
subtitle = null,
|
||||
preference = preferences.migrationHideUnmatched(),
|
||||
)
|
||||
MigrationSheetDividerItem()
|
||||
MigrationSheetWarningItem(stringResource(MR.strings.migrationConfigScreen_enhancedOptionsWarning))
|
||||
MigrationSheetSwitchItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_hideWithoutUpdatesTitle),
|
||||
subtitle = stringResource(MR.strings.migrationConfigScreen_hideWithoutUpdatesSubtitle),
|
||||
preference = preferences.migrationHideWithoutUpdates(),
|
||||
)
|
||||
MigrationSheetSwitchItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_deepSearchModeTitle),
|
||||
subtitle = stringResource(MR.strings.migrationConfigScreen_deepSearchModeSubtitle),
|
||||
preference = preferences.migrationDeepSearchMode(),
|
||||
)
|
||||
MigrationSheetSwitchItem(
|
||||
title = stringResource(MR.strings.migrationConfigScreen_prioritizeByChaptersTitle),
|
||||
subtitle = null,
|
||||
preference = preferences.migrationPrioritizeByChapters(),
|
||||
)
|
||||
}
|
||||
HorizontalDivider()
|
||||
Button(
|
||||
onClick = onStartMigration,
|
||||
onClick = { onStartMigration(extraSearchQuery) },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
@@ -71,17 +177,65 @@ fun MigrationConfigScreenSheet(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MigrationSheetItem(
|
||||
private fun MigrationSheetSwitchItem(
|
||||
title: String,
|
||||
subtitle: String?,
|
||||
action: @Composable () -> Unit,
|
||||
preference: Preference<Boolean>,
|
||||
) {
|
||||
val checked by preference.collectAsState()
|
||||
MigrationSheetSwitchItem(
|
||||
title = title,
|
||||
subtitle = subtitle,
|
||||
checked = checked,
|
||||
onClick = { preference.toggle() },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MigrationSheetSwitchItem(
|
||||
title: String,
|
||||
subtitle: String?,
|
||||
checked: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
ListItem(
|
||||
headlineContent = { Text(text = title) },
|
||||
supportingContent = subtitle?.let { { Text(text = subtitle) } },
|
||||
trailingContent = action,
|
||||
trailingContent = {
|
||||
Switch(
|
||||
checked = checked,
|
||||
onCheckedChange = null,
|
||||
)
|
||||
},
|
||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||
modifier = Modifier.clickable(onClick = onClick),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MigrationSheetDividerItem() {
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = MaterialTheme.padding.extraSmall))
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MigrationSheetWarningItem(
|
||||
text: String,
|
||||
) {
|
||||
ListItem(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Warning,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.active,
|
||||
)
|
||||
},
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = text,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier,
|
||||
)
|
||||
},
|
||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||
)
|
||||
}
|
||||
|
@@ -1004,10 +1004,16 @@
|
||||
<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>
|
||||
<string name="migrationConfigScreen.dataToMigrateHeader">Data to migrate</string>
|
||||
<string name="migrationConfigScreen.removeDownloadsTitle">Delete downloads after migration</string>
|
||||
<string name="migrationConfigScreen.additionalSearchQueryLabel">Additional search keywords</string>
|
||||
<string name="migrationConfigScreen.additionalSearchQueryPlaceholder">e.g. language:english</string>
|
||||
<string name="migrationConfigScreen.additionalSearchQuerySupportingText">Appends keywords to the search query</string>
|
||||
<string name="migrationConfigScreen.hideUnmatchedTitle">Hide unmatched manga</string>
|
||||
<string name="migrationConfigScreen.enhancedOptionsWarning">Settings below can be slower and may lead to temporary source restrictions</string>
|
||||
<string name="migrationConfigScreen.hideWithoutUpdatesTitle">Hide if no new chapters</string>
|
||||
<string name="migrationConfigScreen.hideWithoutUpdatesSubtitle">Show only if the match offers newer chapters</string>
|
||||
<string name="migrationConfigScreen.deepSearchModeTitle">Deep search mode</string>
|
||||
<string name="migrationConfigScreen.deepSearchModeSubtitle">More detailed keyword search</string>
|
||||
<string name="migrationConfigScreen.prioritizeByChaptersTitle">Prioritize by newer chapters</string>
|
||||
</resources>
|
||||
|
Reference in New Issue
Block a user