Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ import org.mifos.mobile.core.ui.component.EmptyDataView
import org.mifos.mobile.core.ui.component.MifosErrorComponent
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay

/**
* Composable function for the Notification Screen.
* This is the entry point for the notification feature.
*
* @param navigateBack The function to call to navigate back to the previous screen.
* @param modifier [Modifier] for the composable.
* @param viewModel The [NotificationViewModel] for this screen.
*/
@Composable
internal fun NotificationScreen(
navigateBack: () -> Unit,
Expand All @@ -73,6 +81,20 @@ internal fun NotificationScreen(
)
}

/**
* Composable function that displays the main content of the Notification Screen.
* It handles the different UI states (Loading, Error, Success, Empty) and displays
* the appropriate content.
*
* @param uiState The current state of the UI.
* @param isNetworkAvailable A boolean indicating if the network is available.
* @param navigateBack The function to call to navigate back to the previous screen.
* @param onRetry The function to call to retry loading notifications.
* @param dismissNotification The function to call to dismiss a notification.
* @param isRefreshing A boolean indicating if the screen is being refreshed.
* @param onRefresh The function to call to refresh the notifications.
* @param modifier [Modifier] for the composable.
*/
@Composable
private fun NotificationScreen(
uiState: NotificationUiState,
Expand Down Expand Up @@ -124,6 +146,16 @@ private fun NotificationScreen(
)
}

/**
* Composable function that displays the list of notifications.
* It uses a [PullToRefreshBox] to allow the user to refresh the list.
*
* @param isRefreshing A boolean indicating if the screen is being refreshed.
* @param notifications The list of notifications to display.
* @param dismissNotification The function to call to dismiss a notification.
* @param onRefresh The function to call to refresh the notifications.
* @param modifier [Modifier] for the composable.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun NotificationContent(
Expand Down Expand Up @@ -155,6 +187,13 @@ private fun NotificationContent(
}
}

/**
* Composable function that displays a single notification item.
*
* @param notification The notification to display.
* @param dismissNotification The function to call to dismiss the notification.
* @param modifier [Modifier] for the composable.
*/
@Composable
private fun NotificationItem(
notification: MifosNotification,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ import org.mifos.mobile.core.data.util.NetworkMonitor
import org.mifos.mobile.core.model.entity.MifosNotification
import org.mifos.mobile.feature.notification.NotificationUiState.Loading

/**
* ViewModel for the Notification screen.
*
* This ViewModel is responsible for loading notifications, handling refreshing,
* and managing the UI state of the notification screen. It interacts with the
* [NotificationRepository] to fetch and update notification data. It also
* monitors network availability via [NetworkMonitor].
*
* @param notificationRepositoryImp The repository for accessing notification data.
* @param networkMonitor The utility to monitor network connectivity.
*/
internal class NotificationViewModel(
private val notificationRepositoryImp: NotificationRepository,
networkMonitor: NetworkMonitor,
Expand All @@ -48,6 +59,10 @@ internal class NotificationViewModel(
}
}

/**
* Loads the notifications from the repository and updates the UI state.
* It handles loading, success, and error states.
*/
fun loadNotifications() {
_notificationUiState.value = Loading
viewModelScope.launch {
Expand Down Expand Up @@ -78,18 +93,31 @@ internal class NotificationViewModel(
}
}

/**
* Refreshes the notifications by setting the refreshing state and calling [loadNotifications].
*/
fun refreshNotifications() {
_isRefreshing.value = true
loadNotifications()
}

/**
* Marks a notification as read and saves the updated status in the repository.
* @param notification The notification to be dismissed.
*/
fun dismissNotification(notification: MifosNotification) {
viewModelScope.launch {
notificationRepositoryImp.saveNotification(notification.copy(read = true))
notificationRepositoryImp.updateReadStatus(notification, true)
}
}

/**
* Sorts the notifications based on their read status and timestamp.
* Unread notifications are shown first, followed by the most recent ones.
* @param notifications The list of notifications to be sorted.
* @return The sorted list of notifications.
*/
private fun sortNotifications(notifications: List<MifosNotification>): List<MifosNotification> {
return notifications.sortedWith(
compareByDescending<MifosNotification> { !it.isRead() }
Expand All @@ -98,9 +126,29 @@ internal class NotificationViewModel(
}
}

/**
* Represents the different UI states for the Notification screen.
*/
internal sealed interface NotificationUiState {
/**
* Represents the loading state where notifications are being fetched.
*/
data object Loading : NotificationUiState

/**
* Represents the success state with a list of notifications.
* @param notifications The list of notifications to display.
*/
data class Success(val notifications: List<MifosNotification>) : NotificationUiState

/**
* Represents the error state with an error message.
* @param errorMessage The error message to display.
*/
data class Error(val errorMessage: String?) : NotificationUiState

/**
* Represents the empty state when no notifications are available.
*/
data object Empty : NotificationUiState
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,26 @@ import kotlinx.serialization.Serializable
import org.mifos.mobile.core.ui.composableWithPushTransitions
import org.mifos.mobile.feature.notification.NotificationScreen

/**
* Navigation route for the Notification Screen.
*/
@Serializable
data object NotificationRoute

/**
* Navigates to the Notification Screen.
*
* @param navOptions The navigation options to be applied.
*/
fun NavController.navigateToNotificationScreen(navOptions: NavOptions? = null) {
navigate(NotificationRoute, navOptions)
}

/**
* Adds the Notification Screen to the navigation graph.
*
* @param navigateBack The function to be called when the back button is pressed.
*/
fun NavGraphBuilder.notificationDestination(
navigateBack: () -> Unit,
) {
Expand Down
Loading