The Old Onboarding module serves as the first touchpoint for new users. It is designed as a narrative journey that transitions from high-level value propositions (mindful usage) to technical setup (permissions). The module uses a to create a guided, step-by-step experience.The feature’s primary goals are:
Education: Explaining the difference between “mindless scrolling” and “intentional usage.”
Trust Building: Using premium animations (Pixel Grids, Typewriter effects) to establish app quality.
System Integration: Guiding the user through complex Android required for the app’s core tracking functionality.
The module follows a strict pattern. The OnboardingScreen acts as the state consumer, while the SettingsViewModel orchestrates logic across multiple repositories.
The onboarding flow is not strictly linear. The pageCount is dynamically calculated based on the mandatoryPermissionsGranted state.
Gating: If mandatory permissions (Usage Stats, Accessibility, Notification Listener) are not granted, the user is blocked from reaching the “Final Page.”
Lifecycle Awareness: The UI uses a LifecycleEventObserver to trigger viewModel.refreshPermissionStatus() every time the user returns to the app from the System Settings screens.
The module performs several critical data operations during the transition from onboarding to active usage:
State Mapping: The SettingsViewModel transforms raw repository flows into UI-ready states using the stateIn operator. For example, calibrationStatusText is derived by mapping the screenDpi flow to a human-readable string.
Historical Backfilling: When the Usage Stats permission is granted, the system detects a KEY_FORWARD_FILL_PENDING flag in SharedPreferences. It then triggers scrollDataRepository.backfillHistoricalAppUsageData(7), which pulls the last 7 days of usage data into the local database.
Reactive Cleanup: Upon completion, setOnboardingCompleted(true) is called, which persists the state in the SettingsRepository (likely backed by DataStore), ensuring the user never sees the onboarding flow again.
Animation Optimization: The PixelGridAnimation uses a custom Canvas implementation with a time-based infiniteTransition. It calculates dot positions and “Matrix-style” rain patterns using math functions (sin, cos) rather than heavy object allocation to maintain 60FPS.
Haptic Feedback: The module utilizes a centralized HapticsManager to perform different types of feedback (Confirm, Tick, Heavy) depending on the importance of the user action.
Memory Management: The KonfettiView on the final page is only active when the page is visible, preventing unnecessary CPU usage on background pages.