feat: notifications page rework
This commit is contained in:
parent
37949c7e8e
commit
2b4c9bf7a9
11 changed files with 487 additions and 324 deletions
|
@ -1,309 +0,0 @@
|
|||
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 android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
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
|
||||
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
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class NotificationActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
private lateinit var commentStore: List<CommentStore>
|
||||
private lateinit var subscriptionStore: List<SubscriptionStore>
|
||||
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
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
binding.listTitle.text = getString(R.string.notifications)
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
}
|
||||
binding.listFrameLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = navBarHeight
|
||||
}
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager =
|
||||
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
binding.followerGrid.visibility = ViewGroup.GONE
|
||||
binding.followerList.visibility = ViewGroup.GONE
|
||||
binding.listBack.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
binding.listProgressBar.visibility = ViewGroup.VISIBLE
|
||||
commentStore = PrefManager.getNullableVal<List<CommentStore>>(
|
||||
PrefName.CommentNotificationStore,
|
||||
null
|
||||
) ?: listOf()
|
||||
subscriptionStore = PrefManager.getNullableVal<List<SubscriptionStore>>(
|
||||
PrefName.SubscriptionNotificationStore,
|
||||
null
|
||||
) ?: listOf()
|
||||
|
||||
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)
|
||||
val title = dialogView.findViewById<TextView>(R.id.scantitle)
|
||||
title.visibility = ViewGroup.GONE
|
||||
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) {
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
binding.listRecyclerView.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_UP) {
|
||||
if (hasNextPage && !binding.listRecyclerView.canScrollVertically(1) && !binding.followRefresh.isVisible
|
||||
&& binding.listRecyclerView.adapter!!.itemCount != 0 &&
|
||||
(binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1)
|
||||
) {
|
||||
binding.followRefresh.visibility = ViewGroup.VISIBLE
|
||||
loadPage(-1) {
|
||||
binding.followRefresh.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
binding.followSwipeRefresh.setOnRefreshListener {
|
||||
currentPage = 1
|
||||
hasNextPage = true
|
||||
adapter.clear()
|
||||
notificationList = emptyList()
|
||||
loadPage(-1) {
|
||||
binding.followSwipeRefresh.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadPage(activityId: Int, onFinish: () -> Unit = {}) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val resetNotification = activityId == -1
|
||||
val res = Anilist.query.getNotifications(
|
||||
Anilist.userid ?: PrefManager.getVal<String>(PrefName.AnilistUserId).toIntOrNull()
|
||||
?: 0, currentPage, resetNotification = resetNotification
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
val newNotifications: MutableList<Notification> = mutableListOf()
|
||||
res?.data?.page?.notifications?.let { notifications ->
|
||||
Logger.log("Notifications: $notifications")
|
||||
newNotifications += if (activityId != -1) {
|
||||
notifications.filter { it.id == activityId }
|
||||
} else {
|
||||
notifications
|
||||
}.toMutableList()
|
||||
}
|
||||
if (activityId == -1) {
|
||||
val furthestTime = newNotifications.minOfOrNull { it.createdAt } ?: 0
|
||||
commentStore.forEach {
|
||||
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.title + ": " + it.content,
|
||||
createdAt = (it.time / 1000L).toInt(),
|
||||
image = it.image,
|
||||
banner = it.banner ?: it.image
|
||||
)
|
||||
newNotifications += notification
|
||||
}
|
||||
}
|
||||
newNotifications.sortByDescending { it.createdAt }
|
||||
}
|
||||
|
||||
notificationList += newNotifications
|
||||
adapter.addAll(newNotifications.filter { notification ->
|
||||
!filters.contains(notification.notificationType)
|
||||
}.map {
|
||||
NotificationItem(
|
||||
it,
|
||||
::onNotificationClick
|
||||
)
|
||||
})
|
||||
currentPage = res?.data?.page?.pageInfo?.currentPage?.plus(1) ?: 1
|
||||
hasNextPage = res?.data?.page?.pageInfo?.hasNextPage ?: false
|
||||
binding.followSwipeRefresh.isRefreshing = false
|
||||
onFinish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNotificationClick(id: Int, optional: Int?, type: NotificationClickType) {
|
||||
when (type) {
|
||||
NotificationClickType.USER -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, ProfileActivity::class.java)
|
||||
.putExtra("userId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.MEDIA -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, MediaDetailsActivity::class.java)
|
||||
.putExtra("mediaId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.ACTIVITY -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, FeedActivity::class.java)
|
||||
.putExtra("activityId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.COMMENT -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, MediaDetailsActivity::class.java)
|
||||
.putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
|
||||
.putExtra("mediaId", id)
|
||||
.putExtra("commentId", optional ?: -1),
|
||||
null
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
NotificationClickType.UNDEFINED -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
enum class NotificationClickType {
|
||||
USER, MEDIA, ACTIVITY, COMMENT, UNDEFINED
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package ani.dantotsu.profile.notification
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ActivityNotificationBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
|
||||
class NotificationActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityNotificationBinding
|
||||
private var selected: Int = 0
|
||||
lateinit var navBar: AnimatedBottomBar
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityNotificationBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
binding.notificationTitle.text = getString(R.string.notifications)
|
||||
binding.notificationToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
}
|
||||
navBar = binding.notificationNavBar
|
||||
binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = navBarHeight
|
||||
}
|
||||
val mediaTab = navBar.createTab(R.drawable.ic_round_movie_filter_24, "Media")
|
||||
val userTab = navBar.createTab(R.drawable.ic_round_person_24, "User")
|
||||
val subscriptionTab = navBar.createTab(R.drawable.ic_round_notifications_active_24, "Subscriptions")
|
||||
val commentTab = navBar.createTab(R.drawable.ic_round_comment_24, "Comments")
|
||||
navBar.addTab(mediaTab)
|
||||
navBar.addTab(userTab)
|
||||
navBar.addTab(subscriptionTab)
|
||||
navBar.addTab(commentTab)
|
||||
binding.notificationBack.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
val getOne = intent.getIntExtra("activityId", -1)
|
||||
binding.notificationViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, getOne)
|
||||
binding.notificationViewPager.setOffscreenPageLimit(4)
|
||||
binding.notificationViewPager.setCurrentItem(selected, false)
|
||||
binding.notificationViewPager
|
||||
navBar.selectTabAt(selected)
|
||||
navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||
override fun onTabSelected(
|
||||
lastIndex: Int,
|
||||
lastTab: AnimatedBottomBar.Tab?,
|
||||
newIndex: Int,
|
||||
newTab: AnimatedBottomBar.Tab
|
||||
) {
|
||||
selected = newIndex
|
||||
binding.notificationViewPager.setCurrentItem(selected, true)
|
||||
}
|
||||
})
|
||||
binding.notificationViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
navBar.selectTabAt(position)
|
||||
}
|
||||
})
|
||||
}
|
||||
override fun onResume() {
|
||||
if (this::navBar.isInitialized) {
|
||||
navBar.selectTabAt(selected)
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
private class ViewPagerAdapter(
|
||||
fragmentManager: FragmentManager,
|
||||
lifecycle: Lifecycle,
|
||||
val id: Int = -1
|
||||
) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
override fun getItemCount(): Int = 4
|
||||
|
||||
override fun createFragment(position: Int): Fragment = when (position) {
|
||||
0 -> NotificationFragment(if (id != -1) "getOne" else "media", id)
|
||||
1 -> NotificationFragment("user")
|
||||
2 -> NotificationFragment("subscription")
|
||||
3 -> NotificationFragment("comment")
|
||||
else -> NotificationFragment("media")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
package ani.dantotsu.profile.notification
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.databinding.FragmentNotificationsBinding
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.notifications.comment.CommentStore
|
||||
import ani.dantotsu.notifications.subscription.SubscriptionStore
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.profile.activity.FeedActivity
|
||||
import ani.dantotsu.setBaseline
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class NotificationFragment(val type: String, private val getID: Int = -1) : Fragment() {
|
||||
private lateinit var binding: FragmentNotificationsBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var currentPage = 1
|
||||
private var hasNextPage = false
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentNotificationsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val navbar = (activity as NotificationActivity).navBar
|
||||
binding.listRecyclerView.setBaseline(navbar)
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager = LinearLayoutManager(context)
|
||||
binding.emptyTextView.text = getString(R.string.no_notifications)
|
||||
lifecycleScope.launch {
|
||||
val list = when (type) {
|
||||
"getOne" -> getOne(getID)
|
||||
"media" -> getMediaUpdates()
|
||||
"user" -> getUserUpdates()
|
||||
"subscription" -> getSubscriptions()
|
||||
"comment" -> getComments()
|
||||
else -> listOf()
|
||||
}
|
||||
adapter.addAll(list.map { NotificationItem(it, ::onClick) })
|
||||
if (adapter.itemCount != 0) {
|
||||
binding.listProgressBar.isVisible = false
|
||||
}else{
|
||||
binding.listProgressBar.isVisible = false
|
||||
binding.emptyTextView.isVisible = true
|
||||
}
|
||||
}
|
||||
binding.followSwipeRefresh.setOnRefreshListener {
|
||||
lifecycleScope.launch {
|
||||
adapter.clear()
|
||||
currentPage = 1
|
||||
val list = when (type) {
|
||||
"getOne" -> getOne(getID)
|
||||
"media" -> getMediaUpdates()
|
||||
"user" -> getUserUpdates()
|
||||
"subscription" -> getSubscriptions()
|
||||
"comment" -> getComments()
|
||||
else -> listOf()
|
||||
}
|
||||
adapter.addAll(list.map { NotificationItem(it, ::onClick) })
|
||||
binding.followSwipeRefresh.isRefreshing = false
|
||||
}
|
||||
}
|
||||
binding.listRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
if (shouldLoadMore()) {
|
||||
lifecycleScope.launch {
|
||||
val list = when (type) {
|
||||
"media" -> getMediaUpdates()
|
||||
"user" -> getUserUpdates()
|
||||
else -> listOf()
|
||||
}
|
||||
binding.followRefresh.visibility = View.VISIBLE
|
||||
adapter.addAll(list.map {
|
||||
NotificationItem(
|
||||
it,
|
||||
::onClick
|
||||
)
|
||||
})
|
||||
binding.followRefresh.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
private suspend fun getNotificationsFiltered(filter: (Notification) -> Boolean): List<Notification> {
|
||||
val userId = Anilist.userid ?: PrefManager.getVal<String>(PrefName.AnilistUserId).toIntOrNull() ?: 0
|
||||
val res = withContext(Dispatchers.IO) {
|
||||
Anilist.query.getNotifications(userId, currentPage)
|
||||
}
|
||||
currentPage = res?.data?.page?.pageInfo?.currentPage?.plus(1) ?: 1
|
||||
hasNextPage = res?.data?.page?.pageInfo?.hasNextPage ?: false
|
||||
return res?.data?.page?.notifications?.filter(filter) ?: listOf()
|
||||
}
|
||||
|
||||
private suspend fun getMediaUpdates(): List<Notification> {
|
||||
return getNotificationsFiltered { it.media != null }
|
||||
}
|
||||
|
||||
private suspend fun getUserUpdates(): List<Notification> {
|
||||
return getNotificationsFiltered { it.media == null }
|
||||
}
|
||||
|
||||
private suspend fun getOne(id: Int): List<Notification> {
|
||||
return getNotificationsFiltered { it.id == id }
|
||||
}
|
||||
|
||||
private fun getSubscriptions(): List<Notification> {
|
||||
val list = PrefManager.getNullableVal<List<SubscriptionStore>>(
|
||||
PrefName.SubscriptionNotificationStore,
|
||||
null
|
||||
) ?: listOf()
|
||||
return list.sortedByDescending{ (it.time / 1000L).toInt() }
|
||||
.filter{ it.image != null }.map {
|
||||
Notification(
|
||||
it.type,
|
||||
System.currentTimeMillis().toInt(),
|
||||
commentId = it.mediaId,
|
||||
mediaId = it.mediaId,
|
||||
notificationType = it.type,
|
||||
context = it.title + ": " + it.content,
|
||||
createdAt = (it.time / 1000L).toInt(),
|
||||
image = it.image,
|
||||
banner = it.banner ?: it.image
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getComments(): List<Notification> {
|
||||
val list = PrefManager.getNullableVal<List<CommentStore>>(
|
||||
PrefName.CommentNotificationStore,
|
||||
null
|
||||
) ?: listOf()
|
||||
return list
|
||||
.sortedByDescending {(it.time / 1000L).toInt()}
|
||||
.map {
|
||||
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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldLoadMore(): Boolean {
|
||||
val layoutManager = binding.listRecyclerView.layoutManager as LinearLayoutManager
|
||||
val adapter = binding.listRecyclerView.adapter
|
||||
|
||||
return hasNextPage && !binding.followRefresh.isVisible && adapter?.itemCount != 0 &&
|
||||
layoutManager.findLastVisibleItemPosition() == (adapter!!.itemCount - 1) &&
|
||||
!binding.listRecyclerView.canScrollVertically(1)
|
||||
}
|
||||
|
||||
fun onClick(
|
||||
id: Int,
|
||||
optional: Int?,
|
||||
type: NotificationClickType
|
||||
) {
|
||||
when (type) {
|
||||
NotificationClickType.USER -> {
|
||||
ContextCompat.startActivity(
|
||||
requireContext(), Intent( requireContext(), ProfileActivity::class.java)
|
||||
.putExtra("userId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.MEDIA -> {
|
||||
ContextCompat.startActivity(
|
||||
requireContext(), Intent( requireContext(), MediaDetailsActivity::class.java)
|
||||
.putExtra("mediaId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.ACTIVITY -> {
|
||||
ContextCompat.startActivity(
|
||||
requireContext(), Intent( requireContext(), FeedActivity::class.java)
|
||||
.putExtra("activityId", id), null
|
||||
)
|
||||
}
|
||||
|
||||
NotificationClickType.COMMENT -> {
|
||||
ContextCompat.startActivity(
|
||||
requireContext(), Intent( requireContext(), MediaDetailsActivity::class.java)
|
||||
.putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
|
||||
.putExtra("mediaId", id)
|
||||
.putExtra("commentId", optional ?: -1),
|
||||
null
|
||||
)
|
||||
|
||||
}
|
||||
NotificationClickType.UNDEFINED -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (this::binding.isInitialized) {
|
||||
binding.root.requestLayout()
|
||||
binding.root.setBaseline((activity as NotificationActivity).navBar)
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
enum class NotificationClickType {
|
||||
USER, MEDIA, ACTIVITY, COMMENT, UNDEFINED
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
package ani.dantotsu.profile.notification
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -8,7 +8,8 @@ import ani.dantotsu.connections.anilist.api.Notification
|
|||
import ani.dantotsu.connections.anilist.api.NotificationType
|
||||
import ani.dantotsu.databinding.ItemNotificationBinding
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.profile.activity.NotificationActivity.Companion.NotificationClickType
|
||||
import ani.dantotsu.profile.notification.NotificationFragment.Companion.NotificationClickType
|
||||
import ani.dantotsu.profile.activity.ActivityItemBuilder
|
||||
import ani.dantotsu.setAnimation
|
||||
import ani.dantotsu.toPx
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
Loading…
Add table
Add a link
Reference in a new issue