merge backup and sync screens

This commit is contained in:
Aria Moradi 2023-07-07 22:20:17 +03:30
parent 6d9f74d0bf
commit a1e9d34bb8
8 changed files with 219 additions and 267 deletions

View File

@ -17,7 +17,6 @@ import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.QueryStats import androidx.compose.material.icons.outlined.QueryStats
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.SettingsBackupRestore import androidx.compose.material.icons.outlined.SettingsBackupRestore
import androidx.compose.material.icons.outlined.Sync
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
@ -47,7 +46,6 @@ fun MoreScreen(
onClickCategories: () -> Unit, onClickCategories: () -> Unit,
onClickStats: () -> Unit, onClickStats: () -> Unit,
onClickBackupAndRestore: () -> Unit, onClickBackupAndRestore: () -> Unit,
onClickSync: () -> Unit,
onClickSettings: () -> Unit, onClickSettings: () -> Unit,
onClickAbout: () -> Unit, onClickAbout: () -> Unit,
) { ) {
@ -143,18 +141,11 @@ fun MoreScreen(
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_backup), title = stringResource(R.string.label_backup_and_sync),
icon = Icons.Outlined.SettingsBackupRestore, icon = Icons.Outlined.SettingsBackupRestore,
onPreferenceClick = onClickBackupAndRestore, onPreferenceClick = onClickBackupAndRestore,
) )
} }
item {
TextPreferenceWidget(
title = stringResource(R.string.label_sync),
icon = Icons.Outlined.Sync,
onPreferenceClick = onClickSync,
)
}
item { Divider() } item { Divider() }

View File

