This commit is contained in:
tom5079
2020-12-27 13:39:57 +09:00
parent 3051d800bd
commit 8703fde9b1
9 changed files with 143 additions and 36 deletions

View File

@@ -20,6 +20,7 @@ package xyz.quaver.pupil.util.downloader
import android.content.Context
import android.content.ContextWrapper
import android.net.Uri
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

View File

@@ -18,7 +18,13 @@
package xyz.quaver.pupil.util.downloader
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.TaskStackBuilder
import com.google.firebase.crashlytics.FirebaseCrashlytics
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -26,10 +32,14 @@ import kotlinx.coroutines.launch
import okhttp3.*
import okio.*
import xyz.quaver.pupil.PupilInterceptor
import xyz.quaver.pupil.R
import xyz.quaver.pupil.client
import xyz.quaver.pupil.interceptors
import xyz.quaver.pupil.services.DownloadService
import xyz.quaver.pupil.sources.sources
import xyz.quaver.pupil.ui.ReaderActivity
import xyz.quaver.pupil.util.cleanCache
import xyz.quaver.pupil.util.normalizeID
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap
@@ -51,6 +61,79 @@ class Downloader private constructor(private val context: Context) {
}
}
//region Notification
private val notificationManager by lazy {
NotificationManagerCompat.from(context)
}
private val serviceNotification by lazy {
NotificationCompat.Builder(context, "downloader")
.setContentTitle(context.getString(R.string.downloader_running))
.setProgress(0, 0, false)
.setSmallIcon(R.drawable.ic_notification)
.setOngoing(true)
}
private val notification = ConcurrentHashMap<String, NotificationCompat.Builder?>()
private fun initNotification(source: String, itemID: String) {
val key = "$source-$itemID"
val intent = Intent(context, ReaderActivity::class.java)
.putExtra("source", source)
.putExtra("itemID", itemID)
val pendingIntent = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(intent)
getPendingIntent(itemID.hashCode(), PendingIntent.FLAG_UPDATE_CURRENT)
}
val action =
NotificationCompat.Action.Builder(0, context.getText(android.R.string.cancel),
PendingIntent.getService(
context,
R.id.notification_download_cancel_action.normalizeID(),
Intent(context, DownloadService::class.java)
.putExtra(DownloadService.KEY_COMMAND, DownloadService.COMMAND_CANCEL)
.putExtra(DownloadService.KEY_ID, itemID),
PendingIntent.FLAG_UPDATE_CURRENT),
).build()
notification[key] = NotificationCompat.Builder(context, "download").apply {
setContentTitle(context.getString(R.string.reader_loading))
setContentText(context.getString(R.string.reader_notification_text))
setSmallIcon(R.drawable.ic_notification)
setContentIntent(pendingIntent)
addAction(action)
setProgress(0, 0, true)
setOngoing(true)
}
notify(source, itemID)
}
@SuppressLint("RestrictedApi")
private fun notify(source: String, itemID: String) {
val key = "$source-$itemID"
val max = progress[key]?.size ?: 0
val progress = progress[key]?.count { it == Float.POSITIVE_INFINITY } ?: 0
val notification = notification[key] ?: return
if (isCompleted(source, itemID)) {
notification
.setContentText(context.getString(R.string.reader_notification_complete))
.setProgress(0, 0, false)
.setOngoing(false)
.mActions.clear()
notificationManager.cancel(key.hashCode())
} else
notification
.setProgress(max, progress, false)
.setContentText("$progress/$max")
}
//endregion
//region ProgressListener
@Suppress("UNCHECKED_CAST")
private val progressListener: ProgressListener = { (source, itemID, index), bytesRead, contentLength, done ->
@@ -134,6 +217,8 @@ class Downloader private constructor(private val context: Context) {
return progress["$source-$itemID"]
}
fun isCompleted(source: String, itemID: String) = progress["$source-$itemID"]?.all { it == Float.POSITIVE_INFINITY } == true
fun cancel() {
client.dispatcher().queuedCalls().filter {
it.request().tag() is Tag
@@ -178,6 +263,7 @@ class Downloader private constructor(private val context: Context) {
if (isDownloading(source, itemID))
return@launch
initNotification(source, itemID)
cleanCache(context)
val source = sources[source] ?: return@launch
@@ -188,15 +274,8 @@ class Downloader private constructor(private val context: Context) {
if (cache.metadata.imageList?.get(i) == null) 0F else Float.POSITIVE_INFINITY
}
with (Cache.getInstance(context, source.name, itemID).metadata) {
if (imageList == null)
imageList = MutableList(it.size) { null }
imageList!!.forEachIndexed { index, s ->
if (s != null)
progress["${source.name}-$itemID"]?.set(index, Float.POSITIVE_INFINITY)
}
}
if (cache.metadata.imageList == null)
cache.metadata.imageList = MutableList(it.size) { null }
onImageListLoadedCallback?.invoke(it)
}.forEachIndexed { index, url ->