Skip to content

Commit 3af50cd

Browse files
authored
Documentation Done for feature/notification (#2991)
1 parent 0d10464 commit 3af50cd

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

feature/notification/src/commonMain/kotlin/org/mifos/mobile/feature/notification/NotificationScreen.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ import org.mifos.mobile.core.ui.component.EmptyDataView
5151
import org.mifos.mobile.core.ui.component.MifosErrorComponent
5252
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay
5353

54+
/**
55+
* This is the main entry point for the Notification Screen feature. It's a composable function
56+
* that sets up the screen, observes state from the [NotificationViewModel], and delegates the UI
57+
* rendering to other composable functions.
58+
*
59+
* @param navigateBack A lambda function to be invoked when the user wants to navigate back from
60+
* this screen.
61+
* @param modifier The [Modifier] to be applied to this composable.
62+
* @param viewModel An instance of [NotificationViewModel] which holds the business logic for this
63+
* screen. It's provided by Koin's `koinViewModel()`.
64+
*/
5465
@Composable
5566
internal fun NotificationScreen(
5667
navigateBack: () -> Unit,
@@ -73,6 +84,22 @@ internal fun NotificationScreen(
7384
)
7485
}
7586

87+
/**
88+
* This composable function is responsible for displaying the main content of the Notification
89+
* Screen. It acts as a presentation layer that reacts to different UI states like Loading, Error,
90+
* Success, or Empty. Based on the `uiState`, it renders the appropriate composable.
91+
*
92+
* @param uiState The current state of the UI, which determines what to display.
93+
* @param isNetworkAvailable A boolean that indicates whether the device has an active network
94+
* connection.
95+
* @param navigateBack A lambda function to handle the back navigation event.
96+
* @param onRetry A lambda function to be called when the user wants to retry loading notifications
97+
* after an error.
98+
* @param dismissNotification A lambda function to handle the dismissal of a notification.
99+
* @param isRefreshing A boolean that indicates if the screen is currently in a refresh state.
100+
* @param onRefresh A lambda function to be called to refresh the list of notifications.
101+
* @param modifier The [Modifier] to be applied to this composable.
102+
*/
76103
@Composable
77104
private fun NotificationScreen(
78105
uiState: NotificationUiState,
@@ -124,6 +151,19 @@ private fun NotificationScreen(
124151
)
125152
}
126153

154+
/**
155+
* This composable function is responsible for displaying the list of notifications. It uses a
156+
* [PullToRefreshBox], allowing the user to swipe down to refresh the list. The actual list is
157+
* rendered using a `LazyColumn` for efficient display of potentially long lists.
158+
*
159+
* @param isRefreshing A boolean indicating if the pull-to-refresh action is currently active.
160+
* @param notifications The list of [MifosNotification] objects to be displayed.
161+
* @param dismissNotification A lambda function that handles the action of dismissing a
162+
* notification.
163+
* @param onRefresh A lambda function that's triggered when the user performs a pull-to-refresh
164+
* gesture.
165+
* @param modifier The [Modifier] to be applied to this composable.
166+
*/
127167
@OptIn(ExperimentalMaterial3Api::class)
128168
@Composable
129169
private fun NotificationContent(
@@ -155,6 +195,16 @@ private fun NotificationContent(
155195
}
156196
}
157197

198+
/**
199+
* This composable function is designed to display a single notification item in the list. It shows
200+
* the notification's message, the timestamp, and provides an "OK" button to dismiss it if it's
201+
* unread. The visual style of the item changes based on whether the notification has been read.
202+
*
203+
* @param notification The [MifosNotification] object to be displayed.
204+
* @param dismissNotification A lambda function that's called when the user dismisses the
205+
* notification.
206+
* @param modifier The [Modifier] to be applied to this composable.
207+
*/
158208
@Composable
159209
private fun NotificationItem(
160210
notification: MifosNotification,

feature/notification/src/commonMain/kotlin/org/mifos/mobile/feature/notification/NotificationViewModel.kt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ import org.mifos.mobile.core.data.util.NetworkMonitor
2323
import org.mifos.mobile.core.model.entity.MifosNotification
2424
import org.mifos.mobile.feature.notification.NotificationUiState.Loading
2525

26+
/**
27+
* The ViewModel for the Notification screen.
28+
*
29+
* This class is responsible for the business logic of the Notification screen. It fetches
30+
* notifications from the [NotificationRepository], manages the UI state, and handles user
31+
* interactions like refreshing the list and dismissing notifications. It's also aware of the
32+
* network status, thanks to [NetworkMonitor].
33+
*
34+
* @param notificationRepositoryImp The repository that provides access to notification data.
35+
* @param networkMonitor A utility to monitor the device's network connectivity.
36+
*/
2637
internal class NotificationViewModel(
2738
private val notificationRepositoryImp: NotificationRepository,
2839
networkMonitor: NetworkMonitor,
@@ -48,6 +59,10 @@ internal class NotificationViewModel(
4859
}
4960
}
5061

62+
/**
63+
* Kicks off the process of loading notifications from the repository. This function updates the
64+
* UI state to reflect the current status of the operation, such as Loading, Success, or Error.
65+
*/
5166
fun loadNotifications() {
5267
_notificationUiState.value = Loading
5368
viewModelScope.launch {
@@ -78,18 +93,36 @@ internal class NotificationViewModel(
7893
}
7994
}
8095

96+
/**
97+
* Initiates a refresh of the notifications. This is typically triggered by a user action, like
98+
* a pull-to-refresh gesture. It sets the refreshing state and then calls [loadNotifications]
99+
* to fetch the latest data.
100+
*/
81101
fun refreshNotifications() {
82102
_isRefreshing.value = true
83103
loadNotifications()
84104
}
85105

106+
/**
107+
* Marks a specific notification as read. This involves updating the notification's state in
108+
* the local repository to ensure the change is persisted.
109+
*
110+
* @param notification The [MifosNotification] to be marked as read.
111+
*/
86112
fun dismissNotification(notification: MifosNotification) {
87113
viewModelScope.launch {
88114
notificationRepositoryImp.saveNotification(notification.copy(read = true))
89115
notificationRepositoryImp.updateReadStatus(notification, true)
90116
}
91117
}
92118

119+
/**
120+
* Sorts a list of notifications. The sorting logic prioritizes unread notifications and then
121+
* sorts them by timestamp, so the most recent ones appear first.
122+
*
123+
* @param notifications The list of [MifosNotification]s to be sorted.
124+
* @return A new list containing the sorted notifications.
125+
*/
93126
private fun sortNotifications(notifications: List<MifosNotification>): List<MifosNotification> {
94127
return notifications.sortedWith(
95128
compareByDescending<MifosNotification> { !it.isRead() }
@@ -98,9 +131,34 @@ internal class NotificationViewModel(
98131
}
99132
}
100133

134+
/**
135+
* A sealed interface that represents the various states the Notification screen can be in. This
136+
* allows for exhaustive state handling in the UI, ensuring a predictable user experience.
137+
*/
101138
internal sealed interface NotificationUiState {
139+
/**
140+
* Indicates that the notifications are currently being loaded. This is the ideal time to show
141+
* a progress indicator.
142+
*/
102143
data object Loading : NotificationUiState
144+
145+
/**
146+
* Represents a successful fetch of notifications.
147+
*
148+
* @param notifications The list of notifications to be displayed on the screen.
149+
*/
103150
data class Success(val notifications: List<MifosNotification>) : NotificationUiState
151+
152+
/**
153+
* Signals that an error occurred while trying to fetch notifications.
154+
*
155+
* @param errorMessage A descriptive message about the error that can be shown to the user.
156+
*/
104157
data class Error(val errorMessage: String?) : NotificationUiState
158+
159+
/**
160+
* Used when the notification list is empty. This state allows for showing a user-friendly
161+
* message indicating that there are no notifications.
162+
*/
105163
data object Empty : NotificationUiState
106164
}

feature/notification/src/commonMain/kotlin/org/mifos/mobile/feature/notification/navigation/NotificationNavigation.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,32 @@ import kotlinx.serialization.Serializable
1818
import org.mifos.mobile.core.ui.composableWithPushTransitions
1919
import org.mifos.mobile.feature.notification.NotificationScreen
2020

21+
/**
22+
* A type-safe navigation destination for the Notification Screen. Using a serializable object
23+
* like this ensures that navigation is robust and less prone to runtime errors.
24+
*/
2125
@Serializable
2226
data object NotificationRoute
2327

28+
/**
29+
* An extension function on [NavController] that provides a convenient and type-safe way to
30+
* navigate to the Notification Screen.
31+
*
32+
* @param navOptions Optional [NavOptions] to apply to this navigation action. This can be used
33+
* to control aspects like the back stack and animations.
34+
*/
2435
fun NavController.navigateToNotificationScreen(navOptions: NavOptions? = null) {
2536
navigate(NotificationRoute, navOptions)
2637
}
2738

39+
/**
40+
* An extension function on [NavGraphBuilder] that defines the Notification Screen destination
41+
* within the navigation graph. This is where the screen's composable is associated with its
42+
* route, and where transitions and arguments can be configured.
43+
*
44+
* @param navigateBack A lambda function that will be invoked when the user navigates back from
45+
* the Notification Screen. This is typically used to pop the back stack.
46+
*/
2847
fun NavGraphBuilder.notificationDestination(
2948
navigateBack: () -> Unit,
3049
) {

0 commit comments

Comments
 (0)