mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Add basic storage usage info to "Data and storage" settings screen
This commit is contained in:
		@@ -4,12 +4,15 @@ import android.content.ActivityNotFoundException
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.os.Environment
 | 
			
		||||
import android.text.format.Formatter
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.activity.compose.rememberLauncherForActivityResult
 | 
			
		||||
import androidx.activity.result.contract.ActivityResultContracts
 | 
			
		||||
import androidx.annotation.StringRes
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.lazy.rememberLazyListState
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.verticalScroll
 | 
			
		||||
@@ -32,6 +35,8 @@ import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.platform.LocalContext
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import eu.kanade.presentation.more.settings.Preference
 | 
			
		||||
import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
 | 
			
		||||
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
 | 
			
		||||
import eu.kanade.presentation.permissions.PermissionRequestHelper
 | 
			
		||||
import eu.kanade.presentation.util.relativeTimeSpanString
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
@@ -41,6 +46,7 @@ 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.storage.DiskUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
@@ -373,22 +379,24 @@ object SettingsDataScreen : SearchableSettings {
 | 
			
		||||
        val libraryPreferences = remember { Injekt.get<LibraryPreferences>() }
 | 
			
		||||
 | 
			
		||||
        val chapterCache = remember { Injekt.get<ChapterCache>() }
 | 
			
		||||
        var readableSizeSema by remember { mutableIntStateOf(0) }
 | 
			
		||||
        val readableSize = remember(readableSizeSema) { chapterCache.readableSize }
 | 
			
		||||
        var cacheReadableSizeSema by remember { mutableIntStateOf(0) }
 | 
			
		||||
        val cacheReadableSize = remember(cacheReadableSizeSema) { chapterCache.readableSize }
 | 
			
		||||
 | 
			
		||||
        return Preference.PreferenceGroup(
 | 
			
		||||
            title = stringResource(R.string.label_data),
 | 
			
		||||
            preferenceItems = listOf(
 | 
			
		||||
                getStorageInfoPref(cacheReadableSize),
 | 
			
		||||
 | 
			
		||||
                Preference.PreferenceItem.TextPreference(
 | 
			
		||||
                    title = stringResource(R.string.pref_clear_chapter_cache),
 | 
			
		||||
                    subtitle = stringResource(R.string.used_cache, readableSize),
 | 
			
		||||
                    subtitle = stringResource(R.string.used_cache, cacheReadableSize),
 | 
			
		||||
                    onClick = {
 | 
			
		||||
                        scope.launchNonCancellable {
 | 
			
		||||
                            try {
 | 
			
		||||
                                val deletedFiles = chapterCache.clear()
 | 
			
		||||
                                withUIContext {
 | 
			
		||||
                                    context.toast(context.getString(R.string.cache_deleted, deletedFiles))
 | 
			
		||||
                                    readableSizeSema++
 | 
			
		||||
                                    cacheReadableSizeSema++
 | 
			
		||||
                                }
 | 
			
		||||
                            } catch (e: Throwable) {
 | 
			
		||||
                                logcat(LogPriority.ERROR, e)
 | 
			
		||||
@@ -404,6 +412,33 @@ object SettingsDataScreen : SearchableSettings {
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
    fun getStorageInfoPref(
 | 
			
		||||
        chapterCacheReadableSize: String,
 | 
			
		||||
    ): Preference.PreferenceItem.CustomPreference {
 | 
			
		||||
        val context = LocalContext.current
 | 
			
		||||
        val available = remember {
 | 
			
		||||
            Formatter.formatFileSize(context, DiskUtil.getAvailableStorageSpace(Environment.getDataDirectory()))
 | 
			
		||||
        }
 | 
			
		||||
        val total = remember {
 | 
			
		||||
            Formatter.formatFileSize(context, DiskUtil.getTotalStorageSpace(Environment.getDataDirectory()))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Preference.PreferenceItem.CustomPreference(
 | 
			
		||||
            title = stringResource(R.string.pref_storage_usage),
 | 
			
		||||
        ) {
 | 
			
		||||
            BasePreferenceWidget(
 | 
			
		||||
                title = stringResource(R.string.pref_storage_usage),
 | 
			
		||||
                subcomponent = {
 | 
			
		||||
                    // TODO: downloads, SD cards, bar representation?, i18n
 | 
			
		||||
                    Box(modifier = Modifier.padding(horizontal = PrefsHorizontalPadding)) {
 | 
			
		||||
                        Text(text = "Available: $available / $total (chapter cache: $chapterCacheReadableSize)")
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private data class MissingRestoreComponents(
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,30 @@ object DiskUtil {
 | 
			
		||||
        return size
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the total space for the disk that a file path points to, in bytes.
 | 
			
		||||
     */
 | 
			
		||||
    fun getTotalStorageSpace(file: File): Long {
 | 
			
		||||
        return try {
 | 
			
		||||
            val stat = StatFs(file.absolutePath)
 | 
			
		||||
            stat.blockCountLong * stat.blockSizeLong
 | 
			
		||||
        } catch (_: Exception) {
 | 
			
		||||
            -1L
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the available space for the disk that a file path points to, in bytes.
 | 
			
		||||
     */
 | 
			
		||||
    fun getAvailableStorageSpace(file: File): Long {
 | 
			
		||||
        return try {
 | 
			
		||||
            val stat = StatFs(file.absolutePath)
 | 
			
		||||
            stat.availableBlocksLong * stat.blockSizeLong
 | 
			
		||||
        } catch (_: Exception) {
 | 
			
		||||
            -1L
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the available space for the disk that a file path points to, in bytes.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ interface Preference<T> {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * A preference used for internal app state that isn't really a user preference
 | 
			
		||||
         * and therefore should not be inplaces like backips.
 | 
			
		||||
         * and therefore should not be in places like backups.
 | 
			
		||||
         */
 | 
			
		||||
        fun isAppState(key: String): Boolean {
 | 
			
		||||
            return key.startsWith(APP_STATE_PREFIX)
 | 
			
		||||
 
 | 
			
		||||
@@ -506,6 +506,13 @@
 | 
			
		||||
    <string name="restoring_backup_canceled">Canceled restore</string>
 | 
			
		||||
    <string name="backup_info">You should keep copies of backups in other places as well. Backups may contain sensitive data including any stored passwords; be careful if sharing.</string>
 | 
			
		||||
    <string name="last_auto_backup_info">Last automatically backed up: %s</string>
 | 
			
		||||
    <string name="label_data">Data</string>
 | 
			
		||||
    <string name="pref_storage_usage">Storage usage</string>
 | 
			
		||||
    <string name="pref_clear_chapter_cache">Clear chapter cache</string>
 | 
			
		||||
    <string name="used_cache">Used: %1$s</string>
 | 
			
		||||
    <string name="cache_deleted">Cache cleared. %1$d files have been deleted</string>
 | 
			
		||||
    <string name="cache_delete_error">Error occurred while clearing</string>
 | 
			
		||||
    <string name="pref_auto_clear_chapter_cache">Clear chapter cache on app launch</string>
 | 
			
		||||
 | 
			
		||||
    <!-- Sync section -->
 | 
			
		||||
    <string name="syncing_library">Syncing library</string>
 | 
			
		||||
@@ -521,12 +528,6 @@
 | 
			
		||||
    <string name="pref_reset_user_agent_string">Reset default user agent string</string>
 | 
			
		||||
    <string name="requires_app_restart">Requires app restart to take effect</string>
 | 
			
		||||
    <string name="cookies_cleared">Cookies cleared</string>
 | 
			
		||||
    <string name="label_data">Data</string>
 | 
			
		||||
    <string name="pref_clear_chapter_cache">Clear chapter cache</string>
 | 
			
		||||
    <string name="used_cache">Used: %1$s</string>
 | 
			
		||||
    <string name="cache_deleted">Cache cleared. %1$d files have been deleted</string>
 | 
			
		||||
    <string name="cache_delete_error">Error occurred while clearing</string>
 | 
			
		||||
    <string name="pref_auto_clear_chapter_cache">Clear chapter cache on app launch</string>
 | 
			
		||||
    <string name="pref_invalidate_download_cache">Invalidate downloads index</string>
 | 
			
		||||
    <string name="pref_invalidate_download_cache_summary">Force app to recheck downloaded chapters</string>
 | 
			
		||||
    <string name="download_cache_invalidated">Downloads index invalidated</string>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user