feat: global notification

This commit is contained in:
rebelonion 2024-03-14 14:16:25 -05:00
parent b654824eb7
commit 6122eb3669
5 changed files with 93 additions and 33 deletions

View file

@ -167,7 +167,7 @@ class App : MultiDexApplication() {
//run once //run once
androidx.work.WorkManager.getInstance(this).enqueue(OneTimeWorkRequest.Companion.from(AnilistNotificationWorker::class.java)) androidx.work.WorkManager.getInstance(this).enqueue(OneTimeWorkRequest.Companion.from(AnilistNotificationWorker::class.java))
} }
androidx.work.WorkManager.getInstance(this).cancelUniqueWork("ani.dantotsu.notifications.NotificationWorker") androidx.work.WorkManager.getInstance(this).cancelUniqueWork("ani.dantotsu.notifications.NotificationWorker") //legacy worker
} }

View file

@ -412,7 +412,9 @@ data class Notification(
@SerialName("type") @SerialName("type")
val type: Int? = null, val type: Int? = null,
@SerialName("content") @SerialName("content")
val content: String? = null val content: String? = null,
@SerialName("notification_id")
val notificationId: Int
) )

View file

@ -19,6 +19,7 @@ import ani.dantotsu.MainActivity
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.connections.comments.CommentsAPI
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -34,45 +35,75 @@ class CommentNotificationWorker(appContext: Context, workerParams: WorkerParamet
PrefManager.init(applicationContext) //make sure prefs are initialized PrefManager.init(applicationContext) //make sure prefs are initialized
val client = OkHttpClient() val client = OkHttpClient()
CommentsAPI.fetchAuthToken(client) CommentsAPI.fetchAuthToken(client)
val notifications = CommentsAPI.getNotifications(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 //if we have at least one reply notification, we need to fetch the media titles
var names = emptyMap<Int, MediaNameFetch.Companion.ReturnedData>() var names = emptyMap<Int, MediaNameFetch.Companion.ReturnedData>()
if (notifications?.notifications?.any { it.type == 1 || it.type == null } == true) { if (notifications?.any { it.type == 1 || it.type == null } == true) {
val mediaIds = notifications.notifications.filter { it.type == 1 || it.type == null }.map { it.mediaId } val mediaIds = notifications.filter { it.type == 1 || it.type == null }.map { it.mediaId }
names = MediaNameFetch.fetchMediaTitles(mediaIds) names = MediaNameFetch.fetchMediaTitles(mediaIds)
} }
notifications?.notifications?.forEach { val recentGlobal = PrefManager.getVal<Int>(
PrefName.RecentGlobalNotification)
notifications = notifications?.filter { it.type != 3 || it.notificationId > recentGlobal }?.toMutableList()
val newRecentGlobal = notifications?.filter { it.type == 3 }?.maxOfOrNull { it.notificationId }
if (newRecentGlobal != null) {
PrefManager.setVal(PrefName.RecentGlobalNotification, newRecentGlobal)
}
notifications?.forEach {
val type: NotificationType = when (it.type) { val type: NotificationType = when (it.type) {
1 -> NotificationType.COMMENT_REPLY 1 -> NotificationType.COMMENT_REPLY
2 -> NotificationType.COMMENT_WARNING 2 -> NotificationType.COMMENT_WARNING
3 -> NotificationType.APP_GLOBAL
else -> NotificationType.COMMENT_REPLY else -> NotificationType.COMMENT_REPLY
} }
val notification = if (it.type == 2) { val notification = when (type) {
val title = "You received a warning" NotificationType.COMMENT_WARNING -> {
val message = it.content ?: "Be more thoughtful with your comments" val title = "You received a warning"
createNotification( val message = it.content ?: "Be more thoughtful with your comments"
NotificationType.COMMENT_WARNING, createNotification(
message, NotificationType.COMMENT_WARNING,
title, message,
it.mediaId, title,
it.commentId, it.mediaId,
"", it.commentId,
"" "",
) ""
} else { )
val title = "New CommentNotificationWorker Reply" }
val mediaName = names[it.mediaId]?.title ?: "Unknown"
val message = "${it.username} replied to your comment in $mediaName" NotificationType.COMMENT_REPLY -> {
createNotification( val title = "New CommentNotificationWorker Reply"
NotificationType.COMMENT_REPLY, val mediaName = names[it.mediaId]?.title ?: "Unknown"
message, val message = "${it.username} replied to your comment in $mediaName"
title, createNotification(
it.mediaId, NotificationType.COMMENT_REPLY,
it.commentId, message,
names[it.mediaId]?.color ?: "#222222", title,
names[it.mediaId]?.coverImage ?: "" it.mediaId,
) it.commentId,
names[it.mediaId]?.color ?: "#222222",
names[it.mediaId]?.coverImage ?: ""
)
}
NotificationType.APP_GLOBAL -> {
val title = "Update from Dantotsu"
val message = it.content ?: "New feature available"
createNotification(
NotificationType.APP_GLOBAL,
message,
title,
0,
0,
"",
""
)
}
} }
if (ActivityCompat.checkSelfPermission( if (ActivityCompat.checkSelfPermission(
@ -141,7 +172,7 @@ class CommentNotificationWorker(appContext: Context, workerParams: WorkerParamet
.setContentTitle(title) .setContentTitle(title)
.setContentText(message) .setContentText(message)
.setSmallIcon(R.drawable.notification_icon) .setSmallIcon(R.drawable.notification_icon)
.setPriority(NotificationCompat.PRIORITY_HIGH) .setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.setAutoCancel(true) .setAutoCancel(true)
if (imageUrl.isNotEmpty()) { if (imageUrl.isNotEmpty()) {
@ -155,6 +186,25 @@ class CommentNotificationWorker(appContext: Context, workerParams: WorkerParamet
} }
builder.build() builder.build()
} }
NotificationType.APP_GLOBAL -> {
val intent = Intent(applicationContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent = PendingIntent.getActivity(
applicationContext,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val builder = NotificationCompat.Builder(applicationContext, notificationType.id)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.notification_icon)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
builder.build()
}
} }
return notification return notification
} }
@ -182,7 +232,8 @@ class CommentNotificationWorker(appContext: Context, workerParams: WorkerParamet
enum class NotificationType(val id: String) { enum class NotificationType(val id: String) {
COMMENT_REPLY(Notifications.CHANNEL_COMMENTS), COMMENT_REPLY(Notifications.CHANNEL_COMMENTS),
COMMENT_WARNING(Notifications.CHANNEL_COMMENT_WARING) COMMENT_WARNING(Notifications.CHANNEL_COMMENT_WARING),
APP_GLOBAL(Notifications.CHANNEL_APP_GLOBAL)
} }
companion object { companion object {

View file

@ -168,6 +168,7 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
CommentAuthResponse(Pref(Location.Irrelevant, AuthResponse::class, "")), CommentAuthResponse(Pref(Location.Irrelevant, AuthResponse::class, "")),
CommentTokenExpiry(Pref(Location.Irrelevant, Long::class, 0L)), CommentTokenExpiry(Pref(Location.Irrelevant, Long::class, 0L)),
LogToFile(Pref(Location.Irrelevant, Boolean::class, false)), LogToFile(Pref(Location.Irrelevant, Boolean::class, false)),
RecentGlobalNotification(Pref(Location.Irrelevant, Int::class, 0)),
//Protected //Protected
DiscordToken(Pref(Location.Protected, String::class, "")), DiscordToken(Pref(Location.Protected, String::class, "")),

View file

@ -53,6 +53,9 @@ object Notifications {
const val CHANNEL_COMMENT_WARING = "comment_warning_channel" const val CHANNEL_COMMENT_WARING = "comment_warning_channel"
const val ID_COMMENT_REPLY = -801 const val ID_COMMENT_REPLY = -801
const val CHANNEL_APP_GLOBAL = "app_global"
/** /**
* Notification channel and ids used for anilist updates. * Notification channel and ids used for anilist updates.
*/ */
@ -151,6 +154,9 @@ object Notifications {
setName("Anilist") setName("Anilist")
setGroup(GROUP_ANILIST) setGroup(GROUP_ANILIST)
}, },
buildNotificationChannel(CHANNEL_APP_GLOBAL, IMPORTANCE_HIGH) {
setName("Global Updates")
},
buildNotificationChannel(CHANNEL_APP_UPDATE, IMPORTANCE_DEFAULT) { buildNotificationChannel(CHANNEL_APP_UPDATE, IMPORTANCE_DEFAULT) {
setGroup(GROUP_APK_UPDATES) setGroup(GROUP_APK_UPDATES)
setName("App Updates") setName("App Updates")