feat(notifications): Notification fetching & marking as read

This commit is contained in:
Peter Vacho 2025-01-04 12:35:45 +01:00
parent 4cf5a35255
commit dbbbfee769
Signed by: school
GPG key ID: 8CFC3837052871B4
2 changed files with 47 additions and 28 deletions

View file

@ -2,21 +2,29 @@ package com.p_vacho.neat_calendar.activities
import android.os.Bundle import android.os.Bundle
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.p_vacho.neat_calendar.MyApplication
import com.p_vacho.neat_calendar.R import com.p_vacho.neat_calendar.R
import com.p_vacho.neat_calendar.adapters.NotificationAdapter import com.p_vacho.neat_calendar.adapters.NotificationAdapter
import com.p_vacho.neat_calendar.api.RetrofitClient
import com.p_vacho.neat_calendar.api.models.NotificationResponse import com.p_vacho.neat_calendar.api.models.NotificationResponse
import java.time.OffsetDateTime import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class NotificationsActivity : AppCompatActivity() { class NotificationsActivity : AppCompatActivity() {
private lateinit var rvNotifications: RecyclerView private lateinit var rvNotifications: RecyclerView
private lateinit var btnBack: ImageButton private lateinit var btnBack: ImageButton
private lateinit var notifications: MutableList<NotificationResponse>
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
@ -31,33 +39,29 @@ class NotificationsActivity : AppCompatActivity() {
rvNotifications = findViewById(R.id.rvNotifications) rvNotifications = findViewById(R.id.rvNotifications)
btnBack = findViewById(R.id.btnBack) btnBack = findViewById(R.id.btnBack)
val notifications = fetchNotifications()
val adapter = NotificationAdapter(notifications, ::handleNotificationAction, ::handleNotificationClick)
rvNotifications.layoutManager = LinearLayoutManager(this) rvNotifications.layoutManager = LinearLayoutManager(this)
rvNotifications.adapter = adapter
lifecycleScope.launch {
notifications = fetchNotifications().toMutableList()
rvNotifications.adapter = NotificationAdapter(notifications, ::handleNotificationAction, ::handleNotificationClick)
}
btnBack.setOnClickListener { finish() } btnBack.setOnClickListener { finish() }
} }
private fun fetchNotifications(): List<NotificationResponse> { private suspend fun fetchNotifications(): List<NotificationResponse> {
// TODO: Replace with actual API calls val userId = (application as MyApplication).tokenManager.userId
return listOf(
NotificationResponse( if (userId == null) {
"1", "2", "invitation", finish()
"You've been invited to event X", return emptyList()
"12", false, OffsetDateTime.now(), null }
),
NotificationResponse( val notifications = withContext(Dispatchers.IO) {
"2", "2", "message", RetrofitClient.notificationsService.getUserNotifications(userId)
"System maintenance scheduled", }
"", false, OffsetDateTime.now(), null
), return notifications
NotificationResponse(
"2", "2", "message",
"App update available",
"", true, OffsetDateTime.now(), null
),
)
} }
private fun handleNotificationAction(notification: NotificationResponse, action: NotificationAdapter.Action, position: Int) { private fun handleNotificationAction(notification: NotificationResponse, action: NotificationAdapter.Action, position: Int) {
@ -72,6 +76,15 @@ class NotificationsActivity : AppCompatActivity() {
} }
private fun handleNotificationClick(notification: NotificationResponse, position: Int) { private fun handleNotificationClick(notification: NotificationResponse, position: Int) {
TODO("Handle marking notification as read") lifecycleScope.launch {
val updatedNotification =
RetrofitClient.notificationsService.markNotificationRead(notification.id)
notifications[position] = updatedNotification
val adapter = rvNotifications.adapter as NotificationAdapter
adapter.notifyItemChanged(position)
Toast.makeText(this@NotificationsActivity, "Marked as read", Toast.LENGTH_SHORT).show()
}
} }
} }

View file

@ -10,7 +10,7 @@ import com.p_vacho.neat_calendar.R
import com.p_vacho.neat_calendar.api.models.NotificationResponse import com.p_vacho.neat_calendar.api.models.NotificationResponse
class NotificationAdapter( class NotificationAdapter(
private val notifications: List<NotificationResponse>, private val notifications: MutableList<NotificationResponse>,
private val onActionClick: (NotificationResponse, Action, Int) -> Unit, private val onActionClick: (NotificationResponse, Action, Int) -> Unit,
private val onNotificationClick: (NotificationResponse, Int) -> Unit, private val onNotificationClick: (NotificationResponse, Int) -> Unit,
) : RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder>() { ) : RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder>() {
@ -54,9 +54,15 @@ class NotificationAdapter(
holder.invitationActions.visibility = View.GONE holder.invitationActions.visibility = View.GONE
} }
// Set click listener for the whole notification (excluding buttons) // Set click listener for the whole notification (only for unread ones though)
holder.itemView.setOnClickListener { if (!notification.read) {
onNotificationClick(notification, position) holder.itemView.isClickable = true
holder.itemView.setOnClickListener {
onNotificationClick(notification, position)
}
} else {
holder.itemView.isClickable = false
holder.itemView.setOnClickListener(null)
} }
// Ensure buttons consume their click events // Ensure buttons consume their click events