From bc273bfb8f183de69cca5f6624e2d284ce1c2cc3 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 20 Jul 2023 15:50:32 +0300 Subject: [PATCH] Storage usage preference --- .editorconfig | 1 + .../koitharu/kotatsu/core/util/ext/Android.kt | 13 +- .../kotatsu/settings/SettingsActivity.kt | 1 + .../kotatsu/settings/tools/ToolsFragment.kt | 106 --------------- .../kotatsu/settings/tools/ToolsViewModel.kt | 68 ---------- .../settings/tools/model/StorageUsage.kt | 14 -- .../kotatsu/settings/userdata/StorageUsage.kt | 51 ++++++++ .../StorageUsagePreference.kt} | 58 +++++---- .../UserDataSettingsFragment.kt | 13 +- .../UserDataSettingsViewModel.kt | 40 +++++- .../res/layout-w600dp-land/fragment_tools.xml | 88 ------------- app/src/main/res/layout/fragment_tools.xml | 121 ------------------ ..._usage.xml => preference_memory_usage.xml} | 33 +---- app/src/main/res/xml/pref_root.xml | 2 +- app/src/main/res/xml/pref_user_data.xml | 10 +- 15 files changed, 153 insertions(+), 466 deletions(-) delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsFragment.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsViewModel.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/model/StorageUsage.kt create mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsage.kt rename app/src/main/kotlin/org/koitharu/kotatsu/settings/{tools/views/MemoryUsageView.kt => userdata/StorageUsagePreference.kt} (64%) rename app/src/main/kotlin/org/koitharu/kotatsu/settings/{ => userdata}/UserDataSettingsFragment.kt (95%) rename app/src/main/kotlin/org/koitharu/kotatsu/settings/{ => userdata}/UserDataSettingsViewModel.kt (71%) delete mode 100644 app/src/main/res/layout-w600dp-land/fragment_tools.xml delete mode 100644 app/src/main/res/layout/fragment_tools.xml rename app/src/main/res/layout/{layout_memory_usage.xml => preference_memory_usage.xml} (76%) diff --git a/.editorconfig b/.editorconfig index 999845632..63c49d65d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,6 +13,7 @@ disabled_rules = no-wildcard-imports, no-unused-imports [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] ij_continuation_indent_size = 4 +ij_xml_attribute_wrap = on_every_item [{*.kt,*.kts}] ij_kotlin_allow_trailing_comma_on_call_site = true diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt index 92403178d..5087a013e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt @@ -69,11 +69,14 @@ fun ActivityResultLauncher.resolve(context: Context, input: I): ResolveIn return pm.resolveActivity(intent, 0) } -fun ActivityResultLauncher.tryLaunch(input: I, options: ActivityOptionsCompat? = null): Boolean { - return runCatching { - launch(input, options) - }.isSuccess -} +fun ActivityResultLauncher.tryLaunch( + input: I, + options: ActivityOptionsCompat? = null, +): Boolean = runCatching { + launch(input, options) +}.onFailure { e -> + e.printStackTraceDebug() +}.isSuccess fun SharedPreferences.observe() = callbackFlow { val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index 7af612d70..cf695ed25 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -32,6 +32,7 @@ import org.koitharu.kotatsu.settings.about.AboutSettingsFragment import org.koitharu.kotatsu.settings.sources.SourceSettingsFragment import org.koitharu.kotatsu.settings.sources.SourcesListFragment import org.koitharu.kotatsu.settings.tracker.TrackerSettingsFragment +import org.koitharu.kotatsu.settings.userdata.UserDataSettingsFragment @AndroidEntryPoint class SettingsActivity : diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsFragment.kt deleted file mode 100644 index b8fa37327..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsFragment.kt +++ /dev/null @@ -1,106 +0,0 @@ -package org.koitharu.kotatsu.settings.tools - -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import androidx.core.graphics.Insets -import androidx.core.net.toUri -import androidx.core.view.isVisible -import androidx.core.view.updatePadding -import androidx.fragment.app.viewModels -import dagger.hilt.android.AndroidEntryPoint -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.github.AppVersion -import org.koitharu.kotatsu.core.ui.BaseFragment -import org.koitharu.kotatsu.core.util.ext.observe -import org.koitharu.kotatsu.core.util.ext.setChecked -import org.koitharu.kotatsu.databinding.FragmentToolsBinding -import org.koitharu.kotatsu.download.ui.list.DownloadsActivity -import org.koitharu.kotatsu.settings.SettingsActivity -import org.koitharu.kotatsu.settings.about.AppUpdateDialog - -@AndroidEntryPoint -class ToolsFragment : - BaseFragment(), - CompoundButton.OnCheckedChangeListener, - View.OnClickListener { - - private val viewModel by viewModels() - - override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentToolsBinding { - return FragmentToolsBinding.inflate(inflater, container, false) - } - - override fun onViewBindingCreated(binding: FragmentToolsBinding, savedInstanceState: Bundle?) { - super.onViewBindingCreated(binding, savedInstanceState) - binding.buttonSettings.setOnClickListener(this) - binding.buttonDownloads.setOnClickListener(this) - binding.cardUpdate.buttonChangelog.setOnClickListener(this) - binding.cardUpdate.buttonDownload.setOnClickListener(this) - binding.switchIncognito.setOnCheckedChangeListener(this) - binding.memoryUsageView.setManageButtonOnClickListener(this) - - binding.chart?.setDataChart( - listOf( - Pair(5, "Категория 1"), - Pair(3, "Категория 2"), - Pair(7, "Категория 3"), - ) - ) - binding.chart?.startAnimation() - - viewModel.isIncognitoModeEnabled.observe(viewLifecycleOwner) { - binding.switchIncognito.setChecked(it, false) - } - viewModel.storageUsage.observe(viewLifecycleOwner) { - binding.memoryUsageView.bind(it) - } - viewModel.appUpdate.observe(viewLifecycleOwner, ::onAppUpdateAvailable) - } - - override fun onClick(v: View) { - when (v.id) { - R.id.button_settings -> startActivity(SettingsActivity.newIntent(v.context)) - R.id.button_manage -> startActivity(SettingsActivity.newHistorySettingsIntent(v.context)) - R.id.button_downloads -> startActivity(DownloadsActivity.newIntent(v.context)) - R.id.button_download -> { - val url = viewModel.appUpdate.value?.apkUrl ?: return - val intent = Intent(Intent.ACTION_VIEW) - intent.data = url.toUri() - startActivity(Intent.createChooser(intent, getString(R.string.open_in_browser))) - } - - R.id.button_changelog -> { - val version = viewModel.appUpdate.value ?: return - AppUpdateDialog(v.context).show(version) - } - } - } - - override fun onCheckedChanged(button: CompoundButton?, isChecked: Boolean) { - viewModel.toggleIncognitoMode(isChecked) - } - - override fun onWindowInsetsChanged(insets: Insets) { - requireViewBinding().root.updatePadding( - bottom = insets.bottom, - ) - } - - private fun onAppUpdateAvailable(version: AppVersion?) { - if (version == null) { - requireViewBinding().cardUpdate.root.isVisible = false - return - } - requireViewBinding().cardUpdate.textSecondary.text = getString(R.string.new_version_s, version.name) - requireViewBinding().cardUpdate.root.isVisible = true - } - - companion object { - - fun newInstance() = ToolsFragment() - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsViewModel.kt deleted file mode 100644 index 9d0289bb0..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/ToolsViewModel.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.koitharu.kotatsu.settings.tools - -import androidx.lifecycle.viewModelScope -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.plus -import org.koitharu.kotatsu.core.github.AppUpdateRepository -import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.core.prefs.observeAsStateFlow -import org.koitharu.kotatsu.core.ui.BaseViewModel -import org.koitharu.kotatsu.local.data.CacheDir -import org.koitharu.kotatsu.local.data.LocalStorageManager -import org.koitharu.kotatsu.settings.tools.model.StorageUsage -import javax.inject.Inject - -@HiltViewModel -class ToolsViewModel @Inject constructor( - private val storageManager: LocalStorageManager, - private val settings: AppSettings, - appUpdateRepository: AppUpdateRepository, -) : BaseViewModel() { - - val appUpdate = appUpdateRepository.observeAvailableUpdate() - - val storageUsage: StateFlow = flow { - emit(collectStorageUsage()) - }.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, null) - - val isIncognitoModeEnabled = settings.observeAsStateFlow( - scope = viewModelScope + Dispatchers.Default, - key = AppSettings.KEY_INCOGNITO_MODE, - valueProducer = { isIncognitoModeEnabled }, - ) - - fun toggleIncognitoMode(isEnabled: Boolean) { - settings.isIncognitoModeEnabled = isEnabled - } - - private suspend fun collectStorageUsage(): StorageUsage { - val pagesCacheSize = storageManager.computeCacheSize(CacheDir.PAGES) - val otherCacheSize = storageManager.computeCacheSize() - pagesCacheSize - val storageSize = storageManager.computeStorageSize() - val availableSpace = storageManager.computeAvailableSize() - val totalBytes = pagesCacheSize + otherCacheSize + storageSize + availableSpace - return StorageUsage( - savedManga = StorageUsage.Item( - bytes = storageSize, - percent = (storageSize.toDouble() / totalBytes).toFloat(), - ), - pagesCache = StorageUsage.Item( - bytes = pagesCacheSize, - percent = (pagesCacheSize.toDouble() / totalBytes).toFloat(), - ), - otherCache = StorageUsage.Item( - bytes = otherCacheSize, - percent = (otherCacheSize.toDouble() / totalBytes).toFloat(), - ), - available = StorageUsage.Item( - bytes = availableSpace, - percent = (availableSpace.toDouble() / totalBytes).toFloat(), - ), - ) - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/model/StorageUsage.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/model/StorageUsage.kt deleted file mode 100644 index 0cb0a3c7b..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/model/StorageUsage.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.settings.tools.model - -class StorageUsage( - val savedManga: Item, - val pagesCache: Item, - val otherCache: Item, - val available: Item, -) { - - class Item( - val bytes: Long, - val percent: Float, - ) -} \ No newline at end of file diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsage.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsage.kt new file mode 100644 index 000000000..5d3f2c80a --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsage.kt @@ -0,0 +1,51 @@ +package org.koitharu.kotatsu.settings.userdata + +class StorageUsage( + val savedManga: Item, + val pagesCache: Item, + val otherCache: Item, + val available: Item, +) { + + class Item( + val bytes: Long, + val percent: Float, + ) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Item + + if (bytes != other.bytes) return false + return percent == other.percent + } + + override fun hashCode(): Int { + var result = bytes.hashCode() + result = 31 * result + percent.hashCode() + return result + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as StorageUsage + + if (savedManga != other.savedManga) return false + if (pagesCache != other.pagesCache) return false + if (otherCache != other.otherCache) return false + return available == other.available + } + + override fun hashCode(): Int { + var result = savedManga.hashCode() + result = 31 * result + pagesCache.hashCode() + result = 31 * result + otherCache.hashCode() + result = 31 * result + available.hashCode() + return result + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/views/MemoryUsageView.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsagePreference.kt similarity index 64% rename from app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/views/MemoryUsageView.kt rename to app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsagePreference.kt index c73ae6b67..20f114981 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tools/views/MemoryUsageView.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/StorageUsagePreference.kt @@ -1,48 +1,53 @@ -package org.koitharu.kotatsu.settings.tools.views +package org.koitharu.kotatsu.settings.userdata import android.content.Context import android.content.res.ColorStateList -import android.graphics.Color import android.util.AttributeSet -import android.view.LayoutInflater -import android.widget.LinearLayout import androidx.annotation.AttrRes import androidx.annotation.ColorInt import androidx.annotation.StringRes -import androidx.core.content.ContextCompat import androidx.core.graphics.ColorUtils import androidx.core.widget.TextViewCompat +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder import com.google.android.material.color.MaterialColors -import okio.ByteString.Companion.decodeHex +import kotlinx.coroutines.flow.FlowCollector import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.ext.getThemeColor -import org.koitharu.kotatsu.databinding.LayoutMemoryUsageBinding -import org.koitharu.kotatsu.settings.tools.model.StorageUsage +import org.koitharu.kotatsu.databinding.PreferenceMemoryUsageBinding +import com.google.android.material.R as materialR - -class MemoryUsageView @JvmOverloads constructor( +class StorageUsagePreference @JvmOverloads constructor( context: Context, - attrs: AttributeSet? = null -) : LinearLayout(context, attrs) { + attrs: AttributeSet? = null, +) : Preference(context, attrs), FlowCollector { - private val binding = LayoutMemoryUsageBinding.inflate(LayoutInflater.from(context), this) private val labelPattern = context.getString(R.string.memory_usage_pattern) + private var usage: StorageUsage? = null init { - orientation = VERTICAL - bind(null) + layoutResource = R.layout.preference_memory_usage + isSelectable = false + isPersistent = false } - fun setManageButtonOnClickListener(listener: OnClickListener?) { - binding.buttonManage.setOnClickListener(listener) - } - - fun bind(usage: StorageUsage?) { - val storageSegment = SegmentedBarView.Segment(usage?.savedManga?.percent ?: 0f, segmentColor(com.google.android.material.R.attr.colorPrimary)) - val pagesSegment = SegmentedBarView.Segment(usage?.pagesCache?.percent ?: 0f, segmentColor(com.google.android.material.R.attr.colorOnPrimaryContainer)) - val otherSegment = SegmentedBarView.Segment(usage?.otherCache?.percent ?: 0f, segmentColor(com.google.android.material.R.attr.colorTertiary)) + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + val binding = PreferenceMemoryUsageBinding.bind(holder.itemView) + val storageSegment = SegmentedBarView.Segment( + usage?.savedManga?.percent ?: 0f, + segmentColor(materialR.attr.colorPrimary), + ) + val pagesSegment = SegmentedBarView.Segment( + usage?.pagesCache?.percent ?: 0f, + segmentColor(materialR.attr.colorSecondary), + ) + val otherSegment = SegmentedBarView.Segment( + usage?.otherCache?.percent ?: 0f, + segmentColor(materialR.attr.colorTertiary), + ) with(binding) { bar.animateSegments(listOf(storageSegment, pagesSegment, otherSegment).filter { it.percent > 0f }) @@ -57,6 +62,11 @@ class MemoryUsageView @JvmOverloads constructor( } } + override suspend fun emit(value: StorageUsage?) { + usage = value + notifyChanged() + } + private fun formatLabel( item: StorageUsage.Item?, @StringRes labelResId: Int, @@ -91,7 +101,7 @@ class MemoryUsageView @JvmOverloads constructor( val colorHex = String.format("%06x", context.getThemeColor(resId)) val hue = getHue(colorHex) val color = ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f)) - val backgroundColor = context.getThemeColor(com.google.android.material.R.attr.colorSurfaceContainerHigh) + val backgroundColor = context.getThemeColor(materialR.attr.colorSurfaceContainerHigh) return MaterialColors.harmonize(color, backgroundColor) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsFragment.kt similarity index 95% rename from app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsFragment.kt rename to app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsFragment.kt index 0eea92ea2..19ade169c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsFragment.kt @@ -1,6 +1,5 @@ -package org.koitharu.kotatsu.settings +package org.koitharu.kotatsu.settings.userdata -import android.content.ActivityNotFoundException import android.content.Intent import android.content.SharedPreferences import android.net.Uri @@ -28,7 +27,7 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent -import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug +import org.koitharu.kotatsu.core.util.ext.tryLaunch import org.koitharu.kotatsu.local.data.CacheDir import org.koitharu.kotatsu.settings.backup.BackupDialogFragment import org.koitharu.kotatsu.settings.backup.RestoreDialogFragment @@ -76,6 +75,9 @@ class UserDataSettingsFragment : BasePreferenceFragment(R.string.data_and_privac pref.summary = pref.context.resources.getQuantityString(R.plurals.items, it, it) } } + findPreference("storage_usage")?.let { pref -> + viewModel.storageUsage.observe(viewLifecycleOwner, pref) + } viewModel.loadingKeys.observe(viewLifecycleOwner) { keys -> preferenceScreen.forEach { pref -> pref.isEnabled = pref.key !in keys @@ -129,10 +131,7 @@ class UserDataSettingsFragment : BasePreferenceFragment(R.string.data_and_privac } AppSettings.KEY_RESTORE -> { - try { - backupSelectCall.launch(arrayOf("*/*")) - } catch (e: ActivityNotFoundException) { - e.printStackTraceDebug() + if (!backupSelectCall.tryLaunch(arrayOf("*/*"))) { Snackbar.make( listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT, ).show() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsViewModel.kt similarity index 71% rename from app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsViewModel.kt rename to app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsViewModel.kt index 5739402ae..626d0f601 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/UserDataSettingsViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/UserDataSettingsViewModel.kt @@ -1,7 +1,9 @@ -package org.koitharu.kotatsu.settings +package org.koitharu.kotatsu.settings.userdata import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.runInterruptible @@ -36,6 +38,9 @@ class UserDataSettingsViewModel @Inject constructor( val feedItemsCount = MutableStateFlow(-1) val httpCacheSize = MutableStateFlow(-1L) val cacheSizes = EnumMap>(CacheDir::class.java) + val storageUsage = MutableStateFlow(null) + + private var storageUsageJob: Job? = null init { CacheDir.values().forEach { @@ -55,6 +60,7 @@ class UserDataSettingsViewModel @Inject constructor( launchJob(Dispatchers.Default) { httpCacheSize.value = runInterruptible { httpCache.size() } } + loadStorageUsage() } fun clearCache(key: String, cache: CacheDir) { @@ -63,6 +69,7 @@ class UserDataSettingsViewModel @Inject constructor( loadingKeys.update { it + key } storageManager.clearCache(cache) checkNotNull(cacheSizes[cache]).value = storageManager.computeCacheSize(cache) + loadStorageUsage() } finally { loadingKeys.update { it - key } } @@ -78,6 +85,7 @@ class UserDataSettingsViewModel @Inject constructor( httpCache.size() } httpCacheSize.value = size + loadStorageUsage() } finally { loadingKeys.update { it - AppSettings.KEY_HTTP_CACHE_CLEAR } } @@ -106,4 +114,34 @@ class UserDataSettingsViewModel @Inject constructor( onActionDone.call(ReversibleAction(R.string.updates_feed_cleared, null)) } } + + private fun loadStorageUsage() { + val prevJob = storageUsageJob + storageUsageJob = launchJob(Dispatchers.Default) { + prevJob?.cancelAndJoin() + val pagesCacheSize = storageManager.computeCacheSize(CacheDir.PAGES) + val otherCacheSize = storageManager.computeCacheSize() - pagesCacheSize + val storageSize = storageManager.computeStorageSize() + val availableSpace = storageManager.computeAvailableSize() + val totalBytes = pagesCacheSize + otherCacheSize + storageSize + availableSpace + storageUsage.value = StorageUsage( + savedManga = StorageUsage.Item( + bytes = storageSize, + percent = (storageSize.toDouble() / totalBytes).toFloat(), + ), + pagesCache = StorageUsage.Item( + bytes = pagesCacheSize, + percent = (pagesCacheSize.toDouble() / totalBytes).toFloat(), + ), + otherCache = StorageUsage.Item( + bytes = otherCacheSize, + percent = (otherCacheSize.toDouble() / totalBytes).toFloat(), + ), + available = StorageUsage.Item( + bytes = availableSpace, + percent = (availableSpace.toDouble() / totalBytes).toFloat(), + ), + ) + } + } } diff --git a/app/src/main/res/layout-w600dp-land/fragment_tools.xml b/app/src/main/res/layout-w600dp-land/fragment_tools.xml deleted file mode 100644 index ba158413a..000000000 --- a/app/src/main/res/layout-w600dp-land/fragment_tools.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_tools.xml b/app/src/main/res/layout/fragment_tools.xml deleted file mode 100644 index 353104b92..000000000 --- a/app/src/main/res/layout/fragment_tools.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/layout_memory_usage.xml b/app/src/main/res/layout/preference_memory_usage.xml similarity index 76% rename from app/src/main/res/layout/layout_memory_usage.xml rename to app/src/main/res/layout/preference_memory_usage.xml index 54bdcc752..e054367da 100644 --- a/app/src/main/res/layout/layout_memory_usage.xml +++ b/app/src/main/res/layout/preference_memory_usage.xml @@ -1,42 +1,19 @@ - - - - - - -