diff --git a/app/src/main/java/com/p_vacho/neat_calendar/activities/NotificationsActivity.kt b/app/src/main/java/com/p_vacho/neat_calendar/activities/NotificationsActivity.kt index c1527b5..3a656e1 100644 --- a/app/src/main/java/com/p_vacho/neat_calendar/activities/NotificationsActivity.kt +++ b/app/src/main/java/com/p_vacho/neat_calendar/activities/NotificationsActivity.kt @@ -127,6 +127,10 @@ class NotificationsActivity : AppCompatActivity() { return fetchedEvents.associateBy { it.id } } + /** + * Fetch both the incoming & outgoing (owned) invitations for the currently + * logged in user. + */ private suspend fun fetchInvitations(): Map { val userId = (application as MyApplication).tokenManager.userId if (userId == null) { @@ -146,6 +150,13 @@ class NotificationsActivity : AppCompatActivity() { return fetchedInvitations.associateBy { it.id } } + /** + * A callback function passed to the Notification Adapter, to allow it to request + * a specific invitation by ID. + * + * This function only obtains the invitation from the pre-fetched invitations list, + * it will not make any new requests. Unknown IDs will result in null. + */ private fun getInvitationData(invitationId: String, rvPosition: Int): InvitationResponse? { val ret = invitations[invitationId] if (ret == null) { @@ -155,6 +166,13 @@ class NotificationsActivity : AppCompatActivity() { return ret } + /** + * A callback function passed to the Notification Adapter, to allow it to request + * a specific event by ID. + * + * This function only obtains the events from the pre-fetched events list, + * it will not make any new requests. Unknown IDs will result in null. + */ private fun getEventData(eventId: String, rvPosition: Int): EventResponse? { val ret = events[eventId] if (ret == null) { @@ -164,6 +182,21 @@ class NotificationsActivity : AppCompatActivity() { return ret } + /** + * A callback function passed to the Notification Adapter, to allow it to request + * a specific user by ID. + * + * This function obtains the users lazily, making a new API request whenever it + * encounters an unknown ID. After obtaining the user data, it will be cached and + * another request for the same user will not be made. + * + * Since the API call needs to be async, instead of making this function block, it + * will immediately return null at first, while the leaving the coroutine for the + * API fetching runs in the background. Once this request finished, if successful, + * the adapter will be notified about a change of this item, which will make it + * call this function again. This time though, it will return immediately from cache, + * without any making further API calls. + */ private fun getUserData(userId: String, rvPosition: Int?): UserResponse? { return users.getOrPut(userId) { lifecycleScope.launch(Dispatchers.IO) { @@ -198,6 +231,15 @@ class NotificationsActivity : AppCompatActivity() { } } + /** + * A callback function passed to the Notification Adapter, triggered by clicking on one of the + * action buttons of the notification. (Currently, the only actions notifications support are + * invite related). + * + * The notification adapter should only call this function if the action is performable, so + * we shouldn't need to perform any additional checks for whether the requested action makes + * sense for given notification. + */ private fun handleNotificationAction(notification: NotificationResponse, action: NotificationAdapter.Action, position: Int) { when (action) { NotificationAdapter.Action.ACCEPT -> { @@ -247,6 +289,12 @@ class NotificationsActivity : AppCompatActivity() { } } + /** + * A callback function passed to the Notification Adapter, triggered by clicking on the notification + * itself. This should mark the notification as read. + * + * The adapter should only call this function if the notification isn't already marked as read. + */ private fun handleNotificationClick(notification: NotificationResponse, position: Int, sendToast: Boolean = true) { lifecycleScope.launch { val updatedNotification = @@ -262,6 +310,11 @@ class NotificationsActivity : AppCompatActivity() { } } + /** + * Attach an ItemTouchHelper to the recycler view adapter, to allow swiping + * of it's items. We only enable swiping to the right, which will trigger + * a deletion of that notification. + */ private fun setupSwipeToDelete(adapter: NotificationAdapter) { val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { override fun onMove( @@ -301,6 +354,12 @@ class NotificationsActivity : AppCompatActivity() { itemTouchHelper.attachToRecyclerView(rvNotifications) } + /** + * This is a helper function to toggle the visibility of the empty state message + * when no notifications are available. + * + * This should be called whenever a notification was removed or added. + */ private fun updateEmptyState() { val isEmpty = notifications.isEmpty() tvEmptyState.visibility = if (isEmpty) View.VISIBLE else View.GONE