mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	| @@ -1,5 +1,6 @@ | ||||
| package eu.kanade.presentation.more.settings.screen | ||||
|  | ||||
| import android.content.ActivityNotFoundException | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.net.Uri | ||||
| @@ -26,8 +27,11 @@ import androidx.compose.runtime.rememberCoroutineScope | ||||
| import androidx.compose.runtime.setValue | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.platform.LocalContext | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.core.net.toUri | ||||
| import cafe.adriel.voyager.navigator.LocalNavigator | ||||
| import cafe.adriel.voyager.navigator.currentOrThrow | ||||
| import com.hippo.unifile.UniFile | ||||
| import eu.kanade.presentation.more.settings.Preference | ||||
| import eu.kanade.presentation.more.settings.screen.data.CreateBackupScreen | ||||
| import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget | ||||
| @@ -54,6 +58,7 @@ 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.domain.storage.service.StoragePreferences | ||||
| import tachiyomi.domain.sync.SyncPreferences | ||||
| import tachiyomi.i18n.MR | ||||
| import tachiyomi.presentation.core.i18n.stringResource | ||||
| @@ -70,6 +75,7 @@ object SettingsDataScreen : SearchableSettings { | ||||
|     @Composable | ||||
|     override fun getPreferences(): List<Preference> { | ||||
|         val backupPreferences = Injekt.get<BackupPreferences>() | ||||
|         val storagePreferences = Injekt.get<StoragePreferences>() | ||||
|  | ||||
|         PermissionRequestHelper.requestStoragePermission() | ||||
|  | ||||
| @@ -77,11 +83,50 @@ object SettingsDataScreen : SearchableSettings { | ||||
|         val syncService by syncPreferences.syncService().collectAsState() | ||||
|  | ||||
|         return listOf( | ||||
|             getStorageLocationPref(storagePreferences = storagePreferences), | ||||
|             Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.pref_storage_location_info)), | ||||
|  | ||||
|             getBackupAndRestoreGroup(backupPreferences = backupPreferences), | ||||
|             getDataGroup(), | ||||
|         ) + getSyncPreferences(syncPreferences = syncPreferences, syncService = syncService) | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun getStorageLocationPref( | ||||
|         storagePreferences: StoragePreferences, | ||||
|     ): Preference.PreferenceItem.TextPreference { | ||||
|         val context = LocalContext.current | ||||
|         val storageDirPref = storagePreferences.baseStorageDirectory() | ||||
|         val storageDir by storageDirPref.collectAsState() | ||||
|         val pickStorageLocation = 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) | ||||
|                 storageDirPref.set(file.uri.toString()) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return Preference.PreferenceItem.TextPreference( | ||||
|             title = stringResource(MR.strings.pref_storage_location), | ||||
|             subtitle = remember(storageDir) { | ||||
|                 (UniFile.fromUri(context, storageDir.toUri())?.filePath) | ||||
|             } ?: stringResource(MR.strings.invalid_location, storageDir), | ||||
|             onClick = { | ||||
|                 try { | ||||
|                     pickStorageLocation.launch(null) | ||||
|                 } catch (e: ActivityNotFoundException) { | ||||
|                     context.toast(MR.strings.file_picker_error) | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun getBackupAndRestoreGroup(backupPreferences: BackupPreferences): Preference.PreferenceGroup { | ||||
|         val context = LocalContext.current | ||||
|   | ||||
| @@ -1,9 +1,5 @@ | ||||
| package eu.kanade.presentation.more.settings.screen | ||||
|  | ||||
| import android.content.Intent | ||||
| import android.os.Environment | ||||
| import androidx.activity.compose.rememberLauncherForActivityResult | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.ReadOnlyComposable | ||||
| import androidx.compose.runtime.collectAsState | ||||
| @@ -12,10 +8,7 @@ import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.saveable.rememberSaveable | ||||
| import androidx.compose.runtime.setValue | ||||
| import androidx.compose.ui.platform.LocalContext | ||||
| import androidx.compose.ui.util.fastMap | ||||
| import androidx.core.net.toUri | ||||
| import com.hippo.unifile.UniFile | ||||
| import eu.kanade.presentation.category.visualName | ||||
| import eu.kanade.presentation.more.settings.Preference | ||||
| import eu.kanade.presentation.more.settings.widget.TriStateListDialog | ||||
| @@ -29,7 +22,6 @@ import tachiyomi.presentation.core.i18n.stringResource | ||||
| import tachiyomi.presentation.core.util.collectAsState | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| import java.io.File | ||||
|  | ||||
| object SettingsDownloadScreen : SearchableSettings { | ||||
|  | ||||
| @@ -44,7 +36,6 @@ object SettingsDownloadScreen : SearchableSettings { | ||||
|  | ||||
|         val downloadPreferences = remember { Injekt.get<DownloadPreferences>() } | ||||
|         return listOf( | ||||
|             getDownloadLocationPreference(downloadPreferences = downloadPreferences), | ||||
|             Preference.PreferenceItem.SwitchPreference( | ||||
|                 pref = downloadPreferences.downloadOnlyOverWifi(), | ||||
|                 title = stringResource(MR.strings.connected_to_wifi), | ||||
| @@ -70,67 +61,6 @@ object SettingsDownloadScreen : SearchableSettings { | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun getDownloadLocationPreference( | ||||
|         downloadPreferences: DownloadPreferences, | ||||
|     ): Preference.PreferenceItem.ListPreference<String> { | ||||
|         val context = LocalContext.current | ||||
|         val currentDirPref = downloadPreferences.downloadsDirectory() | ||||
|         val currentDir by currentDirPref.collectAsState() | ||||
|  | ||||
|         val pickLocation = 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) | ||||
|                 currentDirPref.set(file.uri.toString()) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         val defaultDirPair = rememberDefaultDownloadDir() | ||||
|         val customDirEntryKey = currentDir.takeIf { it != defaultDirPair.first } ?: "custom" | ||||
|  | ||||
|         return Preference.PreferenceItem.ListPreference( | ||||
|             pref = currentDirPref, | ||||
|             title = stringResource(MR.strings.pref_download_directory), | ||||
|             subtitleProvider = { value, _ -> | ||||
|                 remember(value) { | ||||
|                     UniFile.fromUri(context, value.toUri())?.filePath | ||||
|                 } ?: stringResource(MR.strings.invalid_location, value) | ||||
|             }, | ||||
|             entries = mapOf( | ||||
|                 defaultDirPair, | ||||
|                 customDirEntryKey to stringResource(MR.strings.custom_dir), | ||||
|             ), | ||||
|             onValueChanged = { | ||||
|                 val default = it == defaultDirPair.first | ||||
|                 if (!default) { | ||||
|                     pickLocation.launch(null) | ||||
|                 } | ||||
|                 default // Don't update when non-default chosen | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun rememberDefaultDownloadDir(): Pair<String, String> { | ||||
|         val appName = stringResource(MR.strings.app_name) | ||||
|         return remember { | ||||
|             val file = UniFile.fromFile( | ||||
|                 File( | ||||
|                     "${Environment.getExternalStorageDirectory().absolutePath}${File.separator}$appName", | ||||
|                     "downloads", | ||||
|                 ), | ||||
|             )!! | ||||
|             file.uri.toString() to file.filePath!! | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun getDeleteChaptersGroup( | ||||
|         downloadPreferences: DownloadPreferences, | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.util.system.workManager | ||||
| import logcat.LogPriority | ||||
| import tachiyomi.core.util.system.logcat | ||||
| import tachiyomi.domain.backup.service.BackupPreferences | ||||
| import tachiyomi.domain.storage.service.StoragePreferences | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| import java.util.Date | ||||
| @@ -39,8 +40,9 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete | ||||
|         if (isAutoBackup && BackupRestoreJob.isRunning(context)) return Result.retry() | ||||
|  | ||||
|         val backupPreferences = Injekt.get<BackupPreferences>() | ||||
|  | ||||
|         val uri = inputData.getString(LOCATION_URI_KEY)?.toUri() | ||||
|             ?: backupPreferences.backupsDirectory().get().toUri() | ||||
|             ?: getAutomaticBackupLocation() | ||||
|         val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupCreateFlags.AutomaticDefaults) | ||||
|  | ||||
|         try { | ||||
| @@ -73,6 +75,15 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     private fun getAutomaticBackupLocation(): Uri { | ||||
|         val storagePreferences = Injekt.get<StoragePreferences>() | ||||
|         return storagePreferences.baseStorageDirectory().get().let { | ||||
|             val dir = UniFile.fromUri(context, it.toUri()) | ||||
|                 .createDirectory(StoragePreferences.BACKUP_DIR) | ||||
|             dir.uri | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     companion object { | ||||
|         fun isManualJobRunning(context: Context): Boolean { | ||||
|             return context.workManager.isRunning(TAG_MANUAL) | ||||
|   | ||||
| @@ -92,8 +92,8 @@ class BackupCreator( | ||||
|             file = ( | ||||
|                 if (isAutoBackup) { | ||||
|                     // Get dir of file and create | ||||
|                     var dir = UniFile.fromUri(context, uri) | ||||
|                     dir = dir.createDirectory("automatic") | ||||
|                     val dir = UniFile.fromUri(context, uri) | ||||
|                         .createDirectory("automatic") | ||||
|  | ||||
|                     // Delete older backups | ||||
|                     dir.listFiles { _, filename -> Backup.filenameRegex.matches(filename) } | ||||
|   | ||||
| @@ -44,9 +44,9 @@ import tachiyomi.core.util.lang.launchIO | ||||
| import tachiyomi.core.util.lang.launchNonCancellable | ||||
| import tachiyomi.core.util.system.logcat | ||||
| import tachiyomi.domain.chapter.model.Chapter | ||||
| import tachiyomi.domain.download.service.DownloadPreferences | ||||
| import tachiyomi.domain.manga.model.Manga | ||||
| import tachiyomi.domain.source.service.SourceManager | ||||
| import tachiyomi.domain.storage.service.StoragePreferences | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| import java.io.File | ||||
| @@ -64,7 +64,7 @@ class DownloadCache( | ||||
|     private val provider: DownloadProvider = Injekt.get(), | ||||
|     private val sourceManager: SourceManager = Injekt.get(), | ||||
|     private val extensionManager: ExtensionManager = Injekt.get(), | ||||
|     private val downloadPreferences: DownloadPreferences = Injekt.get(), | ||||
|     private val storagePreferences: StoragePreferences = Injekt.get(), | ||||
| ) { | ||||
|  | ||||
|     private val scope = CoroutineScope(Dispatchers.IO) | ||||
| @@ -98,7 +98,7 @@ class DownloadCache( | ||||
|     private var rootDownloadsDir = RootDirectory(getDirectoryFromPreference()) | ||||
|  | ||||
|     init { | ||||
|         downloadPreferences.downloadsDirectory().changes() | ||||
|         storagePreferences.baseStorageDirectory().changes() | ||||
|             .onEach { | ||||
|                 rootDownloadsDir = RootDirectory(getDirectoryFromPreference()) | ||||
|                 invalidateCache() | ||||
| @@ -297,8 +297,8 @@ class DownloadCache( | ||||
|      * Returns the downloads directory from the user's preferences. | ||||
|      */ | ||||
|     private fun getDirectoryFromPreference(): UniFile { | ||||
|         val dir = downloadPreferences.downloadsDirectory().get() | ||||
|         return UniFile.fromUri(context, dir.toUri()) | ||||
|         return UniFile.fromUri(context, storagePreferences.baseStorageDirectory().get().toUri()) | ||||
|             .createDirectory(StoragePreferences.DOWNLOADS_DIR) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -12,8 +12,8 @@ import logcat.LogPriority | ||||
| import tachiyomi.core.i18n.stringResource | ||||
| import tachiyomi.core.util.system.logcat | ||||
| import tachiyomi.domain.chapter.model.Chapter | ||||
| import tachiyomi.domain.download.service.DownloadPreferences | ||||
| import tachiyomi.domain.manga.model.Manga | ||||
| import tachiyomi.domain.storage.service.StoragePreferences | ||||
| import tachiyomi.i18n.MR | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| @@ -26,7 +26,7 @@ import uy.kohesive.injekt.api.get | ||||
|  */ | ||||
| class DownloadProvider( | ||||
|     private val context: Context, | ||||
|     downloadPreferences: DownloadPreferences = Injekt.get(), | ||||
|     private val storagePreferences: StoragePreferences = Injekt.get(), | ||||
| ) { | ||||
|  | ||||
|     private val scope = MainScope() | ||||
| @@ -34,18 +34,23 @@ class DownloadProvider( | ||||
|     /** | ||||
|      * The root directory for downloads. | ||||
|      */ | ||||
|     private var downloadsDir = downloadPreferences.downloadsDirectory().get().let { | ||||
|         val dir = UniFile.fromUri(context, it.toUri()) | ||||
|         DiskUtil.createNoMediaFile(dir, context) | ||||
|         dir | ||||
|     } | ||||
|     private var downloadsDir = setDownloadsLocation() | ||||
|  | ||||
|     init { | ||||
|         downloadPreferences.downloadsDirectory().changes() | ||||
|             .onEach { downloadsDir = UniFile.fromUri(context, it.toUri()) } | ||||
|         storagePreferences.baseStorageDirectory().changes() | ||||
|             .onEach { downloadsDir = setDownloadsLocation() } | ||||
|             .launchIn(scope) | ||||
|     } | ||||
|  | ||||
|     private fun setDownloadsLocation(): UniFile { | ||||
|         return storagePreferences.baseStorageDirectory().get().let { | ||||
|             val dir = UniFile.fromUri(context, it.toUri()) | ||||
|                 .createDirectory(StoragePreferences.DOWNLOADS_DIR) | ||||
|             DiskUtil.createNoMediaFile(dir, context) | ||||
|             dir | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the download directory for a manga. For internal use only. | ||||
|      * | ||||
|   | ||||
| @@ -11,11 +11,11 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences | ||||
| import eu.kanade.tachiyomi.util.system.isDevFlavor | ||||
| import tachiyomi.core.preference.AndroidPreferenceStore | ||||
| import tachiyomi.core.preference.PreferenceStore | ||||
| import tachiyomi.core.provider.AndroidBackupFolderProvider | ||||
| import tachiyomi.core.provider.AndroidDownloadFolderProvider | ||||
| import tachiyomi.core.provider.AndroidStorageFolderProvider | ||||
| import tachiyomi.domain.backup.service.BackupPreferences | ||||
| import tachiyomi.domain.download.service.DownloadPreferences | ||||
| import tachiyomi.domain.library.service.LibraryPreferences | ||||
| import tachiyomi.domain.storage.service.StoragePreferences | ||||
| import tachiyomi.domain.sync.SyncPreferences | ||||
| import uy.kohesive.injekt.api.InjektModule | ||||
| import uy.kohesive.injekt.api.InjektRegistrar | ||||
| @@ -50,20 +50,17 @@ class PreferenceModule(val app: Application) : InjektModule { | ||||
|             TrackPreferences(get()) | ||||
|         } | ||||
|         addSingletonFactory { | ||||
|             AndroidDownloadFolderProvider(app) | ||||
|             DownloadPreferences(get()) | ||||
|         } | ||||
|         addSingletonFactory { | ||||
|             DownloadPreferences( | ||||
|                 folderProvider = get<AndroidDownloadFolderProvider>(), | ||||
|                 preferenceStore = get(), | ||||
|             ) | ||||
|             BackupPreferences(get()) | ||||
|         } | ||||
|         addSingletonFactory { | ||||
|             AndroidBackupFolderProvider(app) | ||||
|             AndroidStorageFolderProvider(app) | ||||
|         } | ||||
|         addSingletonFactory { | ||||
|             BackupPreferences( | ||||
|                 folderProvider = get<AndroidBackupFolderProvider>(), | ||||
|             StoragePreferences( | ||||
|                 folderProvider = get<AndroidStorageFolderProvider>(), | ||||
|                 preferenceStore = get(), | ||||
|             ) | ||||
|         } | ||||
|   | ||||
| @@ -1,25 +0,0 @@ | ||||
| package tachiyomi.core.provider | ||||
|  | ||||
| import android.content.Context | ||||
| import android.os.Environment | ||||
| import androidx.core.net.toUri | ||||
| import tachiyomi.core.i18n.stringResource | ||||
| import tachiyomi.i18n.MR | ||||
| import java.io.File | ||||
|  | ||||
| class AndroidDownloadFolderProvider( | ||||
|     val context: Context, | ||||
| ) : FolderProvider { | ||||
|  | ||||
|     override fun directory(): File { | ||||
|         return File( | ||||
|             Environment.getExternalStorageDirectory().absolutePath + File.separator + | ||||
|                 context.stringResource(MR.strings.app_name), | ||||
|             "downloads", | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     override fun path(): String { | ||||
|         return directory().toUri().toString() | ||||
|     } | ||||
| } | ||||
| @@ -7,7 +7,7 @@ import tachiyomi.core.i18n.stringResource | ||||
| import tachiyomi.i18n.MR | ||||
| import java.io.File | ||||
| 
 | ||||
| class AndroidBackupFolderProvider( | ||||
| class AndroidStorageFolderProvider( | ||||
|     private val context: Context, | ||||
| ) : FolderProvider { | ||||
| 
 | ||||
| @@ -15,7 +15,6 @@ class AndroidBackupFolderProvider( | ||||
|         return File( | ||||
|             Environment.getExternalStorageDirectory().absolutePath + File.separator + | ||||
|                 context.stringResource(MR.strings.app_name), | ||||
|             "backup", | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
| @@ -2,15 +2,11 @@ package tachiyomi.domain.backup.service | ||||
|  | ||||
| import tachiyomi.core.preference.Preference | ||||
| import tachiyomi.core.preference.PreferenceStore | ||||
| import tachiyomi.core.provider.FolderProvider | ||||
|  | ||||
| class BackupPreferences( | ||||
|     private val folderProvider: FolderProvider, | ||||
|     private val preferenceStore: PreferenceStore, | ||||
| ) { | ||||
|  | ||||
|     fun backupsDirectory() = preferenceStore.getString("backup_directory", folderProvider.path()) | ||||
|  | ||||
|     fun backupInterval() = preferenceStore.getInt("backup_interval", 12) | ||||
|  | ||||
|     fun lastAutoBackupTimestamp() = preferenceStore.getLong(Preference.appStateKey("last_auto_backup_timestamp"), 0L) | ||||
|   | ||||
| @@ -1,18 +1,11 @@ | ||||
| package tachiyomi.domain.download.service | ||||
|  | ||||
| import tachiyomi.core.preference.PreferenceStore | ||||
| import tachiyomi.core.provider.FolderProvider | ||||
|  | ||||
| class DownloadPreferences( | ||||
|     private val folderProvider: FolderProvider, | ||||
|     private val preferenceStore: PreferenceStore, | ||||
| ) { | ||||
|  | ||||
|     fun downloadsDirectory() = preferenceStore.getString( | ||||
|         "download_directory", | ||||
|         folderProvider.path(), | ||||
|     ) | ||||
|  | ||||
|     fun downloadOnlyOverWifi() = preferenceStore.getBoolean( | ||||
|         "pref_download_only_over_wifi_key", | ||||
|         true, | ||||
|   | ||||
| @@ -0,0 +1,17 @@ | ||||
| package tachiyomi.domain.storage.service | ||||
|  | ||||
| import tachiyomi.core.preference.PreferenceStore | ||||
| import tachiyomi.core.provider.FolderProvider | ||||
|  | ||||
| class StoragePreferences( | ||||
|     private val folderProvider: FolderProvider, | ||||
|     private val preferenceStore: PreferenceStore, | ||||
| ) { | ||||
|  | ||||
|     fun baseStorageDirectory() = preferenceStore.getString("storage_dir", folderProvider.path()) | ||||
|  | ||||
|     companion object { | ||||
|         const val BACKUP_DIR = "backup" | ||||
|         const val DOWNLOADS_DIR = "downloads" | ||||
|     } | ||||
| } | ||||
| @@ -431,13 +431,11 @@ | ||||
|     <string name="pref_lowest">Lowest</string> | ||||
|  | ||||
|       <!-- Downloads section --> | ||||
|     <string name="pref_download_directory">Download location</string> | ||||
|     <string name="pref_category_delete_chapters">Delete chapters</string> | ||||
|     <string name="pref_remove_after_marked_as_read">After manually marked as read</string> | ||||
|     <string name="pref_remove_after_read">After reading automatically delete</string> | ||||
|     <string name="pref_remove_bookmarked_chapters">Allow deleting bookmarked chapters</string> | ||||
|     <string name="pref_remove_exclude_categories">Excluded categories</string> | ||||
|     <string name="custom_dir">Custom location</string> | ||||
|     <string name="invalid_location">Invalid location: %s</string> | ||||
|     <string name="disabled">Disabled</string> | ||||
|     <string name="last_read_chapter">Last read chapter</string> | ||||
| @@ -470,11 +468,12 @@ | ||||
|     <string name="pref_hide_in_library_items">Hide entries already in library</string> | ||||
|  | ||||
|       <!-- Data and storage section --> | ||||
|     <string name="pref_storage_location">Storage location</string> | ||||
|     <string name="pref_storage_location_info">Used for automatic backups, chapter downloads, and local source.</string> | ||||
|     <string name="pref_create_backup">Create backup</string> | ||||
|     <string name="pref_create_backup_summ">Can be used to restore current library</string> | ||||
|     <string name="pref_restore_backup">Restore backup</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_interval">Automatic backup frequency</string> | ||||
|     <string name="action_create">Create</string> | ||||
|     <string name="backup_created">Backup created</string> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user