Feature: Adding a New Word
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/java/com/vocabri/ui/screens/addword/AddWordScreen.kt
- app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordViewModel.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/AddWordUseCase.kt
- app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordState.kt
- app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordEvent.kt
- data/src/main/java/com/vocabri/data/datasource/word/WordLocalDataSourceImpl.kt
- app/src/main/java/com/vocabri/di/AppModule.kt
- app/src/main/java/com/vocabri/ui/screens/addword/components/NounFields.kt
- app/src/main/java/com/vocabri/ui/screens/addword/components/VerbFields.kt
- app/src/main/java/com/vocabri/ui/screens/addword/components/AdjectiveAdverbFields.kt
The "Add Word" feature is a cornerstone of the Vocabri application, providing users with the functionality to build their personal vocabulary. It allows for the entry of a new word, its translations, usage examples, and metadata specific to its part of speech (e.g., gender for nouns, conjugation for verbs).
This feature is implemented using a modern Android stack, including Jetpack Compose for the UI, a layered architecture (UI, Domain, Data), and the MVI (Model-View-Intent) pattern for state management. This ensures a reactive, testable, and maintainable implementation.
Architecture Overview
The feature follows a clean, layered architecture, separating concerns between the UI, business logic, and data persistence. The MVI pattern is used within the UI layer to manage state and user interactions.
This diagram illustrates the high-level component interaction for the "Add Word" feature.
Sources: app/src/main/java/com/vocabri/ui/screens/addword/AddWordScreen.kt, app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordViewModel.kt, domain/src/main/java/com/vocabri/domain/usecase/word/AddWordUseCase.kt, data/src/main/java/com/vocabri/data/datasource/word/WordLocalDataSourceImpl.kt
Dependencies are provided via Koin. The AddWordViewModel is instantiated in the appModule.
Sources: app/src/main/java/com/vocabri/di/AppModule.kt:29
UI Layer
The UI is built with Jetpack Compose and is responsible for rendering the state and capturing user input.
Sources: app/src/main/java/com/vocabri/ui/screens/addword/AddWordScreen.kt
AddWordScreen
The main entry point for the feature's UI is the AddWordScreen composable. Its primary roles are:
- Collecting the
AddWordStatefrom theAddWordViewModelas a StateFlow. - Displaying the appropriate UI content based on the current state (
Editing,Error, orSaved). - Sending
AddWordEvents to the ViewModel in response to user interactions. - Navigating away from the screen when the state becomes
AddWordState.Saved.
Sources: app/src/main/java/com/vocabri/ui/screens/addword/AddWordScreen.kt:53-65
UI Components
The AddWordScreenContent composable arranges several smaller, focused components in a LazyColumn.
This diagram shows the component structure of the AddWordScreenContent.
Key components include:
SelectPartOfSpeech: Allows the user to choose the word's part of speech (Noun, Verb, etc.).WordTextField: A text field for the word itself.TranslationTextField: A component for entering and managing a list of translations.ExampleTextField: A component for entering and managing a list of usage examples.NounFields,VerbFields,AdjectiveAdverbFields: These are displayed conditionally based on the selected part of speech to capture specific metadata.
State Management (MVI)
The feature's state is managed by AddWordViewModel following the MVI pattern.
Sources: app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordViewModel.kt
AddWordState
AddWordState is a sealed interface representing all possible states of the "Add Word" screen.
Editing: The default state where the user can input data. It holds all the form fields' values.Saved: A terminal state indicating the word was successfully saved. This triggers a navigation event.Error: Indicates that an error occurred during the save operation.
The Editing state contains numerous fields to manage the form's data:
| Property | Type | Description |
|---|---|---|
text | String | The word being added. |
translations | List<String> | A list of saved translations. |
currentTranslation | String | The translation currently being typed. |
partOfSpeech | PartOfSpeech | The selected part of speech (defaults to NOUN). |
selectedGender | WordGender? | The gender for a noun. |
pluralForm | String | The plural form for a noun. |
conjugations | List<String> | List of conjugations for a verb. |
managements | List<String> | List of managements for a verb. |
comparative | String | The comparative form for an adjective/adverb. |
superlative | String | The superlative form for an adjective/adverb. |
isSaveButtonEnabled | Boolean | Controls whether the save button is active. |
Sources: app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordState.kt:27-62
AddWordEvent
User actions are modeled as events defined in the AddWordEvent sealed interface. The AddWordViewModel.handleEvent function processes these events to update the state.
| Event | Description |
|---|---|
UpdateText(text) | Updates the word text. |
UpdatePartOfSpeech(pos) | Changes the selected part of speech. |
AddTranslation | Adds the currentTranslation to the translations list. |
RemoveTranslation(t) | Removes a translation from the list. |
UpdateNounGender(g) | Toggles the selection for a noun's gender. |
SaveWord | Initiates the process of saving the word. |
Sources: app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordEvent.kt:25-62, app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordViewModel.kt:51-89
Data Flow: Saving a Word
The core logic of the feature is triggered by the AddWordEvent.SaveWord event. The following sequence diagram details the entire flow from UI interaction to database insertion.
Domain and Data Layers
-
AddWordUseCase: This use case acts as a simple bridge between the ViewModel and the repository. Itsexecutemethod callswordRepository.insertWord(word), encapsulating this single piece of business logic.
Sources: domain/src/main/java/com/vocabri/domain/usecase/word/AddWordUseCase.kt:38-42 -
WordLocalDataSourceImpl: This class handles the direct interaction with the SQLDelight database. TheinsertWordmethod performs a series of insertions:- Inserts the base data into the
WordBaseEntitytable. - Based on the
Wordsubtype (Word.Noun,Word.Verb, etc.), it inserts the part-of-speech-specific data into the corresponding table (Noun,Verb, etc.). - Inserts all associated translations and examples into their respective tables.
Sources: data/src/main/java/com/vocabri/data/datasource/word/WordLocalDataSourceImpl.kt:43-145
- Inserts the base data into the
Part-of-Speech Specifics
The UI and data model are designed to be extensible for different parts of speech. The AddWordViewModel's saveWord function uses a when statement on the partOfSpeech from the state to construct the correct Word subclass.
// Simplified from AddWordViewModel.kt
val word = when (currentState.partOfSpeech) {
PartOfSpeech.NOUN -> Word.Noun(...)
PartOfSpeech.VERB -> Word.Verb(...)
PartOfSpeech.ADJECTIVE -> Word.Adjective(...)
PartOfSpeech.ADVERB -> Word.Adverb(...)
else -> error("Unsupported part of speech")
}
Sources: app/src/main/java/com/vocabri/ui/screens/addword/viewmodel/AddWordViewModel.kt:399-421
This logic is mirrored in the UI, where different composables are shown for each part of speech to collect the relevant data.
| Part of Speech | Specific Fields | UI Component |
|---|---|---|
| Noun | Gender, Plural Form | NounFields.kt |
| Verb | Conjugation, Management | VerbFields.kt |
| Adjective | Comparative, Superlative | AdjectiveAdverbFields.kt |
| Adverb | Comparative, Superlative | AdjectiveAdverbFields.kt |
Sources: app/src/main/java/com/vocabri/ui/screens/addword/components/NounFields.kt, app/src/main/java/com/vocabri/ui/screens/addword/components/VerbFields.kt, app/src/main/java/com/vocabri/ui/screens/addword/components/AdjectiveAdverbFields.kt
Summary
The "Add Word" feature is a well-architected component of the Vocabri app. It leverages a clean separation of concerns, a reactive MVI pattern for state management, and a flexible data model to handle various word types. The flow from user input to data persistence is clear, robust, and designed for maintainability.