Quick Start Guide¶
This guide provides essential information for new developers to quickly get started with the DocuSnap-Frontend project.
Key Components and Files¶
1. Entry Points¶
- MainActivity.kt: Main application entry point
- Initializes the application
- Sets up the navigation host
-
Configures dependencies
-
AppModule.kt: Dependency injection configuration
- Provides application-wide dependencies
- Configures services and repositories
- Manages singleton instances
2. Core Modules¶
- DocumentViewModel.kt: Core of document processing
- Manages document state and operations
- Handles document loading, saving, and updating
-
Coordinates with repositories for data operations
-
ImageProcessingViewModel.kt: Core of image processing
- Manages image processing state and operations
- Handles image filters and transformations
-
Coordinates with image processing services
-
BackendApiService.kt: Core of backend communication
- Manages API requests and responses
- Implements encryption and security
- Handles error cases and retries
3. Data Models¶
- Document.kt: Document data model
- Defines document structure and properties
-
Used throughout the document processing flow
-
Form.kt: Form data model
- Defines form structure and properties
-
Includes form fields and metadata
-
ExtractedInfoItem.kt: Extracted information model
- Represents extracted text or field data
- Used in both documents and forms
4. UI Components¶
- screens/: Main screen implementations
- Contains all application screens
-
Organized by feature or function
-
components/: Reusable UI components
- Contains shared UI elements
-
Used across multiple screens
-
theme/: Application theme and styles
- Defines colors, typography, and shapes
- Configures Material Design theme
Development Environment Setup¶
1. Environment Requirements¶
- Android Studio: Arctic Fox or higher
- JDK: Version 11 or higher
- Android SDK: API level 33 or higher
- Gradle: Compatible with project configuration
2. Build Steps¶
-
Clone the Repository:
git clone https://github.com/JI-DeepSleep/DocuSnap-Frontend.git cd DocuSnap-Frontend
-
Open in Android Studio:
- Launch Android Studio
- Select "Open an Existing Project"
-
Navigate to the cloned repository directory
-
Sync Gradle Files:
- Wait for the automatic sync or
-
Click "Sync Project with Gradle Files" button
-
Build and Run:
- Select a device or emulator
- Click the "Run" button or press Shift+F10
3. Debugging Tips¶
- Logcat: Use for viewing logs
- Filter by tag to focus on specific components
-
Use different log levels (DEBUG, INFO, ERROR)
-
Layout Inspector: Debug UI issues
- View component hierarchy
-
Inspect properties and constraints
-
Database Inspector: View database content
- Examine tables and records
-
Execute SQL queries for testing
-
Network Profiler: Monitor network activity
- Track API calls
- Analyze response times and data sizes
Common Development Workflows¶
1. Adding a New Screen¶
-
Create a new Composable function in the
screens/
directory:@Composable fun NewScreen( viewModel: SharedViewModel = hiltViewModel(), onNavigate: (String) -> Unit ) { // Screen implementation }
-
Add a new route in the navigation package:
object Screen { // Existing routes object NewScreen : Screen("new_screen") }
-
Register the screen in the NavHost:
NavHost( navController = navController, startDestination = startDestination ) { // Existing routes composable(Screen.NewScreen.route) { NewScreen( onNavigate = { route -> navController.navigate(route) } ) } }
2. Modifying Data Models¶
-
Update the data class definition:
@Serializable data class Document( val id: String, val name: String, // Add new fields val newField: String? = null, // Other existing fields )
-
Update corresponding database entity if needed:
@Entity(tableName = "documents") data class DocumentEntity( @PrimaryKey val id: String, val name: String, // Add new column @ColumnInfo(name = "new_field") val newField: String?, // Other existing columns )
-
Add database migration strategy:
val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE documents ADD COLUMN new_field TEXT") } }
3. Adding New Functionality¶
-
Determine which module the functionality belongs to
-
Add necessary methods to the appropriate ViewModel:
// In DocumentViewModel fun newFeature(param: String) { viewModelScope.launch { _isLoading.value = true try { val result = repository.performNewFeature(param) _featureResult.value = result } catch (e: Exception) { _error.value = "Error: ${e.message}" } finally { _isLoading.value = false } } }
-
Update the UI to support the new feature:
@Composable fun FeatureComponent(viewModel: DocumentViewModel) { val result by viewModel.featureResult.collectAsState() Column { Button(onClick = { viewModel.newFeature("param") }) { Text("Execute New Feature") } if (result != null) { Text("Result: $result") } } }
Architecture Overview¶
DocuSnap-Frontend follows the MVVM (Model-View-ViewModel) architecture pattern:
- Model: Data models and repositories
- Represents the data and business logic
-
Handles data access and storage
-
View: Jetpack Compose UI components
- Displays data to the user
-
Forwards user actions to the ViewModel
-
ViewModel: State management and business logic
- Manages UI state
- Processes user actions
- Communicates with repositories
Data flows through the application in a unidirectional pattern: - User actions in the UI trigger ViewModel methods - ViewModel processes actions and updates state - UI automatically updates to reflect the new state
Common Pitfalls and Solutions¶
1. State Management¶
Pitfall: Mutable state shared across multiple components
Solution: Use StateFlow in ViewModels and collect at the UI level:
// In ViewModel
private val _state = MutableStateFlow(initialState)
val state: StateFlow<UiState> = _state.asStateFlow()
// In UI
val state by viewModel.state.collectAsState()
2. Coroutine Scope¶
Pitfall: Using the wrong coroutine scope or not cancelling coroutines
Solution: Use the appropriate scope and ensure proper cancellation:
// In ViewModel
viewModelScope.launch {
// Long-running operation
}
// Automatically cancelled when ViewModel is cleared
// For background service
val job = CoroutineScope(Dispatchers.IO + SupervisorJob()).launch {
// Background operation
}
// Remember to cancel: job.cancel()
3. Image Processing Performance¶
Pitfall: Performing heavy image processing on the main thread
Solution: Use background dispatchers and optimize processing:
viewModelScope.launch(Dispatchers.IO) {
val processedBitmap = withContext(Dispatchers.Default) {
// Heavy image processing
imageProcService.processImage(bitmap)
}
// Update UI state on main thread
_uiState.update { it.copy(editingBitmap = processedBitmap) }
}
4. Memory Management¶
Pitfall: Memory leaks from holding references to contexts or activities
Solution: Use application context, weak references, or lifecycle-aware components:
// Use application context for long-lived objects
val imageLoader = ImageLoader(context.applicationContext)
// Use rememberCoroutineScope in Compose
val scope = rememberCoroutineScope()
This quick start guide should help new developers understand the key components of DocuSnap-Frontend and get started with common development tasks. For more detailed information, refer to the specific documentation sections on architecture, modules, and processes.