Skip to main content

Overview

The Insights module is the analytical heart of the application. It serves to bridge the gap between raw telemetry (scroll distance, unlock timestamps, notification counts) and human-readable “User Stories.” Instead of just showing numbers, it identifies patterns like “Digital Rush Hour” or “Morning Habits” to help users understand their relationship with their devices. From a user perspective, this feature manifests as a dashboard of cards, interactive charts, and a sophisticated for notification analysis.

Architecture & Data Flow

The module follows a strict pattern, leveraging to maintain a single source of truth for the UI.

Key Components

1. The Logic Hub: InsightsViewModel

The InsightsViewModel acts as a data orchestrator. It doesn’t just fetch data; it performs complex joins between usage records and app metadata.
  • State Management: It manages multiple streams including insightCards (the dashboard), dailyInsights (high-level stats), and treemapState (notification distribution).
  • Date Reactivity: It uses flatMapLatest to automatically re-trigger all data pipelines whenever the user selects a different date via the DatePickerModal.

2. The Narrative Engine: TrendAnalyzer

This is a pure-logic component that takes a 7-day history of a specific metric and synthesizes a TrendSummary. It determines if a user’s behavior is “Increasing,” “Decreasing,” or “Stable,” and assigns a “Good/Bad” interpretation (e.g., a decrease in “Total Scroll” is interpreted as a positive trend).

3. Visual Components

  • Notification Treemap: A custom-built visualization that uses a Squarified Treemap Algorithm to allocate screen real estate to app categories based on notification volume.
  • Premium Charts: A suite of -based components including SparklineChart, ScatterChart (for timing patterns), and FocusGauge.

Operational Logic

Initialization & Pre-fetching

To ensure “Zero-Lag” interactions, the InsightsViewModel initiates a background upon creation to pre-calculate historical data for all potential insights. This data is stored in a ConcurrentHashMap (the detailCache), allowing bottom sheets to open instantly without showing loading spinners.

State Transformation Pipeline

The transformation from raw DB records to UI models is a multi-stage process:
  1. Fetch: Retrieve DailyInsight and DailyAppUsageRecord from the .
  2. Map: Associate package names with AppMetadata to retrieve icons and localized names.
  3. Analyze: Pass the 7-day window to TrendAnalyzer.
  4. Synthesize: Package everything into a InsightCardUiModel (e.g., CompulsiveCheck, TimePattern, or AppStat).

Data Engineering & Transformation

Source Data

The feature relies on several underlying structures:
  • Unlock Sessions: Used to calculate “Meaningful Unlocks” vs “Glances.”
  • Scroll Data: Aggregated pixels/units scrolled per app.
  • Notification Events: Counts of posted vs dismissed notifications.

The Treemap Algorithm

The NotificationTreemap implements a recursive layout strategy:
  1. Normalization: Areas are scaled to fit the total available pixel area.
  2. Squarification: The algorithm attempts to keep the aspect ratio of rectangles as close to 1:1 as possible to avoid thin, unreadable “slivers.”
  3. Tiered Rendering: Depending on the resulting rectangle size, the UI switches between HERO, COMPACT, and MINIMAL layouts to ensure text remains legible.

Dependencies

The module is built with modern Android standards and relies on:
  • Hilt: For of repositories and DAOs.
  • Room: For local persistence of usage and app metadata.
  • Coil: For asynchronous loading of app icons from the internal filesystem.
  • Material 3: Specifically utilizing the Expressive API for shapes and the Carousel component for daily highlights.
// Example of the reactive pipeline in the ViewModel
val insightCards: StateFlow<List<InsightCardUiModel>> = _selectedDateString.flatMapLatest { dateStr ->
    combine(
        scrollDataRepository.getInsightsForDate(dateStr),
        scrollDataRepository.getAppUsageForDate(dateStr),
        // ... other data sources
    ) { insights, usage ->
        buildUiModelsFromInsights(insights, usage, dateStr)
    }
}
Last modified on January 22, 2026