This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A composable function that displays the main notes screen in the app. | |
* This screen dynamically updates its content based on the UI state provided by the ViewModel. | |
* | |
* @param viewModel The ViewModel that provides the state and handles user interactions. | |
*/ | |
@Composable | |
fun NotesScreen( | |
viewModel: NoteViewModel | |
) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The main composable function for setting up the app's UI structure. | |
* It defines the scaffold layout, navigation, and other top-level elements for the app. | |
* | |
* @param navController The navigation controller for managing app navigation. | |
* @param snackbarHostState The state for displaying snackbars in the app. | |
*/ | |
@OptIn(ExperimentalMaterial3Api::class) | |
@Composable | |
fun MainApp( |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@AndroidEntryPoint | |
class MainActivity : ComponentActivity() { | |
@OptIn(ExperimentalMaterial3Api::class) | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
enableEdgeToEdge() | |
setContent { | |
NotesAppTheme { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A data class representing the UI state for displaying notes in the app. | |
* This class is used to encapsulate the state of the UI in a single immutable object. | |
* The immutable nature of the state guarantees that each update leads to a predictable | |
* UI change, helping prevent bugs and ensuring smooth interactions. | |
* | |
* @param isLoading Indicates whether the UI is currently in a loading state. | |
* @param notes A list of notes to display in the UI. Defaults to an empty list. | |
*/ | |
data class NoteUiViewState( |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A singleton object responsible for managing application-wide events in a reactive manner. | |
* It provides an easy way to trigger and observe events using Channel. | |
* This is particularly useful in unidirectional data flow architecture (MVI). | |
*/ | |
object EventManager { | |
/** | |
* A buffered channel to send and receive application events. | |
* This channel ensures that events are stored temporarily until they are consumed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A sealed class representing all possible user actions (via intents). | |
* This helps to encapsulate and categorize user inputs in a type-safe and maintainable way, | |
* making it easier to handle these actions in a centralized manner (e.g., in a ViewModel). | |
* By using a sealed class for intents, MVI ensures that each possible user interaction is | |
* explicitly defined, making it easier to manage different actions in a structured way. | |
*/ | |
sealed class NoteIntent { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class NoteRepository @Inject constructor( | |
private val noteDao: NoteDao | |
) { | |
suspend fun insertNote(note: Note) = noteDao.insertNote(note) | |
suspend fun updateNote(note: Note) = noteDao.updateNote(note) | |
suspend fun deleteNote(note: Note) = noteDao.deleteNote(note) | |
fun getNotes(): Flow<List<Note>> = noteDao.fetchAllNotes() | |
fun getNote(noteId: Long): Flow<Note> = noteDao.getNote(noteId) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* [NoteDatabase] defines the database configuration and serves as the app's main access point | |
* to the persisted data. The database class must satisfy the following conditions: | |
* 1. The class must be annotated with a @Database annotation that includes an entities | |
* array that lists all of the data entities associated with the database. | |
* 2. The class must be an abstract class that extends RoomDatabase. | |
* 3. For each DAO class that is associated with the database, the database class must | |
* define an abstract method that has zero arguments and returns an instance of the DAO class. | |
*/ | |
@Database(entities = [Note::class], version = 1, exportSchema = false) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* DAO's are data access objects. They includes methods that offer abstract access | |
* to the app's database. At compile time, Room automatically generates implementations | |
* of the DAOs that we define. | |
*/ | |
@Dao | |
interface NoteDao { | |
@Insert(onConflict = OnConflictStrategy.REPLACE) | |
suspend fun insertNote(note: Note): Long |
NewerOlder