222 lines
No EOL
9.3 KiB
Kotlin
222 lines
No EOL
9.3 KiB
Kotlin
package ani.dantotsu.notifications.subscription
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.app.PendingIntent
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.graphics.Bitmap
|
|
import android.graphics.BitmapFactory
|
|
import android.os.Build
|
|
import androidx.core.app.NotificationCompat
|
|
import androidx.core.app.NotificationManagerCompat
|
|
import ani.dantotsu.App
|
|
import ani.dantotsu.FileUrl
|
|
import ani.dantotsu.R
|
|
import ani.dantotsu.connections.anilist.UrlMedia
|
|
import ani.dantotsu.hasNotificationPermission
|
|
import ani.dantotsu.notifications.Task
|
|
import ani.dantotsu.parsers.AnimeSources
|
|
import ani.dantotsu.parsers.Episode
|
|
import ani.dantotsu.parsers.MangaChapter
|
|
import ani.dantotsu.parsers.MangaSources
|
|
import ani.dantotsu.settings.saving.PrefManager
|
|
import ani.dantotsu.settings.saving.PrefName
|
|
import ani.dantotsu.util.Logger
|
|
import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK
|
|
import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK_PROGRESS
|
|
import eu.kanade.tachiyomi.data.notification.Notifications.ID_SUBSCRIPTION_CHECK_PROGRESS
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
|
class SubscriptionNotificationTask : Task {
|
|
private var currentlyPerforming = false
|
|
|
|
@SuppressLint("MissingPermission")
|
|
override suspend fun execute(context: Context): Boolean {
|
|
if (!currentlyPerforming) {
|
|
try {
|
|
withContext(Dispatchers.IO) {
|
|
PrefManager.init(context)
|
|
currentlyPerforming = true
|
|
App.context = context
|
|
Logger.log("SubscriptionNotificationTask: execute")
|
|
var timeout = 15_000L
|
|
do {
|
|
delay(1000)
|
|
timeout -= 1000
|
|
} while (timeout > 0 && !AnimeSources.isInitialized && !MangaSources.isInitialized)
|
|
Logger.log("SubscriptionNotificationTask: timeout: $timeout")
|
|
if (timeout <= 0) {
|
|
currentlyPerforming = false
|
|
return@withContext
|
|
}
|
|
val subscriptions = SubscriptionHelper.getSubscriptions()
|
|
var i = 0
|
|
val index = subscriptions.map { i++; it.key to i }.toMap()
|
|
val notificationManager = NotificationManagerCompat.from(context)
|
|
|
|
val progressEnabled: Boolean =
|
|
PrefManager.getVal(PrefName.SubscriptionCheckingNotifications)
|
|
val progressNotification = if (progressEnabled) getProgressNotification(
|
|
context,
|
|
subscriptions.size
|
|
) else null
|
|
if (progressNotification != null && hasNotificationPermission(context)) {
|
|
notificationManager.notify(
|
|
ID_SUBSCRIPTION_CHECK_PROGRESS,
|
|
progressNotification.build()
|
|
)
|
|
//Seems like if the parent coroutine scope gets cancelled, the notification stays
|
|
//So adding this as a safeguard? dk if this will be useful
|
|
CoroutineScope(Dispatchers.Main).launch {
|
|
delay(5 * subscriptions.size * 1000L)
|
|
notificationManager.cancel(ID_SUBSCRIPTION_CHECK_PROGRESS)
|
|
}
|
|
}
|
|
|
|
fun progress(progress: Int, parser: String, media: String) {
|
|
if (progressNotification != null && hasNotificationPermission(context))
|
|
notificationManager.notify(
|
|
ID_SUBSCRIPTION_CHECK_PROGRESS,
|
|
progressNotification
|
|
.setProgress(subscriptions.size, progress, false)
|
|
.setContentText("$media on $parser")
|
|
.build()
|
|
)
|
|
}
|
|
|
|
subscriptions.toList().map {
|
|
val media = it.second
|
|
val text = if (media.isAnime) {
|
|
val parser =
|
|
SubscriptionHelper.getAnimeParser(media.id)
|
|
progress(index[it.first]!!, parser.name, media.name)
|
|
val ep: Episode? =
|
|
SubscriptionHelper.getEpisode(
|
|
parser,
|
|
media.id
|
|
)
|
|
if (ep != null) context.getString(R.string.episode) + "${ep.number}${
|
|
if (ep.title != null) " : ${ep.title}" else ""
|
|
}${
|
|
if (ep.isFiller) " [Filler]" else ""
|
|
} " + context.getString(R.string.just_released) to ep.thumbnail
|
|
else null
|
|
} else {
|
|
val parser =
|
|
SubscriptionHelper.getMangaParser(media.id)
|
|
progress(index[it.first]!!, parser.name, media.name)
|
|
val ep: MangaChapter? =
|
|
SubscriptionHelper.getChapter(
|
|
parser,
|
|
media.id
|
|
)
|
|
if (ep != null) ep.number + " " + context.getString(R.string.just_released) to null
|
|
else null
|
|
} ?: return@map
|
|
val notification = createNotification(
|
|
context.applicationContext,
|
|
media,
|
|
text.first,
|
|
text.second
|
|
)
|
|
if (hasNotificationPermission(context)) {
|
|
NotificationManagerCompat.from(context)
|
|
.notify(
|
|
CHANNEL_SUBSCRIPTION_CHECK,
|
|
System.currentTimeMillis().toInt(),
|
|
notification
|
|
)
|
|
}
|
|
}
|
|
|
|
if (progressNotification != null) notificationManager.cancel(
|
|
ID_SUBSCRIPTION_CHECK_PROGRESS
|
|
)
|
|
currentlyPerforming = false
|
|
}
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.log("SubscriptionNotificationTask: ${e.message}")
|
|
Logger.log(e)
|
|
return false
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
@SuppressLint("MissingPermission")
|
|
private fun createNotification(
|
|
context: Context,
|
|
media: SubscriptionHelper.Companion.SubscribeMedia,
|
|
text: String,
|
|
thumbnail: FileUrl?
|
|
): android.app.Notification {
|
|
val pendingIntent = getIntent(context, media.id)
|
|
val icon =
|
|
if (media.isAnime) R.drawable.ic_round_movie_filter_24 else R.drawable.ic_round_menu_book_24
|
|
|
|
val builder = NotificationCompat.Builder(context, CHANNEL_SUBSCRIPTION_CHECK)
|
|
.setSmallIcon(icon)
|
|
.setContentTitle(media.name)
|
|
.setContentText(text)
|
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
|
.setContentIntent(pendingIntent)
|
|
.setAutoCancel(true)
|
|
|
|
if (thumbnail != null) {
|
|
val bitmap = getBitmapFromUrl(thumbnail.url)
|
|
if (bitmap != null) {
|
|
builder.setLargeIcon(bitmap)
|
|
}
|
|
}
|
|
|
|
return builder.build()
|
|
|
|
}
|
|
|
|
private fun getProgressNotification(
|
|
context: Context,
|
|
size: Int
|
|
): NotificationCompat.Builder {
|
|
return NotificationCompat.Builder(context, CHANNEL_SUBSCRIPTION_CHECK_PROGRESS)
|
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
|
.setSmallIcon(R.drawable.notification_icon)
|
|
.setContentTitle(context.getString(R.string.checking_subscriptions_title))
|
|
.setProgress(size, 0, false)
|
|
.setOngoing(true)
|
|
.setAutoCancel(false)
|
|
}
|
|
|
|
private fun getBitmapFromUrl(url: String): Bitmap? {
|
|
return try {
|
|
val inputStream = java.net.URL(url).openStream()
|
|
BitmapFactory.decodeStream(inputStream)
|
|
} catch (e: Exception) {
|
|
null
|
|
}
|
|
}
|
|
|
|
|
|
private fun getIntent(context: Context, mediaId: Int): PendingIntent {
|
|
val notifyIntent = Intent(context, UrlMedia::class.java)
|
|
.putExtra("media", mediaId)
|
|
.setAction(mediaId.toString())
|
|
.apply {
|
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
}
|
|
return PendingIntent.getActivity(
|
|
context, mediaId, notifyIntent,
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT
|
|
} else {
|
|
PendingIntent.FLAG_ONE_SHOT
|
|
}
|
|
)
|
|
}
|
|
} |