Finished integrating new downloader

This commit is contained in:
Pupil
2020-02-03 11:54:29 +09:00
parent 874606bff9
commit d30c51bb3a
8 changed files with 211 additions and 116 deletions

View File

@@ -51,7 +51,6 @@ class Pupil : MultiDexApplication() {
val preference = PreferenceManager.getDefaultSharedPreferences(this) val preference = PreferenceManager.getDefaultSharedPreferences(this)
histories = Histories(File(ContextCompat.getDataDir(this), "histories.json")) histories = Histories(File(ContextCompat.getDataDir(this), "histories.json"))
downloads = Histories(File(ContextCompat.getDataDir(this), "downloads.json"))
favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json")) favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json"))
try { try {
@@ -64,7 +63,7 @@ class Pupil : MultiDexApplication() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel("download", getString(R.string.channel_download), NotificationManager.IMPORTANCE_LOW).apply { val channel = NotificationChannel("download", getString(R.string.channel_download), NotificationManager.IMPORTANCE_MIN).apply {
description = getString(R.string.channel_download_description) description = getString(R.string.channel_download_description)
enableLights(false) enableLights(false)
enableVibration(false) enableVibration(false)

View File

@@ -21,6 +21,7 @@ package xyz.quaver.pupil.adapters
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.Base64 import android.util.Base64
import android.util.Log
import android.util.SparseBooleanArray import android.util.SparseBooleanArray
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -29,6 +30,7 @@ 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.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.Animatable2Compat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@@ -65,9 +67,54 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
private val glide = Glide.with(context) private val glide = Glide.with(context)
private lateinit var favorites: Histories private lateinit var favorites: Histories
val timer = Timer()
inner class GalleryViewHolder(val view: View) : RecyclerView.ViewHolder(view) { inner class GalleryViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
var timerTask: TimerTask? = null var timerTask: TimerTask? = null
fun updateProgress(context: Context, galleryID: Int) = CoroutineScope(Dispatchers.Main).launch {
val cache = Cache(context).getCachedGallery(galleryID)
val reader = Cache(context).getReaderOrNull(galleryID)
Log.i("PUPILD", "$galleryID ${if (reader == null) null else "%d/%d".format(Cache(context).getImages(galleryID)?.count { it != null }, reader.galleryInfo.size)}")
if (reader == null) {
view.galleryblock_progressbar.visibility = View.GONE
view.galleryblock_progress_complete.visibility = View.GONE
return@launch
}
with(view.galleryblock_progressbar) {
progress = cache?.listFiles { file ->
file.nameWithoutExtension.toIntOrNull() != null
}?.size ?: 0
if (visibility == View.GONE) {
visibility = View.VISIBLE
max = reader.galleryInfo.size
}
if (progress == max) {
if (completeFlag.get(galleryID, false)) {
with(view.galleryblock_progress_complete) {
setImageResource(R.drawable.ic_progressbar)
visibility = View.VISIBLE
}
} else {
with(view.galleryblock_progress_complete) {
setImageDrawable(AnimatedVectorDrawableCompat.create(context, R.drawable.ic_progressbar_complete).apply {
this?.start()
})
visibility = View.VISIBLE
}
completeFlag.put(galleryID, true)
}
} else
view.galleryblock_progress_complete.visibility = View.INVISIBLE
}
}
fun bind(galleryBlock: GalleryBlock) { fun bind(galleryBlock: GalleryBlock) {
with(view) { with(view) {
val resources = context.resources val resources = context.resources
@@ -80,6 +127,10 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
val artists = galleryBlock.artists val artists = galleryBlock.artists
val series = galleryBlock.series val series = galleryBlock.series
galleryblock_thumbnail.setImageDrawable(CircularProgressDrawable(context).also {
it.start()
})
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
val thumbnail = Base64.decode(Cache(context).getThumbnail(galleryBlock.id), Base64.DEFAULT) val thumbnail = Base64.decode(Cache(context).getThumbnail(galleryBlock.id), Base64.DEFAULT)
@@ -114,47 +165,8 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
galleryblock_progressbar.visibility = View.GONE galleryblock_progressbar.visibility = View.GONE
if (timerTask == null) if (timerTask == null)
timerTask = Timer().schedule(0, 1000) { timerTask = timer.schedule(0, 1000) {
CoroutineScope(Dispatchers.Main).launch { updateProgress(context, galleryBlock.id)
val _cache = Cache(context).getCachedGallery(galleryBlock.id)
val _reader = Cache(context).getReaderOrNull(galleryBlock.id)
if (_reader == null) {
view.galleryblock_progressbar.visibility = View.GONE
view.galleryblock_progress_complete.visibility = View.GONE
return@launch
}
with(view.galleryblock_progressbar) {
progress = _cache?.listFiles { file ->
file.nameWithoutExtension.toIntOrNull() != null
}?.size ?: 0
if (visibility == View.GONE) {
visibility = View.VISIBLE
max = _reader.galleryInfo.size
}
if (progress == max) {
if (completeFlag.get(galleryBlock.id, false)) {
with(view.galleryblock_progress_complete) {
setImageResource(R.drawable.ic_progressbar)
visibility = View.VISIBLE
}
} else {
with(view.galleryblock_progress_complete) {
setImageDrawable(AnimatedVectorDrawableCompat.create(context, R.drawable.ic_progressbar_complete).apply {
this?.start()
})
visibility = View.VISIBLE
}
completeFlag.put(galleryBlock.id, true)
}
} else
view.galleryblock_progress_complete.visibility = View.INVISIBLE
}
}
} }
galleryblock_title.text = galleryBlock.title galleryblock_title.text = galleryBlock.title
@@ -343,8 +355,10 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) { override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
super.onViewDetachedFromWindow(holder) super.onViewDetachedFromWindow(holder)
if (holder is GalleryViewHolder) if (holder is GalleryViewHolder) {
holder.timerTask?.cancel() holder.timerTask?.cancel()
holder.timerTask = null
}
} }
override fun getItemCount() = override fun getItemCount() =

View File

@@ -47,6 +47,7 @@ class ReaderAdapter(private val context: Context,
var reader: Reader? = null var reader: Reader? = null
private val glide = Glide.with(context) private val glide = Glide.with(context)
val timer = Timer()
var onItemClickListener : ((Int) -> (Unit))? = null var onItemClickListener : ((Int) -> (Unit))? = null
@@ -81,51 +82,56 @@ class ReaderAdapter(private val context: Context,
onItemClickListener?.invoke(position) onItemClickListener?.invoke(position)
} }
holder.view.container.setOnClickListener {
onItemClickListener?.invoke(position)
}
(holder.view.container.layoutParams as ConstraintLayout.LayoutParams) (holder.view.container.layoutParams as ConstraintLayout.LayoutParams)
.dimensionRatio = "${reader!!.galleryInfo[position].width}:${reader!!.galleryInfo[position].height}" .dimensionRatio = "${reader!!.galleryInfo[position].width}:${reader!!.galleryInfo[position].height}"
holder.view.reader_item_progressbar.progress = DownloadWorker.getInstance(context).progress[galleryID]?.get(position)?.roundToInt() ?: 0
holder.view.reader_index.text = (position+1).toString() holder.view.reader_index.text = (position+1).toString()
val progress = DownloadWorker.getInstance(context).progress[galleryID]?.get(position) val images = Cache(context).getImages(galleryID)
if (progress?.isFinite() == false) { if (images?.get(position) != null) {
when { glide
progress.isInfinite() -> { .load(images[position])
var image = Cache(context).getImages(galleryID) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
while (image?.get(position) == null) .error(R.drawable.image_broken_variant)
image = Cache(context).getImages(galleryID) .apply {
if (BuildConfig.CENSOR)
glide override(5, 8)
.load(image[position])
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.error(R.drawable.image_broken_variant)
.apply {
if (BuildConfig.CENSOR)
override(5, 8)
}
.into(holder.view.image)
}
progress.isNaN() -> {
glide
.load(R.drawable.image_broken_variant)
.into(holder.view.image)
Snackbar
.make(
holder.view,
DownloadWorker.getInstance(context).exception[galleryID]!![position]?.message
?: context.getText(R.string.default_error_msg),
Snackbar.LENGTH_INDEFINITE
)
.show()
} }
.into(holder.view.image)
} else {
val progress = DownloadWorker.getInstance(context).progress[galleryID]?.get(position)
if (progress?.isNaN() == true) {
glide
.load(R.drawable.image_broken_variant)
.into(holder.view.image)
Snackbar
.make(
holder.view,
DownloadWorker.getInstance(context).exception[galleryID]!![position]?.message
?: context.getText(R.string.default_error_msg),
Snackbar.LENGTH_INDEFINITE
)
.show()
return
} }
} else { holder.view.reader_item_progressbar.progress =
if (progress?.isInfinite() == true)
100
else
progress?.roundToInt() ?: 0
holder.view.image.setImageDrawable(null) holder.view.image.setImageDrawable(null)
Timer().schedule(1000) {
timer.schedule(1000) {
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
notifyItemChanged(position) notifyItemChanged(position)
} }

View File

@@ -110,7 +110,6 @@ class MainActivity : AppCompatActivity() {
private var currentPage = 0 private var currentPage = 0
private lateinit var histories: Histories private lateinit var histories: Histories
private lateinit var downloads: Histories
private lateinit var favorites: Histories private lateinit var favorites: Histories
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -148,7 +147,6 @@ class MainActivity : AppCompatActivity() {
with(application as Pupil) { with(application as Pupil) {
this@MainActivity.histories = histories this@MainActivity.histories = histories
this@MainActivity.downloads = downloads
this@MainActivity.favorites = favorites this@MainActivity.favorites = favorites
} }
@@ -174,6 +172,12 @@ class MainActivity : AppCompatActivity() {
} }
} }
override fun onDestroy() {
super.onDestroy()
(main_recyclerview.adapter as GalleryBlockAdapter).timer.cancel()
}
override fun onResume() { override fun onResume() {
val preferences = PreferenceManager.getDefaultSharedPreferences(this) val preferences = PreferenceManager.getDefaultSharedPreferences(this)
@@ -405,7 +409,6 @@ class MainActivity : AppCompatActivity() {
if (worker.progress.indexOfKey(galleryID) >= 0) //download in progress if (worker.progress.indexOfKey(galleryID) >= 0) //download in progress
worker.cancel(galleryID) worker.cancel(galleryID)
else { else {
Cache(context).moveToDownload(galleryID)
Cache(context).setDownloading(galleryID, true) Cache(context).setDownloading(galleryID, true)
if (!worker.queue.contains(galleryID)) if (!worker.queue.contains(galleryID))
@@ -429,7 +432,6 @@ class MainActivity : AppCompatActivity() {
cache = Cache(context).getCachedGallery(galleryID) cache = Cache(context).getCachedGallery(galleryID)
} }
downloads.remove(galleryID)
histories.remove(galleryID) histories.remove(galleryID)
if (this@MainActivity.mode != Mode.SEARCH) if (this@MainActivity.mode != Mode.SEARCH)
@@ -963,8 +965,14 @@ class MainActivity : AppCompatActivity() {
} }
} }
Mode.DOWNLOAD -> { Mode.DOWNLOAD -> {
val downloads = getDownloadDirectory(this@MainActivity).listFiles { file ->
file.isDirectory and (file.name.toIntOrNull() != null) and File(file, ".metadata").exists()
}?.map {
it.name.toInt()
}?: listOf()
when { when {
query.isEmpty() -> downloads.toList().apply { query.isEmpty() -> downloads.apply {
totalItems = size totalItems = size
} }
else -> { else -> {

View File

@@ -38,9 +38,6 @@ import io.fabric.sdk.android.Fabric
import kotlinx.android.synthetic.main.activity_reader.* import kotlinx.android.synthetic.main.activity_reader.*
import kotlinx.android.synthetic.main.activity_reader.view.* import kotlinx.android.synthetic.main.activity_reader.view.*
import kotlinx.android.synthetic.main.dialog_numberpicker.view.* import kotlinx.android.synthetic.main.dialog_numberpicker.view.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.ImplicitReflectionSerializer
import xyz.quaver.hitomi.Reader import xyz.quaver.hitomi.Reader
import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.Pupil
@@ -199,6 +196,7 @@ class ReaderActivity : AppCompatActivity() {
super.onDestroy() super.onDestroy()
timer.cancel() timer.cancel()
(reader_recyclerview.adapter as ReaderAdapter).timer.cancel()
if (!Cache(this).isDownloading(galleryID)) if (!Cache(this).isDownloading(galleryID))
DownloadWorker.getInstance(this@ReaderActivity).cancel(galleryID) DownloadWorker.getInstance(this@ReaderActivity).cancel(galleryID)
@@ -327,10 +325,6 @@ class ReaderActivity : AppCompatActivity() {
animateDownloadFAB(false) animateDownloadFAB(false)
} else { } else {
CoroutineScope(Dispatchers.IO).launch {
Cache(context).moveToDownload(galleryID)
}
Cache(context).setDownloading(galleryID, true) Cache(context).setDownloading(galleryID, true)
animateDownloadFAB(true) animateDownloadFAB(true)
} }

View File

@@ -21,8 +21,6 @@ package xyz.quaver.pupil.util.download
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.util.Base64 import android.util.Base64
import android.util.Log
import android.util.SparseArray
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import kotlinx.coroutines.* import kotlinx.coroutines.*
@@ -175,15 +173,13 @@ class Cache(context: Context) : ContextWrapper(context) {
} }
} }
fun getImages(galleryID: Int): SparseArray<File>? { fun getImages(galleryID: Int): List<File?>? {
val gallery = getCachedGallery(galleryID) ?: return null val gallery = getCachedGallery(galleryID) ?: return null
val reader = getReaderOrNull(galleryID) ?: return null
val images = gallery.listFiles() ?: return null
return SparseArray<File>().apply { return reader.galleryInfo.indices.map { index ->
gallery.listFiles { file -> images.firstOrNull { file -> file.nameWithoutExtension.toIntOrNull() == index }
file.nameWithoutExtension.toIntOrNull() != null
}?.forEach {
put(it.nameWithoutExtension.toInt(), it)
}
} }
} }
@@ -209,7 +205,7 @@ class Cache(context: Context) : ContextWrapper(context) {
val cache = getCachedGallery(galleryID) val cache = getCachedGallery(galleryID)
if (cache != null) { if (cache != null) {
val download = getDownloadDirectory(this) val download = File(getDownloadDirectory(this), galleryID.toString())
if (!download.isParentOf(cache)) { if (!download.isParentOf(cache)) {
cache.copyRecursively(download, true) cache.copyRecursively(download, true)
@@ -222,7 +218,6 @@ class Cache(context: Context) : ContextWrapper(context) {
fun isDownloading(galleryID: Int) = getCachedMetadata(galleryID)?.isDownloading == true fun isDownloading(galleryID: Int) = getCachedMetadata(galleryID)?.isDownloading == true
fun setDownloading(galleryID: Int, isDownloading: Boolean) { fun setDownloading(galleryID: Int, isDownloading: Boolean) {
Log.i("PUPILD", "$galleryID $isDownloading")
setCachedMetadata(galleryID, Metadata(getCachedMetadata(galleryID), isDownloading = isDownloading)) setCachedMetadata(galleryID, Metadata(getCachedMetadata(galleryID), isDownloading = isDownloading))
} }

View File

@@ -18,10 +18,15 @@
package xyz.quaver.pupil.util.download package xyz.quaver.pupil.util.download
import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.SparseArray import android.util.SparseArray
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.TaskStackBuilder
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import io.fabric.sdk.android.Fabric import io.fabric.sdk.android.Fabric
@@ -34,6 +39,8 @@ import xyz.quaver.hitomi.urlFromUrlFromHash
import xyz.quaver.hiyobi.cookie import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.createImgList import xyz.quaver.hiyobi.createImgList
import xyz.quaver.hiyobi.user_agent import xyz.quaver.hiyobi.user_agent
import xyz.quaver.pupil.R
import xyz.quaver.pupil.ui.ReaderActivity
import java.io.IOException import java.io.IOException
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
@@ -66,7 +73,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
private var bufferedSource : BufferedSource? = null private var bufferedSource : BufferedSource? = null
override fun contentLength() = responseBody.contentLength() override fun contentLength() = responseBody.contentLength()
override fun contentType() = responseBody.contentType() override fun contentType() = responseBody.contentType() ?: null
override fun source(): BufferedSource { override fun source(): BufferedSource {
if (bufferedSource == null) if (bufferedSource == null)
@@ -104,6 +111,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
} }
//endregion //endregion
val notificationManager = NotificationManagerCompat.from(context)
val queue = LinkedBlockingQueue<Int>() val queue = LinkedBlockingQueue<Int>()
/* /*
@@ -131,6 +140,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 notification = SparseArray<NotificationCompat.Builder>()
private val loop = loop() private val loop = loop()
private val worker = SparseArray<Job?>() private val worker = SparseArray<Job?>()
@@ -169,6 +179,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress.clear() progress.clear()
exception.clear() exception.clear()
notification.clear()
notificationManager.cancelAll()
nRunners = 0 nRunners = 0
@@ -187,15 +199,19 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
it.cancel() it.cancel()
} }
if (progress.indexOfKey(galleryID) >= 0) { progress.remove(galleryID)
progress.remove(galleryID) exception.remove(galleryID)
exception.remove(galleryID) notification.remove(galleryID)
notificationManager.cancel(galleryID)
if (progress.indexOfKey(galleryID) >= 0) {
Cache(this@DownloadWorker).setDownloading(galleryID, false) Cache(this@DownloadWorker).setDownloading(galleryID, false)
nRunners-- nRunners--
} }
} }
fun isCompleted(galleryID: Int) = progress[galleryID]?.all { !it.isFinite() } == true
private fun queueDownload(galleryID: Int, reader: Reader, index: Int, callback: Callback) { private fun queueDownload(galleryID: Int, reader: Reader, index: Int, callback: Callback) {
val cache = Cache(this@DownloadWorker).getImages(galleryID) val cache = Cache(this@DownloadWorker).getImages(galleryID)
val lowQuality = preferences.getBoolean("low_quality", false) val lowQuality = preferences.getBoolean("low_quality", false)
@@ -204,6 +220,18 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
cache?.get(index)?.let { cache?.get(index)?.let {
progress[galleryID]?.set(index, Float.POSITIVE_INFINITY) progress[galleryID]?.set(index, Float.POSITIVE_INFINITY)
notify(galleryID)
if (isCompleted(galleryID)) {
with(Cache(this@DownloadWorker)) {
if (isDownloading(galleryID)) {
moveToDownload(galleryID)
setDownloading(galleryID, false)
}
}
nRunners--
}
return return
} }
@@ -250,6 +278,9 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress.put(galleryID, reader.galleryInfo.map { 0F }.toMutableList()) progress.put(galleryID, reader.galleryInfo.map { 0F }.toMutableList())
exception.put(galleryID, reader.galleryInfo.map { null }.toMutableList()) exception.put(galleryID, reader.galleryInfo.map { null }.toMutableList())
notification[galleryID].setContentTitle(reader.title)
notify(galleryID)
for (i in reader.galleryInfo.indices) { for (i in reader.galleryInfo.indices) {
val callback = object : Callback { val callback = object : Callback {
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
@@ -259,11 +290,14 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress[galleryID]?.set(i, Float.NaN) progress[galleryID]?.set(i, Float.NaN)
exception[galleryID]?.set(i, e) exception[galleryID]?.set(i, e)
if (progress[galleryID]?.all { !it.isFinite() } == true) { notify(galleryID)
progress.remove(galleryID)
exception.remove(galleryID)
Cache(this@DownloadWorker).setDownloading(galleryID, false) if (isCompleted(galleryID)) {
val cache = Cache(this@DownloadWorker)
if (cache.isDownloading(galleryID)) {
cache.moveToDownload(galleryID)
cache.setDownloading(galleryID, false)
}
nRunners-- nRunners--
} }
} }
@@ -278,11 +312,14 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
progress[galleryID]?.set(i, Float.POSITIVE_INFINITY) progress[galleryID]?.set(i, Float.POSITIVE_INFINITY)
} }
if (progress[galleryID]?.all { !it.isFinite() } == true) { notify(galleryID)
progress.remove(galleryID)
exception.remove(galleryID)
Cache(this@DownloadWorker).setDownloading(galleryID, false) if (isCompleted(galleryID)) {
val cache = Cache(this@DownloadWorker)
if (cache.isDownloading(galleryID)) {
cache.moveToDownload(galleryID)
cache.setDownloading(galleryID, false)
}
nRunners-- nRunners--
} }
} }
@@ -292,6 +329,43 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
} }
} }
private fun notify(galleryID: Int) {
val max = progress[galleryID]?.size ?: 0
val progress = progress[galleryID]?.count { !it.isFinite() } ?: 0
if (isCompleted(galleryID))
notification[galleryID]
.setContentText(getString(R.string.reader_notification_complete))
.setProgress(0, 0, false)
else
notification[galleryID]
.setProgress(max, progress, false)
.setContentText("$progress/$max")
if (Cache(this).isDownloading(galleryID))
notificationManager.notify(galleryID, notification[galleryID].build())
else
notificationManager.cancel(galleryID)
}
private fun initNotification(galleryID: Int) {
val intent = Intent(this, ReaderActivity::class.java).apply {
putExtra("galleryID", galleryID)
}
val pendingIntent = TaskStackBuilder.create(this).run {
addNextIntentWithParentStack(intent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
notification.put(galleryID, NotificationCompat.Builder(this, "download").apply {
setContentTitle(getString(R.string.reader_loading))
setContentText(getString(R.string.reader_notification_text))
setSmallIcon(android.R.drawable.stat_sys_download) // had to use this because old android doesn't support VectorDrawable on Notification :P
setContentIntent(pendingIntent)
setProgress(0, 0, true)
})
}
private fun loop() = CoroutineScope(Dispatchers.Default).launch { private fun loop() = CoroutineScope(Dispatchers.Default).launch {
while (true) { while (true) {
if (queue.isEmpty() || nRunners > preferences.getInt("max_download", 4)) if (queue.isEmpty() || nRunners > preferences.getInt("max_download", 4))
@@ -299,6 +373,12 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
val galleryID = queue.poll() ?: continue val galleryID = queue.poll() ?: continue
if (progress.indexOfKey(galleryID) >= 0) // Gallery already downloading!
continue
initNotification(galleryID)
if (Cache(this@DownloadWorker).isDownloading(galleryID))
notificationManager.notify(galleryID, notification[galleryID].build())
worker.put(galleryID, download(galleryID)) worker.put(galleryID, download(galleryID))
nRunners++ nRunners++
} }

View File

@@ -27,8 +27,7 @@
<item android:id="@+id/reader_type" <item android:id="@+id/reader_type"
android:title="" android:title=""
app:showAsAction="ifRoom" app:showAsAction="ifRoom"/>
android:visible="false"/>
<item android:id="@+id/reader_menu_page_indicator" <item android:id="@+id/reader_menu_page_indicator"
android:title="@string/page_indicator_placeholder" android:title="@string/page_indicator_placeholder"