feat: notification filtering
This commit is contained in:
parent
be97229618
commit
e1a865c973
10 changed files with 151 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ class FollowActivity : AppCompatActivity() {
|
|||
setContentView(binding.root)
|
||||
val layoutType = PrefManager.getVal<Int>(PrefName.FollowerLayout)
|
||||
selected = getSelected(layoutType)
|
||||
binding.followFilterButton.visibility = View.GONE
|
||||
binding.followerGrid.alpha = 0.33f
|
||||
binding.followerList.alpha = 0.33f
|
||||
selected(selected)
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Notification> = emptyList()
|
||||
val filters = ArrayList<String>()
|
||||
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<LinearLayout>(R.id.checkboxContainer)
|
||||
val tickAllButton = dialogView.findViewById<ImageButton>(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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -50,6 +50,16 @@
|
|||
android:textSize="18sp"
|
||||
tools:text="Follow" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/followFilterButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:contentDescription="@string/menu"
|
||||
android:src="@drawable/ic_round_filter_alt_24"
|
||||
app:tint="?attr/colorOnBackground" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue