Misc fixes
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
package org.koitharu.kotatsu.core.local
|
||||
|
||||
enum class Cache(val dir: String) {
|
||||
|
||||
PAGES("pages");
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import java.io.OutputStream
|
||||
class PagesCache(context: Context) {
|
||||
|
||||
private val cacheDir = context.externalCacheDir ?: context.cacheDir
|
||||
private val lruCache = DiskLruCache.create(cacheDir.sub("pages"), FileSizeUtils.mbToBytes(200))
|
||||
private val lruCache = DiskLruCache.create(cacheDir.sub(Cache.PAGES.dir), FileSizeUtils.mbToBytes(200))
|
||||
|
||||
operator fun get(url: String): File? {
|
||||
return lruCache.get(url)?.takeIfReadable()
|
||||
|
||||
@@ -20,7 +20,6 @@ class MangaGridHolder(parent: ViewGroup) : BaseViewHolder<Manga, MangaHistory?>(
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import coil.api.load
|
||||
import coil.request.RequestDisposable
|
||||
import coil.size.Scale
|
||||
import kotlinx.android.synthetic.main.item_manga_list_details.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
@@ -26,7 +27,6 @@ class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder<Manga, MangaHis
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
if(data.rating == Manga.NO_RATING) {
|
||||
textView_rating.isVisible = false
|
||||
|
||||
@@ -23,7 +23,6 @@ class MangaListHolder(parent: ViewGroup) :
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.koitharu.kotatsu.ui.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.Preference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.local.Cache
|
||||
import org.koitharu.kotatsu.ui.common.BasePreferenceFragment
|
||||
import org.koitharu.kotatsu.utils.CacheUtils
|
||||
import org.koitharu.kotatsu.utils.FileSizeUtils
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
|
||||
class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cache) {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_history)
|
||||
findPreference<Preference>(R.string.key_pages_cache_clear)?.let { pref ->
|
||||
lifecycleScope.launchWhenStarted {
|
||||
val size = withContext(Dispatchers.IO) {
|
||||
CacheUtils.computeCacheSize(pref.context, Cache.PAGES.dir)
|
||||
}
|
||||
pref.summary = FileSizeUtils.formatBytes(pref.context, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||
return when(preference.key) {
|
||||
getString(R.string.key_pages_cache_clear) -> {
|
||||
clearCache(preference, Cache.PAGES)
|
||||
true
|
||||
}
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearCache(preference: Preference, cache: Cache) {
|
||||
val ctx = preference.context.applicationContext
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
preference.isEnabled = false
|
||||
val size = withContext(Dispatchers.IO) {
|
||||
CacheUtils.clearCache(ctx, cache.dir)
|
||||
CacheUtils.computeCacheSize(ctx, cache.dir)
|
||||
}
|
||||
preference.summary = FileSizeUtils.formatBytes(ctx, size)
|
||||
} catch (e: Exception) {
|
||||
preference.summary = e.getDisplayMessage(ctx.resources)
|
||||
} finally {
|
||||
preference.isEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.ui.common.BaseFragment
|
||||
|
||||
class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources) {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.setTitle(R.string.remote_sources)
|
||||
}
|
||||
}
|
||||
27
app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt
Normal file
27
app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import org.koitharu.kotatsu.utils.ext.computeSize
|
||||
import org.koitharu.kotatsu.utils.ext.sub
|
||||
import org.koitharu.kotatsu.utils.ext.sumByLong
|
||||
|
||||
object CacheUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun getCacheDirs(context: Context) = (context.externalCacheDirs + context.cacheDir)
|
||||
.filterNotNull()
|
||||
.distinctBy { it.absolutePath }
|
||||
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun computeCacheSize(context: Context, name: String) = getCacheDirs(context)
|
||||
.map { it.sub(name) }
|
||||
.sumByLong { x -> x.computeSize() }
|
||||
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun clearCache(context: Context, name: String) = getCacheDirs(context)
|
||||
.map { it.sub(name) }
|
||||
.forEach { it.deleteRecursively() }
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.content.Context
|
||||
import org.koitharu.kotatsu.R
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
|
||||
|
||||
object FileSizeUtils {
|
||||
|
||||
@JvmStatic
|
||||
@@ -7,4 +14,22 @@ object FileSizeUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun kbToBytes(kb: Int) = 1024L * kb
|
||||
|
||||
@JvmStatic
|
||||
fun formatBytes(context: Context, bytes: Long): String {
|
||||
val units = context.getString(R.string.text_file_sizes).split('|')
|
||||
if (bytes <= 0) {
|
||||
return "0 ${units.first()}"
|
||||
}
|
||||
val digitGroups = (log10(bytes.toDouble()) / log10(1024.0)).toInt()
|
||||
return buildString {
|
||||
append(
|
||||
DecimalFormat("#,##0.#").format(
|
||||
bytes / 1024.0.pow(digitGroups.toDouble())
|
||||
).toString()
|
||||
)
|
||||
append(' ')
|
||||
append(units.getOrNull(digitGroups).orEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,20 @@ package org.koitharu.kotatsu.utils.ext
|
||||
fun <T> MutableCollection<T>.replaceWith(subject: Iterable<T>) {
|
||||
clear()
|
||||
addAll(subject)
|
||||
}
|
||||
|
||||
inline fun <T> Array<out T>.sumByLong(selector: (T) -> Long): Long {
|
||||
var sum = 0L
|
||||
for (element in this) {
|
||||
sum += selector(element)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {
|
||||
var sum = 0L
|
||||
for (element in this) {
|
||||
sum += selector(element)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
@@ -10,4 +10,12 @@ fun File.takeIfReadable() = takeIf { it.exists() && it.canRead() }
|
||||
|
||||
fun ZipFile.readText(entry: ZipEntry) = getInputStream(entry).bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
}
|
||||
|
||||
fun File.computeSize(): Long = listFiles()?.sumByLong { x ->
|
||||
if (x.isDirectory) {
|
||||
x.computeSize()
|
||||
} else {
|
||||
x.length()
|
||||
}
|
||||
} ?: 0L
|
||||
Reference in New Issue
Block a user