@ -4,6 +4,7 @@ import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.text.format.DateUtils
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@ -49,12 +50,15 @@ import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.BackupFileValidator import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.BackupRestoreJob import eu.kanade.tachiyomi.data.backup.BackupRestoreJob
import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.sync.SyncDataJob
import eu.kanade.tachiyomi.data.sync.SyncManager
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.domain.backup.service.BackupPreferences import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.sync.SyncPreferences
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Divider import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
@ -74,11 +78,107 @@ object SettingsBackupScreen : SearchableSettings {
val backupPreferences = Injekt.get<BackupPreferences>() val backupPreferences = Injekt.get<BackupPreferences>()
DiskUtil.RequestStoragePermission() DiskUtil.RequestStoragePermission()
val syncPreferences = remember { Injekt.get<SyncPreferences>() }
val syncService by syncPreferences.syncService().collectAsState()
return listOf( return listOf(
getManualBackupGroup(),
getAutomaticBackupGroup(backupPreferences = backupPreferences),
) + listOf(
Preference.PreferenceGroup(
title = stringResource(R.string.pref_backup_manual_category),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = syncPreferences.syncService(),
title = stringResource(R.string.pref_sync_service),
entries = mapOf(
SyncManager.SyncService.NONE.value to stringResource(R.string.off),
SyncManager.SyncService.SYNCYOMI.value to stringResource(R.string.syncyomi),
),
onValueChanged = { true },
),
),
),
) + getSyncServicePreferences(syncPreferences, syncService)
}
@Composable
private fun getManualBackupGroup(): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_backup_manual_category),
preferenceItems = listOf(
getCreateBackupPref(), getCreateBackupPref(),
getRestoreBackupPref(), getRestoreBackupPref(),
getAutomaticBackupGroup(backupPreferences = backupPreferences), ),
)
}
@Composable
private fun getAutomaticBackupGroup(
backupPreferences: BackupPreferences,
): Preference.PreferenceGroup {
val context = LocalContext.current
val backupIntervalPref = backupPreferences.backupInterval()
val backupInterval by backupIntervalPref.collectAsState()
val backupDirPref = backupPreferences.backupsDirectory()
val backupDir by backupDirPref.collectAsState()
val pickBackupLocation = rememberLauncherForActivityResult(
contract = ActivityResultContracts.OpenDocumentTree(),
) { uri ->
if (uri != null) {
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flags)
val file = UniFile.fromUri(context, uri)
backupDirPref.set(file.uri.toString())
}
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_backup_service_category),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = backupIntervalPref,
title = stringResource(R.string.pref_backup_interval),
entries = mapOf(
0 to stringResource(R.string.off),
6 to stringResource(R.string.update_6hour),
12 to stringResource(R.string.update_12hour),
24 to stringResource(R.string.update_24hour),
48 to stringResource(R.string.update_48hour),
168 to stringResource(R.string.update_weekly),
),
onValueChanged = {
BackupCreateJob.setupTask(context, it)
true
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_backup_directory),
enabled = backupInterval != 0,
subtitle = remember(backupDir) {
(UniFile.fromUri(context, backupDir.toUri())?.filePath)?.let {
"$it/automatic"
}
} ?: stringResource(R.string.invalid_location, backupDir),
onClick = {
try {
pickBackupLocation.launch(null)
} catch (e: ActivityNotFoundException) {
context.toast(R.string.file_picker_error)
}
},
),
Preference.PreferenceItem.ListPreference(
pref = backupPreferences.numberOfBackups(),
enabled = backupInterval != 0,
title = stringResource(R.string.pref_backup_slots),
entries = listOf(2, 3, 4, 5).associateWith { it.toString() },
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.backup_info)),
),
) )
} }
@ -343,71 +443,127 @@ object SettingsBackupScreen : SearchableSettings {
} }
@Composable @Composable
private fun getAutomaticBackupGroup( private fun getSyncServicePreferences(syncPreferences: SyncPreferences, syncService: Int): List<Preference> {
backupPreferences: BackupPreferences, val syncServiceType = SyncManager.SyncService.fromInt(syncService)
): Preference.PreferenceGroup { return when (syncServiceType) {
SyncManager.SyncService.NONE -> emptyList()
SyncManager.SyncService.SYNCYOMI -> getSelfHostPreferences(syncPreferences)
} +
if (syncServiceType == SyncManager.SyncService.NONE) {
emptyList()
} else {
listOf(getSyncNowPref(), getAutomaticSyncGroup(syncPreferences))
}
}
@Composable
private fun getSelfHostPreferences(syncPreferences: SyncPreferences): List<Preference> {
return listOf(
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_device_name),
subtitle = stringResource(R.string.pref_sync_device_name_summ),
pref = syncPreferences.deviceName(),
),
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_host),
subtitle = stringResource(R.string.pref_sync_host_summ),
pref = syncPreferences.syncHost(),
),
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_api_key),
subtitle = stringResource(R.string.pref_sync_api_key_summ),
pref = syncPreferences.syncAPIKey(),
),
)
}
@Composable
private fun getSyncNowPref(): Preference.PreferenceGroup {
val scope = rememberCoroutineScope()
var showDialog by remember { mutableStateOf(false) }
val context = LocalContext.current val context = LocalContext.current
val backupIntervalPref = backupPreferences.backupInterval() if (showDialog) {
val backupInterval by backupIntervalPref.collectAsState() SyncConfirmationDialog(
val backupDirPref = backupPreferences.backupsDirectory() onConfirm = {
val backupDir by backupDirPref.collectAsState() showDialog = false
val pickBackupLocation = rememberLauncherForActivityResult( scope.launch {
contract = ActivityResultContracts.OpenDocumentTree(), if (!SyncDataJob.isAnyJobRunning(context)) {
) { uri -> SyncDataJob.startNow(context)
if (uri != null) { } else {
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or context.toast(R.string.sync_in_progress)
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flags)
val file = UniFile.fromUri(context, uri)
backupDirPref.set(file.uri.toString())
} }
} }
},
onDismissRequest = { showDialog = false },
)
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_sync_now_group_title),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_sync_now),
subtitle = stringResource(R.string.pref_sync_now_subtitle),
onClick = {
showDialog = true
},
),
),
)
}
@Composable
private fun getAutomaticSyncGroup(syncPreferences: SyncPreferences): Preference.PreferenceGroup {
val context = LocalContext.current
val syncIntervalPref = syncPreferences.syncInterval()
val lastSync by syncPreferences.syncLastSync().collectAsState()
val formattedLastSync = DateUtils.getRelativeTimeSpanString(lastSync.toEpochMilli(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS)
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_backup_service_category), title = stringResource(R.string.pref_sync_service_category),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = backupIntervalPref, pref = syncIntervalPref,
title = stringResource(R.string.pref_backup_interval), title = stringResource(R.string.pref_sync_interval),
entries = mapOf( entries = mapOf(
0 to stringResource(R.string.off), 0 to stringResource(R.string.off),
6 to stringResource(R.string.update_6hour), 30 to stringResource(R.string.update_30min),
12 to stringResource(R.string.update_12hour), 60 to stringResource(R.string.update_1hour),
24 to stringResource(R.string.update_24hour), 180 to stringResource(R.string.update_3hour),
48 to stringResource(R.string.update_48hour), 360 to stringResource(R.string.update_6hour),
168 to stringResource(R.string.update_weekly), 720 to stringResource(R.string.update_12hour),
1440 to stringResource(R.string.update_24hour),
2880 to stringResource(R.string.update_48hour),
10080 to stringResource(R.string.update_weekly),
), ),
onValueChanged = { onValueChanged = {
BackupCreateJob.setupTask(context, it) SyncDataJob.setupTask(context, it)
true true
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.InfoPreference(stringResource(R.string.last_synchronization, formattedLastSync)),
title = stringResource(R.string.pref_backup_directory), ),
enabled = backupInterval != 0, )
subtitle = remember(backupDir) {
(UniFile.fromUri(context, backupDir.toUri())?.filePath)?.let {
"$it/automatic"
} }
} ?: stringResource(R.string.invalid_location, backupDir),
onClick = { @Composable
try { fun SyncConfirmationDialog(
pickBackupLocation.launch(null) onConfirm: () -> Unit,
} catch (e: ActivityNotFoundException) { onDismissRequest: () -> Unit,
context.toast(R.string.file_picker_error) ) {
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_sync_confirmation_title)) },
text = { Text(text = stringResource(R.string.pref_sync_confirmation_message)) },
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(onClick = onConfirm) {
Text(text = stringResource(android.R.string.ok))
} }
}, },
),
Preference.PreferenceItem.ListPreference(
pref = backupPreferences.numberOfBackups(),
enabled = backupInterval != 0,
title = stringResource(R.string.pref_backup_slots),
entries = listOf(2, 3, 4, 5).associateWith { it.toString() },
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.backup_info)),
),
) )
} }
} }

