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