
* feat: custom downloader (novel broken) * fix: send headers to ffmpeg ffmpeg can be a real bitch to work with * fix: offline page for new download system * feat: novel to new system | load freezing * chore: clean manifest * fix: notification incrementing * feat: changing the downloads dir
318 lines
No EOL
14 KiB
Kotlin
318 lines
No EOL
14 KiB
Kotlin
package ani.dantotsu.notifications.comment
|
|
|
|
import android.Manifest
|
|
import android.app.PendingIntent
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.content.pm.PackageManager
|
|
import android.graphics.Bitmap
|
|
import android.graphics.BitmapFactory
|
|
import android.graphics.Canvas
|
|
import android.graphics.Color
|
|
import androidx.core.app.ActivityCompat
|
|
import androidx.core.app.NotificationCompat
|
|
import androidx.core.app.NotificationManagerCompat
|
|
import androidx.core.content.ContextCompat
|
|
import ani.dantotsu.MainActivity
|
|
import ani.dantotsu.R
|
|
import ani.dantotsu.connections.comments.CommentsAPI
|
|
import ani.dantotsu.notifications.Task
|
|
import ani.dantotsu.settings.saving.PrefManager
|
|
import ani.dantotsu.settings.saving.PrefName
|
|
import ani.dantotsu.util.Logger
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import okhttp3.OkHttpClient
|
|
|
|
class CommentNotificationTask : Task {
|
|
override suspend fun execute(context: Context): Boolean {
|
|
try {
|
|
withContext(Dispatchers.IO) {
|
|
PrefManager.init(context) //make sure prefs are initialized
|
|
val client = OkHttpClient()
|
|
CommentsAPI.fetchAuthToken(client)
|
|
val notificationResponse = CommentsAPI.getNotifications(client)
|
|
var notifications = notificationResponse?.notifications?.toMutableList()
|
|
//if we have at least one reply notification, we need to fetch the media titles
|
|
var names = emptyMap<Int, MediaNameFetch.Companion.ReturnedData>()
|
|
if (notifications?.any { it.type == 1 || it.type == null } == true) {
|
|
val mediaIds =
|
|
notifications.filter { it.type == 1 || it.type == null }.map { it.mediaId }
|
|
names = MediaNameFetch.fetchMediaTitles(mediaIds)
|
|
}
|
|
|
|
val recentGlobal = PrefManager.getVal<Int>(
|
|
PrefName.RecentGlobalNotification
|
|
)
|
|
|
|
notifications =
|
|
notifications?.filter { !it.type.isGlobal() || it.notificationId > recentGlobal }
|
|
?.toMutableList()
|
|
|
|
val newRecentGlobal =
|
|
notifications?.filter { it.type.isGlobal() }?.maxOfOrNull { it.notificationId }
|
|
if (newRecentGlobal != null) {
|
|
PrefManager.setVal(PrefName.RecentGlobalNotification, newRecentGlobal)
|
|
}
|
|
if (notifications.isNullOrEmpty()) return@withContext
|
|
PrefManager.setVal(
|
|
PrefName.UnreadCommentNotifications,
|
|
PrefManager.getVal<Int>(PrefName.UnreadCommentNotifications) + (notifications.size)
|
|
)
|
|
|
|
notifications.forEach {
|
|
val type: CommentNotificationWorker.NotificationType = when (it.type) {
|
|
1 -> CommentNotificationWorker.NotificationType.COMMENT_REPLY
|
|
2 -> CommentNotificationWorker.NotificationType.COMMENT_WARNING
|
|
3 -> CommentNotificationWorker.NotificationType.APP_GLOBAL
|
|
420 -> CommentNotificationWorker.NotificationType.NO_NOTIFICATION
|
|
else -> CommentNotificationWorker.NotificationType.UNKNOWN
|
|
}
|
|
val notification = when (type) {
|
|
CommentNotificationWorker.NotificationType.COMMENT_WARNING -> {
|
|
val title = "You received a warning"
|
|
val message = it.content ?: "Be more thoughtful with your comments"
|
|
|
|
val commentStore = CommentStore(
|
|
title,
|
|
message,
|
|
it.mediaId,
|
|
it.commentId
|
|
)
|
|
addNotificationToStore(commentStore)
|
|
|
|
createNotification(
|
|
context,
|
|
CommentNotificationWorker.NotificationType.COMMENT_WARNING,
|
|
message,
|
|
title,
|
|
it.mediaId,
|
|
it.commentId,
|
|
"",
|
|
""
|
|
)
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.COMMENT_REPLY -> {
|
|
val title = "New Comment Reply"
|
|
val mediaName = names[it.mediaId]?.title ?: "Unknown"
|
|
val message = "${it.username} replied to your comment in $mediaName"
|
|
|
|
val commentStore = CommentStore(
|
|
title,
|
|
message,
|
|
it.mediaId,
|
|
it.commentId
|
|
)
|
|
addNotificationToStore(commentStore)
|
|
|
|
createNotification(
|
|
context,
|
|
CommentNotificationWorker.NotificationType.COMMENT_REPLY,
|
|
message,
|
|
title,
|
|
it.mediaId,
|
|
it.commentId,
|
|
names[it.mediaId]?.color ?: "#222222",
|
|
names[it.mediaId]?.coverImage ?: ""
|
|
)
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.APP_GLOBAL -> {
|
|
val title = "Update from Dantotsu"
|
|
val message = it.content ?: "New feature available"
|
|
|
|
val commentStore = CommentStore(
|
|
title,
|
|
message,
|
|
null,
|
|
null
|
|
)
|
|
addNotificationToStore(commentStore)
|
|
|
|
createNotification(
|
|
context,
|
|
CommentNotificationWorker.NotificationType.APP_GLOBAL,
|
|
message,
|
|
title,
|
|
0,
|
|
0,
|
|
"",
|
|
""
|
|
)
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.NO_NOTIFICATION -> {
|
|
PrefManager.removeCustomVal("genre_thumb")
|
|
PrefManager.removeCustomVal("banner_ANIME_time")
|
|
PrefManager.removeCustomVal("banner_MANGA_time")
|
|
PrefManager.setVal(PrefName.ImageUrl, it.content ?: "")
|
|
null
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.UNKNOWN -> {
|
|
null
|
|
}
|
|
}
|
|
|
|
if (ActivityCompat.checkSelfPermission(
|
|
context,
|
|
Manifest.permission.POST_NOTIFICATIONS
|
|
) == PackageManager.PERMISSION_GRANTED
|
|
) {
|
|
if (notification != null) {
|
|
NotificationManagerCompat.from(context)
|
|
.notify(
|
|
type.id,
|
|
System.currentTimeMillis().toInt(),
|
|
notification
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.log("CommentNotificationTask: ${e.message}")
|
|
Logger.log(e)
|
|
return false
|
|
}
|
|
}
|
|
|
|
private fun addNotificationToStore(notification: CommentStore) {
|
|
val notificationStore = PrefManager.getNullableVal<List<CommentStore>>(
|
|
PrefName.CommentNotificationStore,
|
|
null
|
|
) ?: listOf()
|
|
val newStore = notificationStore.toMutableList()
|
|
if (newStore.size > 10) {
|
|
newStore.remove(newStore.minByOrNull { it.time })
|
|
}
|
|
if (newStore.any { it.content == notification.content }) {
|
|
return
|
|
}
|
|
newStore.add(notification)
|
|
PrefManager.setVal(PrefName.CommentNotificationStore, newStore)
|
|
}
|
|
|
|
private fun createNotification(
|
|
context: Context,
|
|
notificationType: CommentNotificationWorker.NotificationType,
|
|
message: String,
|
|
title: String,
|
|
mediaId: Int,
|
|
commentId: Int,
|
|
color: String,
|
|
imageUrl: String
|
|
): android.app.Notification? {
|
|
Logger.log(
|
|
"Creating notification of type $notificationType" +
|
|
", message: $message, title: $title, mediaId: $mediaId, commentId: $commentId"
|
|
)
|
|
val notification = when (notificationType) {
|
|
CommentNotificationWorker.NotificationType.COMMENT_WARNING -> {
|
|
val intent = Intent(context, MainActivity::class.java).apply {
|
|
putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
|
|
putExtra("mediaId", mediaId)
|
|
putExtra("commentId", commentId)
|
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
}
|
|
val pendingIntent = PendingIntent.getActivity(
|
|
context,
|
|
commentId,
|
|
intent,
|
|
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
|
)
|
|
val builder = NotificationCompat.Builder(context, notificationType.id)
|
|
.setContentTitle(title)
|
|
.setContentText(message)
|
|
.setSmallIcon(R.drawable.notification_icon)
|
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
.setContentIntent(pendingIntent)
|
|
.setAutoCancel(true)
|
|
builder.build()
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.COMMENT_REPLY -> {
|
|
val intent = Intent(context, MainActivity::class.java).apply {
|
|
putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
|
|
putExtra("mediaId", mediaId)
|
|
putExtra("commentId", commentId)
|
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
}
|
|
val pendingIntent = PendingIntent.getActivity(
|
|
context,
|
|
commentId,
|
|
intent,
|
|
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
|
)
|
|
val builder = NotificationCompat.Builder(context, notificationType.id)
|
|
.setContentTitle(title)
|
|
.setContentText(message)
|
|
.setSmallIcon(R.drawable.notification_icon)
|
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
|
.setContentIntent(pendingIntent)
|
|
.setAutoCancel(true)
|
|
if (imageUrl.isNotEmpty()) {
|
|
val bitmap = getBitmapFromUrl(imageUrl)
|
|
if (bitmap != null) {
|
|
builder.setLargeIcon(bitmap)
|
|
}
|
|
}
|
|
if (color.isNotEmpty()) {
|
|
builder.color = Color.parseColor(color)
|
|
}
|
|
builder.build()
|
|
}
|
|
|
|
CommentNotificationWorker.NotificationType.APP_GLOBAL -> {
|
|
val intent = Intent(context, MainActivity::class.java).apply {
|
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
}
|
|
val pendingIntent = PendingIntent.getActivity(
|
|
context,
|
|
System.currentTimeMillis().toInt(),
|
|
intent,
|
|
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
|
)
|
|
val builder = NotificationCompat.Builder(context, notificationType.id)
|
|
.setContentTitle(title)
|
|
.setContentText(message)
|
|
.setSmallIcon(R.drawable.notification_icon)
|
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
.setContentIntent(pendingIntent)
|
|
.setAutoCancel(true)
|
|
builder.build()
|
|
}
|
|
|
|
else -> {
|
|
null
|
|
}
|
|
}
|
|
return notification
|
|
}
|
|
|
|
@Suppress("unused")
|
|
private fun getBitmapFromVectorDrawable(context: Context, drawableId: Int): Bitmap? {
|
|
val drawable = ContextCompat.getDrawable(context, drawableId) ?: return null
|
|
val bitmap = Bitmap.createBitmap(
|
|
drawable.intrinsicWidth,
|
|
drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
|
|
)
|
|
val canvas = Canvas(bitmap)
|
|
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
|
drawable.draw(canvas)
|
|
return bitmap
|
|
}
|
|
|
|
private fun getBitmapFromUrl(url: String): Bitmap? {
|
|
return try {
|
|
val inputStream = java.net.URL(url).openStream()
|
|
BitmapFactory.decodeStream(inputStream)
|
|
} catch (e: Exception) {
|
|
null
|
|
}
|
|
}
|
|
|
|
private fun Int?.isGlobal() = this == 3 || this == 420
|
|
} |