mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-29 21:37:56 +01:00 
			
		
		
		
	Rename "Backup and restore" settings screen to "Data and storage"
We can house more things in here in the future, like: - A unified storage location setting (with scoped storage) - Sync - Disk usage info
This commit is contained in:
		| @@ -16,7 +16,7 @@ import androidx.compose.material.icons.outlined.Info | ||||
| import androidx.compose.material.icons.outlined.Label | ||||
| import androidx.compose.material.icons.outlined.QueryStats | ||||
| import androidx.compose.material.icons.outlined.Settings | ||||
| import androidx.compose.material.icons.outlined.SettingsBackupRestore | ||||
| import androidx.compose.material.icons.outlined.Storage | ||||
| import androidx.compose.material3.HorizontalDivider | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.Modifier | ||||
| @@ -45,7 +45,7 @@ fun MoreScreen( | ||||
|     onClickDownloadQueue: () -> Unit, | ||||
|     onClickCategories: () -> Unit, | ||||
|     onClickStats: () -> Unit, | ||||
|     onClickBackupAndRestore: () -> Unit, | ||||
|     onClickDataAndStorage: () -> Unit, | ||||
|     onClickSettings: () -> Unit, | ||||
|     onClickAbout: () -> Unit, | ||||
| ) { | ||||
| @@ -141,9 +141,9 @@ fun MoreScreen( | ||||
|             } | ||||
|             item { | ||||
|                 TextPreferenceWidget( | ||||
|                     title = stringResource(R.string.label_backup), | ||||
|                     icon = Icons.Outlined.SettingsBackupRestore, | ||||
|                     onPreferenceClick = onClickBackupAndRestore, | ||||
|                     title = stringResource(R.string.label_data_storage), | ||||
|                     icon = Icons.Outlined.Storage, | ||||
|                     onPreferenceClick = onClickDataAndStorage, | ||||
|                 ) | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,6 @@ import androidx.compose.material3.TextButton | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.ReadOnlyComposable | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.mutableIntStateOf | ||||
| import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.rememberCoroutineScope | ||||
| @@ -31,7 +30,6 @@ import eu.kanade.presentation.more.settings.Preference | ||||
| import eu.kanade.presentation.more.settings.screen.advanced.ClearDatabaseScreen | ||||
| import eu.kanade.presentation.more.settings.screen.debug.DebugInfoScreen | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.cache.ChapterCache | ||||
| import eu.kanade.tachiyomi.data.download.DownloadCache | ||||
| import eu.kanade.tachiyomi.data.library.LibraryUpdateJob | ||||
| import eu.kanade.tachiyomi.network.NetworkHelper | ||||
| @@ -61,7 +59,6 @@ import okhttp3.Headers | ||||
| import tachiyomi.core.util.lang.launchNonCancellable | ||||
| import tachiyomi.core.util.lang.withUIContext | ||||
| import tachiyomi.core.util.system.logcat | ||||
| import tachiyomi.domain.library.service.LibraryPreferences | ||||
| import tachiyomi.domain.manga.repository.MangaRepository | ||||
| import tachiyomi.presentation.core.util.collectAsState | ||||
| import uy.kohesive.injekt.Injekt | ||||
| @@ -183,40 +180,12 @@ object SettingsAdvancedScreen : SearchableSettings { | ||||
|  | ||||
|     @Composable | ||||
|     private fun getDataGroup(): Preference.PreferenceGroup { | ||||
|         val scope = rememberCoroutineScope() | ||||
|         val context = LocalContext.current | ||||
|         val navigator = LocalNavigator.currentOrThrow | ||||
|         val libraryPreferences = remember { Injekt.get<LibraryPreferences>() } | ||||
|  | ||||
|         val chapterCache = remember { Injekt.get<ChapterCache>() } | ||||
|         var readableSizeSema by remember { mutableIntStateOf(0) } | ||||
|         val readableSize = remember(readableSizeSema) { chapterCache.readableSize } | ||||
|  | ||||
|         return Preference.PreferenceGroup( | ||||
|             title = stringResource(R.string.label_data), | ||||
|             preferenceItems = listOf( | ||||
|                 Preference.PreferenceItem.TextPreference( | ||||
|                     title = stringResource(R.string.pref_clear_chapter_cache), | ||||
|                     subtitle = stringResource(R.string.used_cache, readableSize), | ||||
|                     onClick = { | ||||
|                         scope.launchNonCancellable { | ||||
|                             try { | ||||
|                                 val deletedFiles = chapterCache.clear() | ||||
|                                 withUIContext { | ||||
|                                     context.toast(context.getString(R.string.cache_deleted, deletedFiles)) | ||||
|                                     readableSizeSema++ | ||||
|                                 } | ||||
|                             } catch (e: Throwable) { | ||||
|                                 logcat(LogPriority.ERROR, e) | ||||
|                                 withUIContext { context.toast(R.string.cache_delete_error) } | ||||
|                             } | ||||
|                         } | ||||
|                     }, | ||||
|                 ), | ||||
|                 Preference.PreferenceItem.SwitchPreference( | ||||
|                     pref = libraryPreferences.autoClearChapterCache(), | ||||
|                     title = stringResource(R.string.pref_auto_clear_chapter_cache), | ||||
|                 ), | ||||
|                 Preference.PreferenceItem.TextPreference( | ||||
|                     title = stringResource(R.string.pref_invalidate_download_cache), | ||||
|                     subtitle = stringResource(R.string.pref_invalidate_download_cache_summary), | ||||
|   | ||||
| @@ -31,8 +31,6 @@ import androidx.compose.ui.Alignment | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.platform.LocalContext | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.core.net.toUri | ||||
| import com.hippo.unifile.UniFile | ||||
| import eu.kanade.presentation.more.settings.Preference | ||||
| import eu.kanade.presentation.permissions.PermissionRequestHelper | ||||
| import eu.kanade.tachiyomi.R | ||||
| @@ -41,11 +39,17 @@ import eu.kanade.tachiyomi.data.backup.BackupCreateJob | ||||
| import eu.kanade.tachiyomi.data.backup.BackupFileValidator | ||||
| import eu.kanade.tachiyomi.data.backup.BackupRestoreJob | ||||
| import eu.kanade.tachiyomi.data.backup.models.Backup | ||||
| import eu.kanade.tachiyomi.data.cache.ChapterCache | ||||
| import eu.kanade.tachiyomi.util.system.DeviceUtil | ||||
| import eu.kanade.tachiyomi.util.system.copyToClipboard | ||||
| import eu.kanade.tachiyomi.util.system.toast | ||||
| import kotlinx.coroutines.launch | ||||
| import logcat.LogPriority | ||||
| import tachiyomi.core.util.lang.launchNonCancellable | ||||
| import tachiyomi.core.util.lang.withUIContext | ||||
| import tachiyomi.core.util.system.logcat | ||||
| import tachiyomi.domain.backup.service.BackupPreferences | ||||
| import tachiyomi.domain.library.service.LibraryPreferences | ||||
| import tachiyomi.presentation.core.components.LabeledCheckbox | ||||
| import tachiyomi.presentation.core.components.ScrollbarLazyColumn | ||||
| import tachiyomi.presentation.core.util.collectAsState | ||||
| @@ -54,12 +58,12 @@ import tachiyomi.presentation.core.util.isScrolledToStart | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| 
 | ||||
| object SettingsBackupScreen : SearchableSettings { | ||||
| object SettingsDataScreen : SearchableSettings { | ||||
| 
 | ||||
|     @ReadOnlyComposable | ||||
|     @Composable | ||||
|     @StringRes | ||||
|     override fun getTitleRes() = R.string.label_backup | ||||
|     override fun getTitleRes() = R.string.label_data_storage | ||||
| 
 | ||||
|     @Composable | ||||
|     override fun getPreferences(): List<Preference> { | ||||
| @@ -68,9 +72,49 @@ object SettingsBackupScreen : SearchableSettings { | ||||
|         PermissionRequestHelper.requestStoragePermission() | ||||
| 
 | ||||
|         return listOf( | ||||
|             getCreateBackupPref(), | ||||
|             getRestoreBackupPref(), | ||||
|             getAutomaticBackupGroup(backupPreferences = backupPreferences), | ||||
|             getBackupAndRestoreGroup(backupPreferences = backupPreferences), | ||||
|             getDataGroup(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     @Composable | ||||
|     private fun getBackupAndRestoreGroup(backupPreferences: BackupPreferences): Preference.PreferenceGroup { | ||||
|         val context = LocalContext.current | ||||
|         val backupIntervalPref = backupPreferences.backupInterval() | ||||
|         val backupInterval by backupIntervalPref.collectAsState() | ||||
| 
 | ||||
|         return Preference.PreferenceGroup( | ||||
|             title = stringResource(R.string.label_backup), | ||||
|             preferenceItems = listOf( | ||||
|                 // Manual actions | ||||
|                 getCreateBackupPref(), | ||||
|                 getRestoreBackupPref(), | ||||
| 
 | ||||
|                 // Automatic backups | ||||
|                 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.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)), | ||||
|             ), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
| @@ -318,70 +362,40 @@ object SettingsBackupScreen : SearchableSettings { | ||||
|     } | ||||
| 
 | ||||
|     @Composable | ||||
|     private fun getAutomaticBackupGroup( | ||||
|         backupPreferences: BackupPreferences, | ||||
|     ): Preference.PreferenceGroup { | ||||
|     private fun getDataGroup(): Preference.PreferenceGroup { | ||||
|         val scope = rememberCoroutineScope() | ||||
|         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 | ||||
|         val libraryPreferences = remember { Injekt.get<LibraryPreferences>() } | ||||
| 
 | ||||
|                 context.contentResolver.takePersistableUriPermission(uri, flags) | ||||
| 
 | ||||
|                 val file = UniFile.fromUri(context, uri) | ||||
|                 backupDirPref.set(file.uri.toString()) | ||||
|             } | ||||
|         } | ||||
|         val chapterCache = remember { Injekt.get<ChapterCache>() } | ||||
|         var readableSizeSema by remember { mutableIntStateOf(0) } | ||||
|         val readableSize = remember(readableSizeSema) { chapterCache.readableSize } | ||||
| 
 | ||||
|         return Preference.PreferenceGroup( | ||||
|             title = stringResource(R.string.pref_backup_service_category), | ||||
|             title = stringResource(R.string.label_data), | ||||
|             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), | ||||
|                     title = stringResource(R.string.pref_clear_chapter_cache), | ||||
|                     subtitle = stringResource(R.string.used_cache, readableSize), | ||||
|                     onClick = { | ||||
|                         try { | ||||
|                             pickBackupLocation.launch(null) | ||||
|                         } catch (e: ActivityNotFoundException) { | ||||
|                             context.toast(R.string.file_picker_error) | ||||
|                         scope.launchNonCancellable { | ||||
|                             try { | ||||
|                                 val deletedFiles = chapterCache.clear() | ||||
|                                 withUIContext { | ||||
|                                     context.toast(context.getString(R.string.cache_deleted, deletedFiles)) | ||||
|                                     readableSizeSema++ | ||||
|                                 } | ||||
|                             } catch (e: Throwable) { | ||||
|                                 logcat(LogPriority.ERROR, e) | ||||
|                                 withUIContext { context.toast(R.string.cache_delete_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.SwitchPreference( | ||||
|                     pref = libraryPreferences.autoClearChapterCache(), | ||||
|                     title = stringResource(R.string.pref_auto_clear_chapter_cache), | ||||
|                 ), | ||||
|                 Preference.PreferenceItem.InfoPreference(stringResource(R.string.backup_info)), | ||||
|             ), | ||||
|         ) | ||||
|     } | ||||
| @@ -18,7 +18,7 @@ import androidx.compose.material.icons.outlined.Info | ||||
| import androidx.compose.material.icons.outlined.Palette | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material.icons.outlined.Security | ||||
| import androidx.compose.material.icons.outlined.SettingsBackupRestore | ||||
| import androidx.compose.material.icons.outlined.Storage | ||||
| import androidx.compose.material.icons.outlined.Sync | ||||
| import androidx.compose.material3.LocalContentColor | ||||
| import androidx.compose.material3.MaterialTheme | ||||
| @@ -208,10 +208,10 @@ object SettingsMainScreen : Screen() { | ||||
|             screen = SettingsBrowseScreen, | ||||
|         ), | ||||
|         Item( | ||||
|             titleRes = R.string.label_backup, | ||||
|             titleRes = R.string.label_data_storage, | ||||
|             subtitleRes = R.string.pref_backup_summary, | ||||
|             icon = Icons.Outlined.SettingsBackupRestore, | ||||
|             screen = SettingsBackupScreen, | ||||
|             icon = Icons.Outlined.Storage, | ||||
|             screen = SettingsDataScreen, | ||||
|         ), | ||||
|         Item( | ||||
|             titleRes = R.string.pref_category_security, | ||||
|   | ||||
| @@ -291,7 +291,7 @@ private val settingScreens = listOf( | ||||
|     SettingsDownloadScreen, | ||||
|     SettingsTrackingScreen, | ||||
|     SettingsBrowseScreen, | ||||
|     SettingsBackupScreen, | ||||
|     SettingsDataScreen, | ||||
|     SettingsSecurityScreen, | ||||
|     SettingsAdvancedScreen, | ||||
| ) | ||||
|   | ||||
| @@ -71,7 +71,7 @@ object MoreTab : Tab { | ||||
|             onClickDownloadQueue = { navigator.push(DownloadQueueScreen) }, | ||||
|             onClickCategories = { navigator.push(CategoryScreen()) }, | ||||
|             onClickStats = { navigator.push(StatsScreen()) }, | ||||
|             onClickBackupAndRestore = { navigator.push(SettingsScreen.toBackupScreen()) }, | ||||
|             onClickDataAndStorage = { navigator.push(SettingsScreen.toDataAndStorageScreen()) }, | ||||
|             onClickSettings = { navigator.push(SettingsScreen.toMainScreen()) }, | ||||
|             onClickAbout = { navigator.push(SettingsScreen.toAboutScreen()) }, | ||||
|         ) | ||||
|   | ||||
| @@ -13,7 +13,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator | ||||
| import cafe.adriel.voyager.navigator.Navigator | ||||
| import cafe.adriel.voyager.navigator.currentOrThrow | ||||
| import eu.kanade.presentation.more.settings.screen.SettingsAppearanceScreen | ||||
| import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen | ||||
| import eu.kanade.presentation.more.settings.screen.SettingsDataScreen | ||||
| import eu.kanade.presentation.more.settings.screen.SettingsMainScreen | ||||
| import eu.kanade.presentation.more.settings.screen.about.AboutScreen | ||||
| import eu.kanade.presentation.util.DefaultNavigatorScreenTransition | ||||
| @@ -23,7 +23,7 @@ import eu.kanade.presentation.util.isTabletUi | ||||
| import tachiyomi.presentation.core.components.TwoPanelBox | ||||
|  | ||||
| class SettingsScreen private constructor( | ||||
|     val toBackup: Boolean, | ||||
|     val toDataAndStorage: Boolean, | ||||
|     val toAbout: Boolean, | ||||
| ) : Screen() { | ||||
|  | ||||
| @@ -32,8 +32,8 @@ class SettingsScreen private constructor( | ||||
|         val parentNavigator = LocalNavigator.currentOrThrow | ||||
|         if (!isTabletUi()) { | ||||
|             Navigator( | ||||
|                 screen = if (toBackup) { | ||||
|                     SettingsBackupScreen | ||||
|                 screen = if (toDataAndStorage) { | ||||
|                     SettingsDataScreen | ||||
|                 } else if (toAbout) { | ||||
|                     AboutScreen | ||||
|                 } else { | ||||
| @@ -54,8 +54,8 @@ class SettingsScreen private constructor( | ||||
|             ) | ||||
|         } else { | ||||
|             Navigator( | ||||
|                 screen = if (toBackup) { | ||||
|                     SettingsBackupScreen | ||||
|                 screen = if (toDataAndStorage) { | ||||
|                     SettingsDataScreen | ||||
|                 } else if (toAbout) { | ||||
|                     AboutScreen | ||||
|                 } else { | ||||
| @@ -79,10 +79,10 @@ class SettingsScreen private constructor( | ||||
|     } | ||||
|  | ||||
|     companion object { | ||||
|         fun toMainScreen() = SettingsScreen(toBackup = false, toAbout = false) | ||||
|         fun toMainScreen() = SettingsScreen(toDataAndStorage = false, toAbout = false) | ||||
|  | ||||
|         fun toBackupScreen() = SettingsScreen(toBackup = true, toAbout = false) | ||||
|         fun toDataAndStorageScreen() = SettingsScreen(toDataAndStorage = true, toAbout = false) | ||||
|  | ||||
|         fun toAboutScreen() = SettingsScreen(toBackup = false, toAbout = true) | ||||
|         fun toAboutScreen() = SettingsScreen(toDataAndStorage = false, toAbout = true) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user