View File

@ -223,17 +223,11 @@ object SettingsMainScreen : Screen() {
screen = SettingsBrowseScreen, screen = SettingsBrowseScreen,
), ),
Item( Item(
titleRes = R.string.label_backup, titleRes = R.string.label_backup_and_sync,
subtitleRes = R.string.pref_backup_summary, subtitleRes = R.string.pref_backup_and_sync_summary,
icon = Icons.Outlined.SettingsBackupRestore, icon = Icons.Outlined.SettingsBackupRestore,
screen = SettingsBackupScreen, screen = SettingsBackupScreen,
), ),
Item(
titleRes = R.string.label_sync,
subtitleRes = R.string.pref_sync_summary,
icon = Icons.Outlined.Sync,
screen = SettingsSyncScreen,
),
Item( Item(
titleRes = R.string.pref_category_security, titleRes = R.string.pref_category_security,
subtitleRes = R.string.pref_security_summary, subtitleRes = R.string.pref_security_summary,

View File

@ -291,7 +291,6 @@ private val settingScreens = listOf(
SettingsTrackingScreen, SettingsTrackingScreen,
SettingsBrowseScreen, SettingsBrowseScreen,
SettingsBackupScreen, SettingsBackupScreen,
SettingsSyncScreen,
SettingsSecurityScreen, SettingsSecurityScreen,
SettingsAdvancedScreen, SettingsAdvancedScreen,
) )

View File

@ -1,180 +0,0 @@
package eu.kanade.presentation.more.settings.screen
import android.text.format.DateUtils
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Cloud
import androidx.compose.material.icons.outlined.Devices
import androidx.compose.material.icons.outlined.Sync
import androidx.compose.material.icons.outlined.VpnKey
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.sync.SyncDataJob
import eu.kanade.tachiyomi.data.sync.SyncManager.SyncService
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch
import tachiyomi.domain.sync.SyncPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
object SettingsSyncScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.label_sync
@Composable
override fun getPreferences(): List<Preference> {
val syncPreferences = remember { Injekt.get<SyncPreferences>() }
val syncService by syncPreferences.syncService().collectAsState()
return listOf(
Preference.PreferenceItem.ListPreference(
pref = syncPreferences.syncService(),
title = stringResource(R.string.pref_sync_service),
entries = mapOf(
SyncService.NONE.value to stringResource(R.string.off),
SyncService.SYNCYOMI.value to stringResource(R.string.syncyomi),
),
onValueChanged = { true },
),
) + getSyncServicePreferences(syncPreferences, syncService)
}
@Composable
private fun getSyncServicePreferences(syncPreferences: SyncPreferences, syncService: Int): List<Preference> {
return when (SyncService.fromInt(syncService)) {
SyncService.NONE -> emptyList()
SyncService.SYNCYOMI -> getSelfHostPreferences(syncPreferences)
} + getSyncNowPref() + getAutomaticSyncGroup(syncPreferences)
}
@Composable
private fun getSelfHostPreferences(syncPreferences: SyncPreferences): List<Preference> {
return listOf(
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_device_name),
subtitle = stringResource(R.string.pref_sync_device_name_summ),
icon = Icons.Outlined.Devices,
pref = syncPreferences.deviceName(),
),
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_host),
subtitle = stringResource(R.string.pref_sync_host_summ),
icon = Icons.Outlined.Cloud,
pref = syncPreferences.syncHost(),
),
Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_api_key),
subtitle = stringResource(R.string.pref_sync_api_key_summ),
icon = Icons.Outlined.VpnKey,
pref = syncPreferences.syncAPIKey(),
),
)
}
@Composable
private fun getSyncNowPref(): Preference.PreferenceGroup {
val scope = rememberCoroutineScope()
var showDialog by remember { mutableStateOf(false) }
val context = LocalContext.current
if (showDialog) {
SyncConfirmationDialog(
onConfirm = {
showDialog = false
scope.launch {
if (!SyncDataJob.isAnyJobRunning(context)) {
SyncDataJob.startNow(context)
} else {
context.toast(R.string.sync_in_progress)
}
}
},
onDismissRequest = { showDialog = false },
)
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_sync_now_group_title),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_sync_now),
subtitle = stringResource(R.string.pref_sync_now_subtitle),
onClick = {
showDialog = true
},
icon = Icons.Outlined.Sync,
),
),
)
}
@Composable
private fun getAutomaticSyncGroup(syncPreferences: SyncPreferences): Preference.PreferenceGroup {
val context = LocalContext.current
val syncIntervalPref = syncPreferences.syncInterval()
val lastSync by syncPreferences.syncLastSync().collectAsState()
val formattedLastSync = DateUtils.getRelativeTimeSpanString(lastSync.toEpochMilli(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS)
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_sync_service_category),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = syncIntervalPref,
title = stringResource(R.string.pref_sync_interval),
entries = mapOf(
0 to stringResource(R.string.off),
30 to stringResource(R.string.update_30min),
60 to stringResource(R.string.update_1hour),
180 to stringResource(R.string.update_3hour),
360 to stringResource(R.string.update_6hour),
720 to stringResource(R.string.update_12hour),
1440 to stringResource(R.string.update_24hour),
2880 to stringResource(R.string.update_48hour),
10080 to stringResource(R.string.update_weekly),
),
onValueChanged = {
SyncDataJob.setupTask(context, it)
true
},
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.last_synchronization, formattedLastSync)),
),
)
}
@Composable
fun SyncConfirmationDialog(
onConfirm: () -> Unit,
onDismissRequest: () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_sync_confirmation_title)) },
text = { Text(text = stringResource(R.string.pref_sync_confirmation_message)) },
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(onClick = onConfirm) {
Text(text = stringResource(android.R.string.ok))
}
},
)
}
}

