Allow creating backups without library entries

- In case you want a backup of just settings?
- Also disable backup options if dependent option is disabled (and fix being able to toggle disabled items)
- Also fix crash in RestoreBackupScreen due to attempt to parcelize Uri
- Make restore validation message a bit nicer
This commit is contained in:
arkon
2023-12-30 16:02:36 -05:00
parent f3b7eaf4a3
commit f0a0ecfd4a
10 changed files with 92 additions and 58 deletions

View File

@@ -155,7 +155,7 @@ object SettingsDataScreen : SearchableSettings {
return@rememberLauncherForActivityResult
}
navigator.push(RestoreBackupScreen(it))
navigator.push(RestoreBackupScreen(it.toString()))
}
return Preference.PreferenceGroup(

View File

@@ -92,17 +92,7 @@ class CreateBackupScreen : Screen() {
item {
SectionCard(MR.strings.label_library) {
Column {
LabeledCheckbox(
label = stringResource(MR.strings.manga),
checked = true,
onCheckedChange = {},
enabled = false,
modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium),
)
Options(BackupOptions.libraryOptions, state, model)
}
Options(BackupOptions.libraryOptions, state, model)
}
}
@@ -153,6 +143,7 @@ class CreateBackupScreen : Screen() {
onCheckedChange = {
model.toggle(option.setter, it)
},
enabled = option.enabled(state.options),
modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium),
)
}

View File

@@ -20,7 +20,12 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -33,6 +38,7 @@ import eu.kanade.tachiyomi.data.backup.restore.BackupRestoreJob
import eu.kanade.tachiyomi.data.backup.restore.RestoreOptions
import eu.kanade.tachiyomi.util.system.DeviceUtil
import kotlinx.coroutines.flow.update
import tachiyomi.core.util.lang.anyEnabled
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.SectionCard
@@ -41,7 +47,7 @@ import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
class RestoreBackupScreen(
private val uri: Uri,
private val uri: String,
) : Screen() {
@Composable
@@ -99,10 +105,10 @@ class RestoreBackupScreen(
HorizontalDivider()
Button(
enabled = state.canRestore && state.options.anyEnabled(),
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.fillMaxWidth(),
enabled = state.canRestore && state.options.anyEnabled(),
onClick = {
model.startRestore()
navigator.pop()
@@ -126,47 +132,56 @@ class RestoreBackupScreen(
modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
when (error) {
is MissingRestoreComponents -> {
val msg = buildString {
append(stringResource(MR.strings.backup_restore_content_full))
val msg = buildAnnotatedString {
when (error) {
is MissingRestoreComponents -> {
appendLine(stringResource(MR.strings.backup_restore_content_full))
if (error.sources.isNotEmpty()) {
append("\n\n")
append(stringResource(MR.strings.backup_restore_missing_sources))
appendLine()
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
appendLine(stringResource(MR.strings.backup_restore_missing_sources))
}
error.sources.joinTo(
this,
separator = "\n- ",
prefix = "\n- ",
prefix = "- ",
)
}
if (error.trackers.isNotEmpty()) {
append("\n\n")
append(stringResource(MR.strings.backup_restore_missing_trackers))
appendLine()
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
appendLine(stringResource(MR.strings.backup_restore_missing_trackers))
}
error.trackers.joinTo(
this,
separator = "\n- ",
prefix = "\n- ",
prefix = "- ",
)
}
}
SelectionContainer {
Text(text = msg)
is InvalidRestore -> {
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
appendLine(stringResource(MR.strings.invalid_backup_file))
}
appendLine(error.uri.toString())
appendLine()
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
appendLine(stringResource(MR.strings.invalid_backup_file_error))
}
appendLine(error.message)
}
else -> {
appendLine(error.toString())
}
}
}
is InvalidRestore -> {
Text(text = stringResource(MR.strings.invalid_backup_file))
SelectionContainer {
Text(text = listOfNotNull(error.uri, error.message).joinToString("\n\n"))
}
}
else -> {
SelectionContainer {
Text(text = error.toString())
}
}
SelectionContainer {
Text(text = msg)
}
}
}
@@ -176,11 +191,11 @@ class RestoreBackupScreen(
private class RestoreBackupScreenModel(
private val context: Context,
private val uri: Uri,
private val uri: String,
) : StateScreenModel<RestoreBackupScreenModel.State>(State()) {
init {
validate(uri)
validate(uri.toUri())
}
fun toggle(setter: (RestoreOptions, Boolean) -> RestoreOptions, enabled: Boolean) {
@@ -194,7 +209,7 @@ private class RestoreBackupScreenModel(
fun startRestore() {
BackupRestoreJob.start(
context = context,
uri = uri,
uri = uri.toUri(),
options = state.value.options,
)
}