Cache disable setting added

This commit is contained in:
tom5079
2020-06-21 14:45:57 +09:00
parent 902f705e89
commit 065845f1be
11 changed files with 93 additions and 47 deletions

View File

@@ -28,6 +28,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.CircularProgressDrawable import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.Animatable2Compat
@@ -77,7 +78,7 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
val reader = Cache(context).getReaderOrNull(galleryID) val reader = Cache(context).getReaderOrNull(galleryID)
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
if (reader == null) { if (reader == null || PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false)) {
view.galleryblock_progressbar.visibility = View.GONE view.galleryblock_progressbar.visibility = View.GONE
view.galleryblock_progress_complete.visibility = View.GONE view.galleryblock_progress_complete.visibility = View.GONE
return@launch return@launch

View File

@@ -32,7 +32,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import xyz.quaver.hitomi.Reader import xyz.quaver.hitomi.Reader
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.util.download.Cache
import xyz.quaver.pupil.util.download.DownloadWorker import xyz.quaver.pupil.util.download.DownloadWorker
import java.util.* import java.util.*
import kotlin.concurrent.schedule import kotlin.concurrent.schedule
@@ -50,6 +49,8 @@ class ReaderAdapter(private val glide: RequestManager,
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) class ViewHolder(val view: View) : RecyclerView.ViewHolder(view)
var downloadWorker: DownloadWorker? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return LayoutInflater.from(parent.context).inflate( return LayoutInflater.from(parent.context).inflate(
R.layout.item_reader, parent, false R.layout.item_reader, parent, false
@@ -61,6 +62,9 @@ class ReaderAdapter(private val glide: RequestManager,
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.view as ConstraintLayout holder.view as ConstraintLayout
if (downloadWorker == null)
downloadWorker = DownloadWorker.getInstance(holder.view.context)
if (isFullScreen) { if (isFullScreen) {
holder.view.layoutParams.height = RecyclerView.LayoutParams.MATCH_PARENT holder.view.layoutParams.height = RecyclerView.LayoutParams.MATCH_PARENT
holder.view.container.layoutParams.height = ConstraintLayout.LayoutParams.MATCH_PARENT holder.view.container.layoutParams.height = ConstraintLayout.LayoutParams.MATCH_PARENT
@@ -82,15 +86,15 @@ class ReaderAdapter(private val glide: RequestManager,
holder.view.reader_index.text = (position+1).toString() holder.view.reader_index.text = (position+1).toString()
val images = Cache(holder.view.context).getImage(galleryID, position) val image = downloadWorker!!.results[galleryID]?.get(position)
val progress = DownloadWorker.getInstance(holder.view.context).progress[galleryID]?.get(position) val progress = downloadWorker!!.progress[galleryID]?.get(position)
if (progress?.isInfinite() == true && images != null) { if (progress?.isInfinite() == true && image != null) {
holder.view.reader_item_progressbar.visibility = View.INVISIBLE holder.view.reader_item_progressbar.visibility = View.INVISIBLE
holder.view.image.post { holder.view.image.post {
glide glide
.load(images) .load(image)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true) .skipMemoryCache(true)
.fitCenter() .fitCenter()

View File

@@ -31,10 +31,7 @@ import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.widget.EditText import android.widget.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
@@ -439,13 +436,16 @@ class MainActivity : AppCompatActivity() {
onDownloadClickedHandler = { position -> onDownloadClickedHandler = { position ->
val galleryID = galleries[position].id val galleryID = galleries[position].id
val worker = DownloadWorker.getInstance(context) val worker = DownloadWorker.getInstance(context)
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false))
if (Cache(context).isDownloading(galleryID)) //download in progress Toast.makeText(context, R.string.settings_download_when_cache_disable_warning, Toast.LENGTH_SHORT).show()
worker.cancel(galleryID)
else { else {
Cache(context).setDownloading(galleryID, true) if (Cache(context).isDownloading(galleryID)) //download in progress
worker.cancel(galleryID)
else {
Cache(context).setDownloading(galleryID, true)
worker.queue.add(galleryID) worker.queue.add(galleryID)
}
} }
closeAllItems() closeAllItems()

View File

@@ -23,6 +23,7 @@ import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@@ -321,13 +322,17 @@ class ReaderActivity : AppCompatActivity() {
animateDownloadFAB(Cache(context).isDownloading(galleryID)) //If download in progress, animate button animateDownloadFAB(Cache(context).isDownloading(galleryID)) //If download in progress, animate button
setOnClickListener { setOnClickListener {
if (Cache(context).isDownloading(galleryID)) { if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false))
Cache(context).setDownloading(galleryID, false) Toast.makeText(context, R.string.settings_download_when_cache_disable_warning, Toast.LENGTH_SHORT).show()
else {
if (Cache(context).isDownloading(galleryID)) {
Cache(context).setDownloading(galleryID, false)
animateDownloadFAB(false) animateDownloadFAB(false)
} else { } else {
Cache(context).setDownloading(galleryID, true) Cache(context).setDownloading(galleryID, true)
animateDownloadFAB(true) animateDownloadFAB(true)
}
} }
} }
} }

View File

@@ -34,10 +34,8 @@ import xyz.quaver.pupil.util.getCachedGallery
import xyz.quaver.pupil.util.getDownloadDirectory import xyz.quaver.pupil.util.getDownloadDirectory
import xyz.quaver.pupil.util.isParentOf import xyz.quaver.pupil.util.isParentOf
import xyz.quaver.pupil.util.json import xyz.quaver.pupil.util.json
import java.io.BufferedInputStream
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.InputStream
import java.net.URL import java.net.URL
import java.util.* import java.util.*
import java.util.concurrent.locks.Lock import java.util.concurrent.locks.Lock
@@ -47,6 +45,7 @@ class Cache(context: Context) : ContextWrapper(context) {
companion object { companion object {
private val moving = mutableListOf<Int>() private val moving = mutableListOf<Int>()
private val readers = SparseArray<Reader?>()
} }
private val locks = SparseArray<Lock>() private val locks = SparseArray<Lock>()
@@ -68,7 +67,7 @@ class Cache(context: Context) : ContextWrapper(context) {
// Search in this order // Search in this order
// Download -> Cache // Download -> Cache
fun getCachedGallery(galleryID: Int) = getCachedGallery(this, galleryID).also { fun getCachedGallery(galleryID: Int) = getCachedGallery(this, galleryID).also {
if (!it.exists()) if (!it.exists() && !preference.getBoolean("cache_disable", false))
it.mkdirs() it.mkdirs()
} }
@@ -88,6 +87,9 @@ class Cache(context: Context) : ContextWrapper(context) {
} }
fun setCachedMetadata(galleryID: Int, metadata: Metadata) { fun setCachedMetadata(galleryID: Int, metadata: Metadata) {
if (preference.getBoolean("cache_disable", false))
return
val file = File(getCachedGallery(galleryID), ".metadata").also { val file = File(getCachedGallery(galleryID), ".metadata").also {
if (!it.exists()) if (!it.exists())
it.createNewFile() it.createNewFile()
@@ -99,6 +101,7 @@ class Cache(context: Context) : ContextWrapper(context) {
suspend fun getThumbnail(galleryID: Int): String? { suspend fun getThumbnail(galleryID: Int): String? {
val metadata = Cache(this).getCachedMetadata(galleryID) val metadata = Cache(this).getCachedMetadata(galleryID)
@Suppress("BlockingMethodInNonBlockingContext")
val thumbnail = if (metadata?.thumbnail == null) val thumbnail = if (metadata?.thumbnail == null)
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val thumbnails = getGalleryBlock(galleryID)?.thumbnails val thumbnails = getGalleryBlock(galleryID)?.thumbnails
@@ -159,7 +162,7 @@ class Cache(context: Context) : ContextWrapper(context) {
} }
fun getReaderOrNull(galleryID: Int): Reader? { fun getReaderOrNull(galleryID: Int): Reader? {
return getCachedMetadata(galleryID)?.reader return readers[galleryID] ?: getCachedMetadata(galleryID)?.reader
} }
suspend fun getReader(galleryID: Int): Reader? { suspend fun getReader(galleryID: Int): Reader? {
@@ -180,28 +183,33 @@ class Cache(context: Context) : ContextWrapper(context) {
it it
} }
val reader = if (metadata?.reader == null) { val reader =
var retval: Reader? = null if (readers[galleryID] != null)
return readers[galleryID]
else if (metadata?.reader == null) {
var retval: Reader? = null
for (source in sources) { for (source in sources) {
retval = try { retval = try {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
withTimeoutOrNull(1000) { withTimeoutOrNull(1000) {
source.value.invoke() source.value.invoke()
}
} }
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
null
} }
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e) if (retval != null)
null break
} }
if (retval != null) retval
break } else
} metadata.reader
retval readers.put(galleryID, reader)
} else
metadata.reader
setCachedMetadata( setCachedMetadata(
galleryID, galleryID,
@@ -242,18 +250,24 @@ class Cache(context: Context) : ContextWrapper(context) {
} }
fun putImage(galleryID: Int, index: Int, ext: String, data: InputStream) { fun putImage(galleryID: Int, index: Int, ext: String, data: ByteArray) {
if (preference.getBoolean("cache_disable", false))
return
val cache = File(getCachedGallery(galleryID), "%05d.$ext".format(index)).also { val cache = File(getCachedGallery(galleryID), "%05d.$ext".format(index)).also {
if (!it.exists()) if (!it.exists())
it.createNewFile() it.createNewFile()
} }
BufferedInputStream(data).use { FileOutputStream(cache).use {
it.copyTo(FileOutputStream(cache)) it.write(data)
} }
} }
fun moveToDownload(galleryID: Int) { fun moveToDownload(galleryID: Int) {
if (preference.getBoolean("cache_disable", false))
return
if (moving.contains(galleryID)) if (moving.contains(galleryID))
return return

View File

@@ -143,6 +143,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
* null -> Download in progress / Loading * null -> Download in progress / Loading
*/ */
val exception = SparseArray<MutableList<Throwable?>?>() val exception = SparseArray<MutableList<Throwable?>?>()
val results = SparseArray<MutableList<ByteArray?>?>()
val notification = SparseArray<NotificationCompat.Builder>() val notification = SparseArray<NotificationCompat.Builder>()
private val loop = loop() private val loop = loop()
@@ -189,6 +190,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress.clear() progress.clear()
exception.clear() exception.clear()
results.clear()
notification.clear() notification.clear()
notificationManager.cancelAll() notificationManager.cancelAll()
} }
@@ -205,6 +207,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress.remove(galleryID) progress.remove(galleryID)
exception.remove(galleryID) exception.remove(galleryID)
results.remove(galleryID)
notification.remove(galleryID) notification.remove(galleryID)
notificationManager.cancel(galleryID) notificationManager.cancel(galleryID)
@@ -253,6 +256,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
if (reader == null) { if (reader == null) {
progress.put(galleryID, null) progress.put(galleryID, null)
exception.put(galleryID, null) exception.put(galleryID, null)
results.put(galleryID, null)
Cache(this@DownloadWorker).setDownloading(galleryID, false) Cache(this@DownloadWorker).setDownloading(galleryID, false)
return@launch return@launch
@@ -267,6 +271,9 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
0F 0F
}.toMutableList()) }.toMutableList())
exception.put(galleryID, reader.galleryInfo.files.map { null }.toMutableList()) exception.put(galleryID, reader.galleryInfo.files.map { null }.toMutableList())
results.put(galleryID, reader.galleryInfo.files.indices.map { index ->
cache?.firstOrNull { it?.nameWithoutExtension?.toIntOrNull() == index }?.readBytes()
}.toMutableList())
if (notification[galleryID] == null) if (notification[galleryID] == null)
initNotification(galleryID) initNotification(galleryID)
@@ -316,13 +323,19 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
try { try {
response.body().use { response.body().use {
Cache(this@DownloadWorker).putImage(galleryID, i, ext, it!!.byteStream()) it!!
results[galleryID]?.set(i, it.source().readByteArray())
} }
progress[galleryID]?.set(i, Float.POSITIVE_INFINITY) progress[galleryID]?.set(i, Float.POSITIVE_INFINITY)
notify(galleryID) notify(galleryID)
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
results[galleryID]?.get(i)?.also {
Cache(this@DownloadWorker).putImage(galleryID, i, ext, it)
}
if (isCompleted(galleryID)) { if (isCompleted(galleryID)) {
with(Cache(this@DownloadWorker)) { with(Cache(this@DownloadWorker)) {
if (isDownloading(galleryID)) { if (isDownloading(galleryID)) {

View File

@@ -50,7 +50,6 @@ import java.io.File
import java.io.IOException import java.io.IOException
import java.net.URL import java.net.URL
import java.util.* import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
fun getReleases(url: String) : JsonArray { fun getReleases(url: String) : JsonArray {
@@ -320,7 +319,7 @@ fun importOldGalleries(context: Context, folder: File) = CoroutineScope(Dispatch
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val index = it.nameWithoutExtension.toIntOrNull() ?: return@forEach val index = it.nameWithoutExtension.toIntOrNull() ?: return@forEach
Cache(context).putImage(galleryID, index, it.extension, it.inputStream()) Cache(context).putImage(galleryID, index, it.extension, it.readBytes())
} }
} }

View File

@@ -145,4 +145,6 @@
<string name="settings_lock_fingerprint_prompt">Pupil指紋ロック™</string> <string name="settings_lock_fingerprint_prompt">Pupil指紋ロック™</string>
<string name="settings_lock_fingerprint_prompt_subtitle">こうかはばつぐんだ!</string> <string name="settings_lock_fingerprint_prompt_subtitle">こうかはばつぐんだ!</string>
<string name="default_query_dialog_filter_loli">登場人物を全て18歳以上にする</string> <string name="default_query_dialog_filter_loli">登場人物を全て18歳以上にする</string>
<string name="settings_cache_disable">キャッシュを使用しない</string>
<string name="settings_download_when_cache_disable_warning">キャッシュを使用しないため、ダウンロードできません</string>
</resources> </resources>

View File

@@ -145,4 +145,6 @@
<string name="settings_lock_fingerprint_prompt">Pupil 지문 인식™</string> <string name="settings_lock_fingerprint_prompt">Pupil 지문 인식™</string>
<string name="settings_lock_fingerprint_prompt_subtitle">힘세고 강한 지문 인식</string> <string name="settings_lock_fingerprint_prompt_subtitle">힘세고 강한 지문 인식</string>
<string name="default_query_dialog_filter_loli">히익 페도</string> <string name="default_query_dialog_filter_loli">히익 페도</string>
<string name="settings_cache_disable">캐시 비활성화</string>
<string name="settings_download_when_cache_disable_warning">캐시를 활성화 해야 다운로드를 진행할 수 있습니다</string>
</resources> </resources>

View File

@@ -153,6 +153,8 @@
<string name="settings_dl_location_available">%s available</string> <string name="settings_dl_location_available">%s available</string>
<string name="settings_dl_location_custom">Custom Location</string> <string name="settings_dl_location_custom">Custom Location</string>
<string name="settings_dl_location_not_writable">This folder is not writable. Please select another folder.</string> <string name="settings_dl_location_not_writable">This folder is not writable. Please select another folder.</string>
<string name="settings_cache_disable">Disable Cache</string>
<string name="settings_download_when_cache_disable_warning">Download is disabled when the cache is disabled</string>
<string name="settings_low_quality">Low quality images</string> <string name="settings_low_quality">Low quality images</string>
<string name="settings_low_quality_summary">Load low quality images to improve load speed and data usage</string> <string name="settings_low_quality_summary">Load low quality images to improve load speed and data usage</string>

View File

@@ -47,6 +47,10 @@
app:key="dl_location" app:key="dl_location"
app:title="@string/settings_dl_location"/> app:title="@string/settings_dl_location"/>
<SwitchPreferenceCompat
app:key="cache_disable"
app:title="@string/settings_cache_disable"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:key="low_quality" app:key="low_quality"
app:title="@string/settings_low_quality" app:title="@string/settings_low_quality"