Settings & Onboarding Flow
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/onboarding/OnboardingScreen.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/onboarding/OnboardingViewModel.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsScreen.kt
- app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsViewModel.kt
- app/src/main/kotlin/com/fathiraz/flowbell/MainActivity.kt
- app/src/main/kotlin/com/fathiraz/flowbell/domain/usecases/ManageUserSettingsUseCase.kt
- app/src/main/kotlin/com/fathiraz/flowbell/data/local/preferences/DataStoreManager.kt
Introduction
The Settings and Onboarding flow in FlowBell manages the initial user experience and the ongoing configuration of notification forwarding preferences. The onboarding process guides new users through the application's core value propositions, including app monitoring, webhook security, and privacy-first data handling. Once completed, the settings module allows for granular control over the app's appearance, debug tools, and advanced notification filtering.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/onboarding/OnboardingScreen.kt:42-65, app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsScreen.kt:76-248
System Architecture & Data Flow
The flow is driven by a reactive architecture using Jetpack Compose for the UI, ViewModels for state management, and DataStoreManager for persistent storage. The MainActivity acts as the primary orchestrator, determining which screen to display based on the user's current state.
Core Components
| Component | Responsibility |
|---|---|
MainActivity | Orchestrates the transition between Splash, Onboarding, Permission, and the main App container. |
OnboardingViewModel | Manages the state of the onboarding process and persists completion status. |
SettingsViewModel | Handles user preference updates including theme toggles and notification filters. |
DataStoreManager | Provides the low-level persistence layer for user preferences with Samsung-specific fallbacks. |
ManageUserSettingsUseCase | Encapsulates business logic for preference updates. |
Sources: app/src/main/kotlin/com/fathiraz/flowbell/MainActivity.kt:66-125, app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsViewModel.kt:38-51, app/src/main/kotlin/com/fathiraz/flowbell/data/local/preferences/DataStoreManager.kt:40-47
Initial Launch Orchestration
The following flowchart illustrates the logic used by MainActivity to determine the initial user destination upon application startup.
The application uses handleFreshInstallIfNeeded to ensure a clean state by checking version codes in SharedPreferences before proceeding to onboarding checks.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/MainActivity.kt:66-125, app/src/main/kotlin/com/fathiraz/flowbell/data/local/preferences/DataStoreManager.kt:254-282
Onboarding Experience
The onboarding flow consists of a four-page HorizontalPager that introduces the user to FlowBell's features.
Onboarding Stages
- Welcome: Introduction to secure notification forwarding.
- App Monitoring: Explains the ability to select specific applications.
- Secure Webhooks: Details the security and retry mechanisms for endpoints.
- Privacy First: Assures the user that data remains on-device.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/onboarding/OnboardingScreen.kt:42-65
Onboarding State Management
The OnboardingViewModel tracks the completion status. When the user clicks "Get Started" or "Skip," the completeOnboarding function is invoked, which updates the UserPreferences repository.
Settings Configuration
The settings module provides a comprehensive interface for managing the UserPreferences entity.
Configuration Options
| Feature | Type | Description |
|---|---|---|
ThemeMode | Enum | Toggles between Light, Dark, or System default themes. |
Advanced Filters | Boolean | Enables or disables global keyword-based notification filtering. |
Keyword Filters | List | A comma-separated list of strings used to filter incoming notifications globally. |
Debug Mode | Boolean | Toggles the visibility of developer tools (Beagle, Chucker) on the dashboard. |
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsViewModel.kt:18-26, app/src/main/kotlin/com/fathiraz/flowbell/domain/usecases/ManageUserSettingsUseCase.kt:46-72
Notification Filtering Logic
When "Advanced Filters" are enabled, users can input comma-separated keywords. The SettingsViewModel processes this input by splitting the string, trimming whitespace, and filtering out blank entries before persisting the list to storage.
Sources: app/src/main/kotlin/com/fathiraz/flowbell/presentation/screens/settings/SettingsViewModel.kt:133-157
Persistent Storage Architecture
FlowBell uses DataStore with a specialized implementation to handle hardware-specific issues, particularly on Samsung devices.
Samsung Compatibility Layer
The DataStoreManager includes a fallbackPrefs (standard SharedPreferences) used for critical data like the Webhook URL. If the DataStore write fails (common on some eMMC storage modules), the system attempts a synchronous commit() to the fallback storage.
// Example of fallback logic in DataStoreManager
suspend fun updateWebhookUrl(url: String): Result<Unit> {
return try {
dataStore.edit { preferences -> preferences[WEBHOOK_URL] = url }
// Sync to fallback for reliability
fallbackPrefs.edit().putString("webhook_url_fallback", url).apply()
Result.success(Unit)
} catch (exception: IOException) {
// Fallback to SharedPreferences if DataStore fails
fallbackPrefs.edit().putString("webhook_url_fallback", url).commit()
Result.success(Unit)
}
}
Sources: app/src/main/kotlin/com/fathiraz/flowbell/data/local/preferences/DataStoreManager.kt:100-142
Summary
The Settings & Onboarding flow ensures that FlowBell is both user-friendly for new adopters and highly configurable for power users. By combining reactive UI state with a robust, multi-layered persistence strategy, the system maintains reliability across various Android hardware environments while providing granular control over notification traffic.