diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Notification.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Notification.kt index e4338a3763..ac40420377 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Notification.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Notification.kt @@ -26,7 +26,8 @@ enum class NotificationType(val value: String) { //custom COMMENT_REPLY("COMMENT_REPLY"), COMMENT_WARNING("COMMENT_WARNING"), - DANTOTSU_UPDATE("DANTOTSU_UPDATE"); + DANTOTSU_UPDATE("DANTOTSU_UPDATE"), + SUBSCRIPTION("SUBSCRIPTION"); fun toFormattedString(): String { return this.value.replace("_", " ").lowercase(Locale.ROOT) diff --git a/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt b/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt index eb7837d31f..97cbcc0a3d 100644 --- a/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt +++ b/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt @@ -188,7 +188,7 @@ class CommentNotificationTask : Task { null ) ?: listOf() val newStore = notificationStore.toMutableList() - if (newStore.size > 10) { + if (newStore.size > 30) { newStore.remove(newStore.minByOrNull { it.time }) } if (newStore.any { it.content == notification.content }) { diff --git a/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt b/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt index 6024aa7134..e9381d4563 100644 --- a/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt +++ b/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt @@ -13,8 +13,6 @@ data class CommentStore( val time: Long = System.currentTimeMillis(), ) : java.io.Serializable { companion object { - - @Suppress("INAPPROPRIATE_CONST_NAME") private const val serialVersionUID = 2L } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionNotificationTask.kt b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionNotificationTask.kt index 83345013dc..7ea81ae883 100644 --- a/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionNotificationTask.kt +++ b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionNotificationTask.kt @@ -118,6 +118,15 @@ class SubscriptionNotificationTask : Task { if (ep != null) ep.number + " " + context.getString(R.string.just_released) to null else null } ?: return@map + addSubscriptionToStore( + SubscriptionStore( + media.name, + text.first, + media.id + ) + ) + PrefManager.setVal(PrefName.UnreadCommentNotifications, + PrefManager.getVal(PrefName.UnreadCommentNotifications) + 1) val notification = createNotification( context.applicationContext, media, @@ -219,4 +228,17 @@ class SubscriptionNotificationTask : Task { } ) } + + private fun addSubscriptionToStore(notification: SubscriptionStore) { + val notificationStore = PrefManager.getNullableVal>( + PrefName.SubscriptionNotificationStore, + null + ) ?: listOf() + val newStore = notificationStore.toMutableList() + if (newStore.size >= 100) { + newStore.remove(newStore.minByOrNull { it.time }) + } + newStore.add(notification) + PrefManager.setVal(PrefName.SubscriptionNotificationStore, newStore) + } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionStore.kt b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionStore.kt new file mode 100644 index 0000000000..dfb910f507 --- /dev/null +++ b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionStore.kt @@ -0,0 +1,16 @@ +package ani.dantotsu.notifications.subscription + +import kotlinx.serialization.Serializable + +@Serializable +data class SubscriptionStore( + val title: String, + val content: String, + val mediaId: Int, + val type: String = "SUBSCRIPTION", + val time: Long = System.currentTimeMillis(), +) : java.io.Serializable { + companion object { + private const val serialVersionUID = 1L + } +} \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt index 61840c32a6..749716ee3d 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt @@ -92,6 +92,10 @@ class ActivityItemBuilder { NotificationType.DANTOTSU_UPDATE -> { notification.context ?: "You should not see this" } + + NotificationType.SUBSCRIPTION -> { + notification.context ?: "You should not see this" + } } } diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt b/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt index ae27260ba5..30b0c52546 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt @@ -28,6 +28,7 @@ import ani.dantotsu.initActivity import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.navBarHeight import ani.dantotsu.notifications.comment.CommentStore +import ani.dantotsu.notifications.subscription.SubscriptionStore import ani.dantotsu.profile.ProfileActivity import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefName @@ -41,6 +42,8 @@ import kotlinx.coroutines.withContext class NotificationActivity : AppCompatActivity() { private lateinit var binding: ActivityFollowBinding + private lateinit var commentStore: List + private lateinit var subscriptionStore: List private var adapter: GroupieAdapter = GroupieAdapter() private var notificationList: List = emptyList() val filters = ArrayList() @@ -70,6 +73,15 @@ class NotificationActivity : AppCompatActivity() { onBackPressedDispatcher.onBackPressed() } binding.listProgressBar.visibility = ViewGroup.VISIBLE + commentStore = PrefManager.getNullableVal>( + PrefName.CommentNotificationStore, + null + ) ?: listOf() + subscriptionStore = PrefManager.getNullableVal>( + PrefName.SubscriptionNotificationStore, + null + ) ?: listOf() + binding.followFilterButton.setOnClickListener { val dialogView = LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null) val checkboxContainer = dialogView.findViewById(R.id.checkboxContainer) @@ -193,22 +205,39 @@ class NotificationActivity : AppCompatActivity() { notifications }.toMutableList() } - if (activityId == -1 && currentPage == 1) { - val commentStore = PrefManager.getNullableVal>( - PrefName.CommentNotificationStore, - null - ) ?: listOf() + if (activityId == -1) { + val furthestTime = newNotifications.minOfOrNull { it.createdAt } ?: 0 commentStore.forEach { - val notification = Notification( - it.type.toString(), - System.currentTimeMillis().toInt(), - commentId = it.commentId, - notificationType = it.type.toString(), - mediaId = it.mediaId, - context = it.title + "\n" + it.content, - createdAt = (it.time / 1000L).toInt(), - ) - newNotifications += notification + if ((it.time > furthestTime * 1000L || !hasNextPage) && notificationList.none { notification -> + notification.commentId == it.commentId && notification.createdAt == (it.time / 1000L).toInt() + }) { + val notification = Notification( + it.type.toString(), + System.currentTimeMillis().toInt(), + commentId = it.commentId, + notificationType = it.type.toString(), + mediaId = it.mediaId, + context = it.title + "\n" + it.content, + createdAt = (it.time / 1000L).toInt(), + ) + newNotifications += notification + } + } + subscriptionStore.forEach { + if ((it.time > furthestTime * 1000L || !hasNextPage) && notificationList.none { notification -> + notification.mediaId == it.mediaId && notification.createdAt == (it.time / 1000L).toInt() + }) { + val notification = Notification( + it.type, + System.currentTimeMillis().toInt(), + commentId = it.mediaId, + mediaId = it.mediaId, + notificationType = it.type, + context = it.content, + createdAt = (it.time / 1000L).toInt(), + ) + newNotifications += notification + } } newNotifications.sortByDescending { it.createdAt } } diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt index 139d320004..23224184c7 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt @@ -332,6 +332,20 @@ class NotificationItem( NotificationType.DANTOTSU_UPDATE -> { image(user = true) } + + NotificationType.SUBSCRIPTION -> { + image(user = true, commentNotification = true) + binding.notificationCoverUser.setOnClickListener { + clickCallback( + notification.mediaId ?: 0, null, NotificationClickType.MEDIA + ) + } + binding.notificationBannerImage.setOnClickListener { + clickCallback( + notification.mediaId ?: 0, null, NotificationClickType.MEDIA + ) + } + } } } diff --git a/app/src/main/java/ani/dantotsu/settings/saving/Preferences.kt b/app/src/main/java/ani/dantotsu/settings/saving/Preferences.kt index 0e275cf703..df6ed9292d 100644 --- a/app/src/main/java/ani/dantotsu/settings/saving/Preferences.kt +++ b/app/src/main/java/ani/dantotsu/settings/saving/Preferences.kt @@ -4,6 +4,7 @@ import android.graphics.Color import ani.dantotsu.connections.comments.AuthResponse import ani.dantotsu.connections.mal.MAL import ani.dantotsu.notifications.comment.CommentStore +import ani.dantotsu.notifications.subscription.SubscriptionStore import ani.dantotsu.settings.saving.internal.Location import ani.dantotsu.settings.saving.internal.Pref @@ -185,6 +186,7 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files LogToFile(Pref(Location.Irrelevant, Boolean::class, false)), RecentGlobalNotification(Pref(Location.Irrelevant, Int::class, 0)), CommentNotificationStore(Pref(Location.Irrelevant, List::class, listOf())), + SubscriptionNotificationStore(Pref(Location.Irrelevant, List::class, listOf())), UnreadCommentNotifications(Pref(Location.Irrelevant, Int::class, 0)), DownloadsDir(Pref(Location.Irrelevant, String::class, "")), RefreshStatus(Pref(Location.Irrelevant, Boolean::class, false)),