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 a5c59ce1f35..e4338a37637 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 @@ -2,6 +2,7 @@ package ani.dantotsu.connections.anilist.api import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import java.util.Locale enum class NotificationType(val value: String) { ACTIVITY_MESSAGE("ACTIVITY_MESSAGE"), @@ -24,6 +25,19 @@ enum class NotificationType(val value: String) { //custom COMMENT_REPLY("COMMENT_REPLY"), + COMMENT_WARNING("COMMENT_WARNING"), + DANTOTSU_UPDATE("DANTOTSU_UPDATE"); + + fun toFormattedString(): String { + return this.value.replace("_", " ").lowercase(Locale.ROOT) + .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() } + } + + companion object { + fun String.fromFormattedString(): String { + return this.replace(" ", "_").uppercase(Locale.ROOT) + } + } } @Serializable 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 1856ac7140a..eb7837d31f7 100644 --- a/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt +++ b/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationTask.kt @@ -64,7 +64,7 @@ class CommentNotificationTask : Task { val type: CommentNotificationWorker.NotificationType = when (it.type) { 1 -> CommentNotificationWorker.NotificationType.COMMENT_REPLY 2 -> CommentNotificationWorker.NotificationType.COMMENT_WARNING - 3 -> CommentNotificationWorker.NotificationType.APP_GLOBAL + 3 -> CommentNotificationWorker.NotificationType.DANTOTSU_UPDATE 420 -> CommentNotificationWorker.NotificationType.NO_NOTIFICATION else -> CommentNotificationWorker.NotificationType.UNKNOWN } @@ -76,6 +76,7 @@ class CommentNotificationTask : Task { val commentStore = CommentStore( title, message, + CommentNotificationWorker.NotificationType.COMMENT_WARNING, it.mediaId, it.commentId ) @@ -101,6 +102,7 @@ class CommentNotificationTask : Task { val commentStore = CommentStore( title, message, + CommentNotificationWorker.NotificationType.COMMENT_REPLY, it.mediaId, it.commentId ) @@ -118,13 +120,14 @@ class CommentNotificationTask : Task { ) } - CommentNotificationWorker.NotificationType.APP_GLOBAL -> { + CommentNotificationWorker.NotificationType.DANTOTSU_UPDATE -> { val title = "Update from Dantotsu" val message = it.content ?: "New feature available" val commentStore = CommentStore( title, message, + CommentNotificationWorker.NotificationType.DANTOTSU_UPDATE, null, null ) @@ -132,7 +135,7 @@ class CommentNotificationTask : Task { createNotification( context, - CommentNotificationWorker.NotificationType.APP_GLOBAL, + CommentNotificationWorker.NotificationType.DANTOTSU_UPDATE, message, title, 0, @@ -265,7 +268,7 @@ class CommentNotificationTask : Task { builder.build() } - CommentNotificationWorker.NotificationType.APP_GLOBAL -> { + CommentNotificationWorker.NotificationType.DANTOTSU_UPDATE -> { val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } diff --git a/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationWorker.kt b/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationWorker.kt index 08ef4ad94c3..496d0f0e6c6 100644 --- a/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationWorker.kt +++ b/app/src/main/java/ani/dantotsu/notifications/comment/CommentNotificationWorker.kt @@ -27,7 +27,7 @@ class CommentNotificationWorker(appContext: Context, workerParams: WorkerParamet enum class NotificationType(val id: String) { COMMENT_REPLY(Notifications.CHANNEL_COMMENTS), COMMENT_WARNING(Notifications.CHANNEL_COMMENT_WARING), - APP_GLOBAL(Notifications.CHANNEL_APP_GLOBAL), + DANTOTSU_UPDATE(Notifications.CHANNEL_APP_GLOBAL), NO_NOTIFICATION("no_notification"), UNKNOWN("unknown") } 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 bc6ab98bc95..6024aa71347 100644 --- a/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt +++ b/app/src/main/java/ani/dantotsu/notifications/comment/CommentStore.kt @@ -3,11 +3,11 @@ package ani.dantotsu.notifications.comment import kotlinx.serialization.Serializable -@Suppress("INAPPROPRIATE_CONST_NAME") @Serializable data class CommentStore( val title: String, val content: String, + val type: CommentNotificationWorker.NotificationType, val mediaId: Int? = null, val commentId: Int? = null, val time: Long = System.currentTimeMillis(), @@ -15,6 +15,6 @@ data class CommentStore( companion object { @Suppress("INAPPROPRIATE_CONST_NAME") - private const val serialVersionUID = 1L + private const val serialVersionUID = 2L } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/FollowActivity.kt b/app/src/main/java/ani/dantotsu/profile/FollowActivity.kt index 56ec2eb3a27..c5c606d1e87 100644 --- a/app/src/main/java/ani/dantotsu/profile/FollowActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/FollowActivity.kt @@ -43,6 +43,7 @@ class FollowActivity : AppCompatActivity() { setContentView(binding.root) val layoutType = PrefManager.getVal(PrefName.FollowerLayout) selected = getSelected(layoutType) + binding.followFilterButton.visibility = View.GONE binding.followerGrid.alpha = 0.33f binding.followerList.alpha = 0.33f selected(selected) 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 3e2289a2463..61840c32a69 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt @@ -84,6 +84,14 @@ class ActivityItemBuilder { NotificationType.COMMENT_REPLY -> { notification.context ?: "You should not see this" } + + NotificationType.COMMENT_WARNING -> { + notification.context ?: "You should not see this" + } + + NotificationType.DANTOTSU_UPDATE -> { + 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 a07ee3b370f..3707be57551 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt @@ -3,8 +3,13 @@ package ani.dantotsu.profile.activity import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import android.view.MotionEvent import android.view.ViewGroup +import android.widget.CheckBox +import android.widget.ImageButton +import android.widget.LinearLayout +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -14,6 +19,9 @@ import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.api.Notification +import ani.dantotsu.connections.anilist.api.NotificationType +import ani.dantotsu.connections.anilist.api.NotificationType.Companion.fromFormattedString +import ani.dantotsu.currContext import ani.dantotsu.databinding.ActivityFollowBinding import ani.dantotsu.initActivity import ani.dantotsu.media.MediaDetailsActivity @@ -34,6 +42,7 @@ class NotificationActivity : AppCompatActivity() { private lateinit var binding: ActivityFollowBinding private var adapter: GroupieAdapter = GroupieAdapter() private var notificationList: List = emptyList() + val filters = ArrayList() private var currentPage: Int = 1 private var hasNextPage: Boolean = true @@ -60,6 +69,75 @@ class NotificationActivity : AppCompatActivity() { onBackPressedDispatcher.onBackPressed() } binding.listProgressBar.visibility = ViewGroup.VISIBLE + binding.followFilterButton.setOnClickListener { + val dialogView = LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null) + val checkboxContainer = dialogView.findViewById(R.id.checkboxContainer) + val tickAllButton = dialogView.findViewById(R.id.toggleButton) + fun getToggleImageResource(container: ViewGroup): Int { + var allChecked = true + var allUnchecked = true + + for (i in 0 until container.childCount) { + val checkBox = container.getChildAt(i) as CheckBox + if (!checkBox.isChecked) { + allChecked = false + } else { + allUnchecked = false + } + } + return when { + allChecked -> R.drawable.untick_all_boxes + allUnchecked -> R.drawable.tick_all_boxes + else -> R.drawable.invert_all_boxes + } + } + NotificationType.entries.forEach { notificationType -> + val checkBox = CheckBox(currContext()) + checkBox.text = notificationType.toFormattedString() + checkBox.isChecked = !filters.contains(notificationType.value.fromFormattedString()) + checkBox.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + filters.remove(notificationType.value.fromFormattedString()) + } else { + filters.add(notificationType.value.fromFormattedString()) + } + tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) + } + checkboxContainer.addView(checkBox) + } + tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) + tickAllButton.setOnClickListener { + for (i in 0 until checkboxContainer.childCount) { + val checkBox = checkboxContainer.getChildAt(i) as CheckBox + checkBox.isChecked = !checkBox.isChecked + } + + tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) + } + val alertD = AlertDialog.Builder(this, R.style.MyPopup) + alertD.setTitle("Filter") + alertD.setView(dialogView) + alertD.setPositiveButton("OK") { _, _ -> + currentPage = 1 + hasNextPage = true + adapter.clear() + adapter.addAll(notificationList.filter { notification -> + !filters.contains(notification.notificationType) + }.map { + NotificationItem( + it, + ::onNotificationClick + ) + }) + loadPage(-1) { + binding.followRefresh.visibility = ViewGroup.GONE + } + } + alertD.setNegativeButton("Cancel") { _, _ -> } + val dialog = alertD.show() + dialog.window?.setDimAmount(0.8f) + } + val activityId = intent.getIntExtra("activityId", -1) lifecycleScope.launch { loadPage(activityId) { @@ -119,10 +197,10 @@ class NotificationActivity : AppCompatActivity() { ) ?: listOf() commentStore.forEach { val notification = Notification( - "COMMENT_REPLY", + it.type.toString(), System.currentTimeMillis().toInt(), commentId = it.commentId, - notificationType = "COMMENT_REPLY", + notificationType = it.type.toString(), mediaId = it.mediaId, context = it.title + "\n" + it.content, createdAt = (it.time / 1000L).toInt(), @@ -133,7 +211,9 @@ class NotificationActivity : AppCompatActivity() { } notificationList += newNotifications - adapter.addAll(newNotifications.map { + adapter.addAll(newNotifications.filter { notification -> + !filters.contains(notification.notificationType) + }.map { NotificationItem( it, ::onNotificationClick 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 59edae2fe6e..139d3200049 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt @@ -315,6 +315,23 @@ class NotificationItem( } } } + + NotificationType.COMMENT_WARNING -> { + image(user = true, commentNotification = true) + if (notification.commentId != null && notification.mediaId != null) { + binding.notificationBannerImage.setOnClickListener { + clickCallback( + notification.mediaId, + notification.commentId, + NotificationClickType.COMMENT + ) + } + } + } + + NotificationType.DANTOTSU_UPDATE -> { + image(user = true) + } } } diff --git a/app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt b/app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt index 3a13cb88fc4..9b3f92936d7 100644 --- a/app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt +++ b/app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt @@ -397,6 +397,14 @@ object PrefManager { } else { default } + } catch (e: java.io.InvalidClassException) { + try { + getPrefLocation(location).edit().remove(key).apply() + default + } catch (e: Exception) { + Logger.log(e) + default + } } catch (e: Exception) { Logger.log(e) default diff --git a/app/src/main/res/layout/activity_follow.xml b/app/src/main/res/layout/activity_follow.xml index 3ff66743b8e..9ec387c4432 100644 --- a/app/src/main/res/layout/activity_follow.xml +++ b/app/src/main/res/layout/activity_follow.xml @@ -50,6 +50,16 @@ android:textSize="18sp" tools:text="Follow" /> + +