View File

@ -72,7 +72,6 @@ object MoreTab : Tab {
onClickCategories = { navigator.push(CategoryScreen()) }, onClickCategories = { navigator.push(CategoryScreen()) },
onClickStats = { navigator.push(StatsScreen()) }, onClickStats = { navigator.push(StatsScreen()) },
onClickBackupAndRestore = { navigator.push(SettingsScreen.toBackupScreen()) }, onClickBackupAndRestore = { navigator.push(SettingsScreen.toBackupScreen()) },
onClickSync = { navigator.push(SettingsScreen.toSyncScreen()) },
onClickSettings = { navigator.push(SettingsScreen.toMainScreen()) }, onClickSettings = { navigator.push(SettingsScreen.toMainScreen()) },
onClickAbout = { navigator.push(SettingsScreen.toAboutScreen()) }, onClickAbout = { navigator.push(SettingsScreen.toAboutScreen()) },
) )

View File

@ -16,7 +16,6 @@ import eu.kanade.presentation.more.settings.screen.AboutScreen
import eu.kanade.presentation.more.settings.screen.SettingsAppearanceScreen import eu.kanade.presentation.more.settings.screen.SettingsAppearanceScreen
import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
import eu.kanade.presentation.more.settings.screen.SettingsMainScreen import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
import eu.kanade.presentation.more.settings.screen.SettingsSyncScreen
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
import eu.kanade.presentation.util.LocalBackPress import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
@ -25,7 +24,6 @@ import tachiyomi.presentation.core.components.TwoPanelBox
class SettingsScreen private constructor( class SettingsScreen private constructor(
val toBackup: Boolean, val toBackup: Boolean,
val toSync: Boolean,
val toAbout: Boolean, val toAbout: Boolean,
) : Screen() { ) : Screen() {
@ -36,8 +34,6 @@ class SettingsScreen private constructor(
Navigator( Navigator(
screen = if (toBackup) { screen = if (toBackup) {
SettingsBackupScreen SettingsBackupScreen
} else if (toSync) {
SettingsSyncScreen
} else if (toAbout) { } else if (toAbout) {
AboutScreen AboutScreen
} else { } else {
@ -60,8 +56,6 @@ class SettingsScreen private constructor(
Navigator( Navigator(
screen = if (toBackup) { screen = if (toBackup) {
SettingsBackupScreen SettingsBackupScreen
} else if (toSync) {
SettingsSyncScreen
} else if (toAbout) { } else if (toAbout) {
AboutScreen AboutScreen
} else { } else {
@ -85,12 +79,10 @@ class SettingsScreen private constructor(
} }
companion object { companion object {
fun toMainScreen() = SettingsScreen(toBackup = false, toSync = false, toAbout = false) fun toMainScreen() = SettingsScreen(toBackup = false, toAbout = false)
fun toBackupScreen() = SettingsScreen(toBackup = true, toSync = false, toAbout = false) fun toBackupScreen() = SettingsScreen(toBackup = true, toAbout = false)
fun toSyncScreen() = SettingsScreen(toBackup = false, toSync = true, toAbout = false) fun toAboutScreen() = SettingsScreen(toBackup = false, toAbout = true)
fun toAboutScreen() = SettingsScreen(toBackup = false, toSync = false, toAbout = true)
} }
} }

View File

@ -22,7 +22,8 @@
<string name="label_recent_updates">Updates</string> <string name="label_recent_updates">Updates</string>
<string name="label_recent_manga">History</string> <string name="label_recent_manga">History</string>
<string name="label_sources">Sources</string> <string name="label_sources">Sources</string>
<string name="label_backup">Backup and restore</string> <string name="label_backup">Backup</string>
<string name="label_backup_and_sync">Backup and Sync</string>
<string name="label_sync">Sync</string> <string name="label_sync">Sync</string>
<string name="label_stats">Statistics</string> <string name="label_stats">Statistics</string>
<string name="label_migration">Migrate</string> <string name="label_migration">Migrate</string>
@ -179,7 +180,7 @@
<string name="pref_downloads_summary">Automatic download, download ahead</string> <string name="pref_downloads_summary">Automatic download, download ahead</string>
<string name="pref_tracking_summary">One-way progress sync, enhanced sync</string> <string name="pref_tracking_summary">One-way progress sync, enhanced sync</string>
<string name="pref_browse_summary">Sources, extensions, global search</string> <string name="pref_browse_summary">Sources, extensions, global search</string>
<string name="pref_backup_summary">Manual &amp; automatic backups</string> <string name="pref_backup_and_sync_summary">Manual &amp; automatic backups and sync</string>
<string name="pref_security_summary">App lock, secure screen</string> <string name="pref_security_summary">App lock, secure screen</string>
<string name="pref_advanced_summary">Dump crash logs, battery optimizations</string> <string name="pref_advanced_summary">Dump crash logs, battery optimizations</string>
@ -499,6 +500,7 @@
<string name="pref_restore_backup_summ">Restore library from backup file</string> <string name="pref_restore_backup_summ">Restore library from backup file</string>
<string name="pref_backup_directory">Backup location</string> <string name="pref_backup_directory">Backup location</string>
<string name="pref_backup_service_category">Automatic backups</string> <string name="pref_backup_service_category">Automatic backups</string>
<string name="pref_backup_manual_category">Manual backups</string>
<string name="pref_backup_interval">Backup frequency</string> <string name="pref_backup_interval">Backup frequency</string>
<string name="pref_backup_slots">Maximum backups</string> <string name="pref_backup_slots">Maximum backups</string>
<string name="backup_created">Backup created</string> <string name="backup_created">Backup created</string>
@ -537,7 +539,6 @@
<string name="pref_sync_host_summ">Enter the host address for synchronizing your library</string> <string name="pref_sync_host_summ">Enter the host address for synchronizing your library</string>
<string name="pref_sync_api_key">API key</string> <string name="pref_sync_api_key">API key</string>
<string name="pref_sync_api_key_summ">Enter the API key to synchronize your library</string> <string name="pref_sync_api_key_summ">Enter the API key to synchronize your library</string>
<string name="pref_sync_summary">Sync your library with a remote server</string>
<string name="pref_sync_now_group_title">Sync Actions</string> <string name="pref_sync_now_group_title">Sync Actions</string>
<string name="pref_sync_now">Sync now</string> <string name="pref_sync_now">Sync now</string>
<string name="pref_sync_confirmation_title">Sync confirmation</string> <string name="pref_sync_confirmation_title">Sync confirmation</string>