Skip to main content

Overview

The Settings Module is more than a configuration panel; it is the interface where the user defines their relationship with their device. It encompasses hardware-level calibration, granular app visibility controls, psychological commitment via the “Pledge,” and robust data backup/restore mechanisms. The module is designed with a heavy emphasis on Digital Sovereignty, ensuring that all data remains local and portable while providing the user with high-fidelity tools to “rig the game” in their favor.

Architecture & Data Flow

This module follows a strict pattern. ViewModels act as orchestrators between the UI and various specialized repositories.

Key Components

1. Hardware Calibration (CalibrationViewModel)

The most technically critical part of the module. Since Android devices vary wildly in screen size and density, the CalibrationScreen allows users to match a physical object (a standard credit card) to an on-screen visual.
  • Logic: It calculates the real-world by dividing the pixel height of the user-adjusted slider by the standard physical length of an ID-1 card (3.375 inches).
  • Impact: This ensures that “10 meters of scrolling” in the app actually represents 10 physical meters on the user’s specific device.

2. App Visibility & Privacy (AppVisibilityViewModel)

Manages which installed applications are tracked.
  • Heuristics: It uses AppMetadataRepository to filter for “user-visible” apps (those with a launcher intent).
  • Optimistic Updates: When a user toggles an app’s visibility, the UI updates instantly while the persists the change to the database in the background.

3. Data Portability (ExportViewModel & ImportViewModel)

Handles the lifecycle of compressed JSON backups.
  • Phases: The system tracks BackupPhase (Idle -> Preflighting -> Writing -> Complete).
  • Performance: Uses with Dispatchers.IO to prevent UI jank during heavy database serialization.

4. The Digital Pledge (PledgeViewModel)

A behavioral psychology feature where users “sign” a commitment.
  • Visuals: Features a custom InkStampSeal component that uses drawing and haptic feedback to simulate the physical “slam” of a rubber stamp.

Operational Logic

Initialization & State Management

When the SettingsScreen loads, it observes multiple streams from the SettingsRepository. This includes:
  • Theme Engine: Dynamic switching between AppTheme palettes (e.g., CalmLavender, Midnight).
  • Permission Sync: A LifecycleEventObserver refreshes the PermissionState every time the user returns to the app from the system settings.

The “Credit Card” Calibration Algorithm

// Simplified logic from CalibrationViewModel
val dpi = (sliderPosition * sliderHeightPx / CARD_LONG_EDGE_INCHES).roundToInt()
settingsRepository.setScreenDpi(dpi)
This calculation is the foundation for all “Scroll Distance” metrics throughout the entire application.

Data Engineering & Transformation

App Metadata Synchronization

The AppMetadataRepositoryImpl performs a “Full Sync” by comparing the list of apps currently installed on the OS (via PackageManager) against the local app_metadata table.
  • Source: packageManager.getInstalledApplications.
  • Transformation: It maps system flags to determine if an app is a “System App” or “User Visible.”
  • Caching: App icons are extracted and saved to the internal filesDir/app_icons to ensure the UI remains fast and works offline.

Backup Serialization

The backup process iterates through every table in the (Scroll Sessions, App Events, Daily Insights), converts them to JSON, and streams them into a compressed GZIP file. This prevents memory spikes that would occur if the entire database were loaded into RAM at once.

Dependencies

  • Hilt: Used for across all ViewModels and Repositories.
  • Coil: Used for asynchronous loading of app icons from the internal cache.
  • Konfetti: Provides the celebratory feedback when a user completes the Pledge or unlocks Developer Mode.
  • Graphics-Shapes: Used in the AboutScreen to create the rotating “Sunny” profile shape.

Operational Edge Cases

ScenarioHandling Logic
Offline BackupThe system uses DocumentFile API to write directly to user-selected local storage (SD Card/Internal), requiring no internet.
App UninstalledAppMetadataRepository detects the missing package during sync and marks isInstalled = false in the DB but preserves the history for data integrity.
Calibration ResetSetting DPI to 0 triggers a “Not Calibrated” state, which prompts the user in the main dashboard to re-calibrate for accuracy.
Last modified on January 22, 2026