Misc fixes

This commit is contained in:
Koitharu
2020-02-24 18:48:37 +02:00
parent f02c233292
commit a2a0e62b47
19 changed files with 218 additions and 30 deletions

View File

@@ -0,0 +1,6 @@
package org.koitharu.kotatsu.core.local
enum class Cache(val dir: String) {
PAGES("pages");
}

View File

@@ -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()

View File

@@ -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)
}
}
}

View File

@@ -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

View File

@@ -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)
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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)
}
}

View 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() }
}

View File

@@ -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())
}
}
}

View File

@@ -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
}

View File

@@ -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