The in.ui.components module serves as the architectural “Design System” for the ScrollLess application. It transcends basic UI widgets by providing a collection of interactive, state-aware, and gamified components designed to make digital wellbeing data engaging.From a user perspective, this module provides the “feel” of the app: the 3D warp transitions, the reactive “PixelPet” mascot, the Tinder-style swipeable tips, and the fluid bubble charts that visualize screen time.
The module follows a strict pattern. Most components are stateless, accepting data models (like AppUsageUiItem or LimitInfo) and emitting events via lambdas.
To reduce the “clinical” feel of usage tracking, the module includes mascots:
PixelPet: A grid-based sprite that reacts to user “Moods” (Idle, Eating, Confused). It features a “Phosphor Glow” effect using RenderEffect (Android 12+).
FocusSpirit: A fluid, physics-based blob that uses paths and spring physics to “lag” behind movement, creating a jelly-like feel.
The module relies on a centralized HapticsManager provided via CompositionLocalProvider.
Slider Scrubbing: Components like the MaterialTimePickerDialog and BubbleChart use performSliderScrub, which maps a 0.0-1.0 progress value to varying haptic intensities.
Confirmation: Destructive actions (like the DestructiveCountdownButton) trigger a “Confirm” haptic only after a 5-second safety countdown.
A high-performance 3D background used in premium or transition states. It projects 2D lines into a 3D perspective using a custom projection function:
scale=1/z
This creates the illusion of moving through a digital tunnel, with “beams” that fade in from the distance (Zmax) and fly past the viewer (Znear).
The AppUsageUiItem acts as the bridge between the database and the UI.
Icon Handling: Icons are loaded as File objects (cached on disk) and rendered via the Coil library.
Normalization: The HeroAppUsageCard normalizes raw milliseconds into a “Fill Ratio” to determine bubble sizes relative to the available screen real estate.
The InteractiveCalendarHeatmap transforms a Map<LocalDate, Int> into a color-coded grid:
Luminance Interpolation: It calculates the monthMax and uses Color.lerp to interpolate between a neutral surface color and the primary theme color based on usage density.