Presentation Layer
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/java/com/musagenius/ocrapp/MainActivity.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/ocr/OCRResultScreen.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/OCRViewModel.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Theme.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Color.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Type.kt
- app/src/main/res/values/strings.xml
The Presentation Layer is responsible for displaying the application's user interface and handling user interactions. It is built entirely with Jetpack Compose and follows the Model-View-ViewModel (MVVM) architecture. This layer is decoupled from the business logic (Domain Layer) and data handling (Data Layer), interacting with them primarily through ViewModels.
Key responsibilities include defining UI components (Composables), managing UI state, handling navigation, and applying the Material Design 3 theme. The entry point for the UI is MainActivity, which sets up the navigation graph and the overall theme for the application.
Architecture
The Presentation Layer uses a standard MVVM pattern.
- Views (Composables): Stateless or stateful composable functions that render the UI. They observe state from the ViewModel and delegate user events to it. Examples include
OCRResultScreenandCameraScreen. - ViewModels: Classes like
OCRViewModelhold and manage UI-related data in a lifecycle-conscious way. They expose UI state viaStateFlowand receive events from the UI to trigger business logic in the Domain Layer. - UI State: Data classes (e.g.,
OCRUiState) that model the information to be displayed on the screen. - Navigation: Managed by Jetpack Navigation Compose, with routes and arguments defined for each screen.
This diagram illustrates the high-level interaction within the presentation layer and its connection to the domain layer.
Navigation
Navigation is handled by NavHost from Navigation Compose, configured in MainActivity.kt. The app defines several screens and the navigation paths between them.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:50-151
Navigation Graph
The OCRAppNavigation composable sets up the navigation graph. The start destination is the Camera screen.
This diagram shows the flow between the main screens as defined in the navigation host.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:54-151
Screen Definitions
The navigation routes are defined using a Screen object, which provides type-safe routes and argument handling. Although the Screen.kt file is not provided, its usage in MainActivity.kt implies a structure for defining routes and creating paths with arguments.
| Screen | Route Template | Purpose |
|---|---|---|
Camera | camera | The entry point of the app for capturing images. |
ImageEditor | image_editor/{imageUri} | Allows editing an image selected from the gallery before OCR. |
Results | results/{imageUri} | Displays the extracted text and other metadata from the OCR process. |
History | history | Placeholder for viewing past scans (planned for Phase 4). |
Settings | settings | Placeholder for app settings (planned for Phase 5). |
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:56-128
Navigation from the CameraScreen to the ResultsScreen involves passing the URI of the captured image as an argument. The URI is encoded to be safely passed in the route.
// From CameraScreen
navController.navigate(Screen.Results.createRoute(imageUri.toString()))
// In NavHost for ResultsScreen
val decodedUriString = Uri.decode(encodedUriString)
val imageUri = Uri.parse(decodedUriString)
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:62, app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:123-124
UI Components and State
OCRViewModel and OCRUiState
The OCRViewModel manages the state for the OCRResultScreen. It uses a MutableStateFlow of OCRUiState to represent the screen's state.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/OCRViewModel.kt
The OCRUiState data class holds all the necessary information to render the results screen.
| Field | Type | Description |
|---|---|---|
isProcessing | Boolean | true if OCR is in progress. |
imageUri | Uri? | The URI of the image being processed. |
extractedText | String | The text extracted by the OCR engine. |
confidenceScore | Float | The confidence score of the OCR result (0.0 to 1.0). |
processingTimeMs | Long | The time taken for the OCR process in milliseconds. |
error | String? | An error message if the process fails. |
isSaved | Boolean | true if the result has been saved to the history. |
language | String | The language used for OCR. |
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/ocr/OCRUiState.kt (inferred from OCRViewModel.kt)
OCR Result Screen (OCRResultScreen.kt)
This screen observes the OCRUiState from the OCRViewModel and displays different content based on the state:
- Processing View: A
CircularProgressIndicatoris shown whenisProcessingis true. - Error View: An error message and a "Retry" button are shown when
erroris not null. - Result Content: The captured image, extracted text, and action buttons (Copy, Share, Save) are displayed upon successful OCR.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/ocr/OCRResultScreen.kt:47-75
The following sequence diagram shows the flow of processing an image and displaying the result.
Theming
The application uses Material Design 3 for its styling. The theme is configured in the com.musagenius.ocrapp.presentation.ui.theme package.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Theme.kt, app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Color.kt, app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Type.kt
Color Scheme
The app defines separate color palettes for light and dark themes in Color.kt. It also supports dynamic color theming on Android 12+ by using dynamicDarkColorScheme and dynamicLightColorScheme.
// In Theme.kt
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Theme.kt:76-85, app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Color.kt
Typography
A full Material 3 type scale is defined in Type.kt, specifying TextStyle for different text appearances like displayLarge, headlineMedium, bodyLarge, etc. This ensures consistent typography throughout the app.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/theme/Type.kt:8-107
String Resources
User-facing strings are externalized in app/src/main/res/values/strings.xml, allowing for easy localization and management of UI text. This includes labels for navigation items, buttons, and messages.
Sources: app/src/main/res/values/strings.xml
Summary
The presentation layer of the OCR app is a modern, well-structured implementation using Jetpack Compose and MVVM. It effectively separates UI rendering from state management and business logic. Navigation is centrally managed, and the UI state is clearly defined and observed. The use of Material Design 3 with dynamic color support provides a modern and adaptable user experience. The layer is designed to be extensible, with placeholders for future features like History and Settings screens.