Skip to content

Instantly share code, notes, and snippets.

@anitaa1990
Last active November 30, 2024 17:44
Show Gist options
  • Select an option

  • Save anitaa1990/9f9fafa3e5707de6b0ee12025c61ddb3 to your computer and use it in GitHub Desktop.

Select an option

Save anitaa1990/9f9fafa3e5707de6b0ee12025c61ddb3 to your computer and use it in GitHub Desktop.
/**
* The ViewModel class manages the UI state and handling user interactions.
* It serves as the bridge between the repository and the UI, ensuring unidirectional data flow.
* This ViewModel uses Hilt for dependency injection and manages state using StateFlow.
*
* @param repository The repository responsible for performing data operations related to notes.
*/
@HiltViewModel
class NoteViewModel @Inject constructor(
private val repository: NoteRepository
) : ViewModel() {
/**
* A private MutableStateFlow to store and update the UI state for the notes screen.
*/
private val _notesViewState = MutableStateFlow(NotesViewState())
/**
* A public immutable StateFlow exposing the current UI state.
* The UI observes this flow to react to state changes.
*/
val notesViewState: StateFlow<NotesViewState> = _notesViewState
/**
* Upon creation, the ViewModel immediately triggers a LoadNotes
* intent to fetch and display the current user list. This automatic
* loading of data when the ViewModel is initialized ensures that the
* UI is always populated with up-to-date information when the notes
* screen appears.
*/
init {
handleIntent(NoteIntent.LoadNotes)
}
/**
* Handles user intents by mapping them to appropriate methods.
* This ensures that all user actions are processed in a centralized, predictable manner.
*
* @param intent The user action to be handled.
*/
fun handleIntent(intent: NoteIntent) {
when (intent) {
is NoteIntent.LoadNotes -> loadNotes()
is NoteIntent.DeleteNote -> deleteNote(intent.note)
is NoteIntent.OpenNoteClicked -> onNoteClicked(intent.note)
is NoteIntent.ValidatePassword -> validatePassword(intent.password)
else -> { /* No-op for unsupported intents */ }
}
}
/**
* The loadNotes function performs the following steps:
* 1. Set Loading State: Updates the state to indicate that a loading process
* is in progress by setting isLoading = true.
* 2. Retrieve Data: Using viewModelScope.launch, it asynchronously fetches
* the list of notes from the repository.
* 3. Update State: Once the data is fetched, the state is updated with the
* new notes list, and the loading flag is set to false to indicate that
* the loading process is complete.
* 4. Trigger Effect: A snackbar effect is sent to notify the user that the
* data has been successfully loaded.
* This function ensures that the UI accurately reflects the loading status and the
* notes list, following the MVI pattern’s principles of immutability and
* state management.
*/
private fun loadNotes() {
_notesViewState.value = _notesViewState.value.copy(isLoading = true)
viewModelScope.launch(IO) {
repository.getNotes().collect { notes ->
_notesViewState.value = _notesViewState.value.copy(
isLoading = false,
notes = notes
)
}
}
}
/**
* Deletes a note via the repository and triggers a snackbar event to notify the user of success.
*
* @param note The note to be deleted.
*/
private fun deleteNote(note: Note) {
viewModelScope.launch(IO) {
repository.deleteNote(note)
EventManager.triggerEvent(AppEvent.ShowSnackbar(R.string.delete_note_success))
}
}
/**
* Handles the user clicking on a note.
* If the note is encrypted, prompts the user to enter a password.
* Otherwise, navigates to the note detail screen.
*
* @param note The note that was clicked.
*/
private fun onNoteClicked(note: Note) {
if (note.encrypt) {
_notesViewState.value = _notesViewState.value.copy(
selectedNote = note,
showPasswordSheet = true
)
} else {
EventManager.triggerEvent(AppEvent.NavigateToDetail(note.id))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment