Files
Meshtastic-Android/specs/20260513-160000-m3-expressive-adoption/data-model.md
T

3.8 KiB
Raw Blame History

Data Model: M3 Expressive Design System Adoption

Date: 2025-07-18 | Branch: 20260513-160000-m3-expressive-adoption

Overview

This feature is primarily a UI/styling upgrade with minimal data model impact. The only new persistent state is the swipe-action discoverability hint preference.

New Entities

SwipeHintPreference

Location: core/datastore (user preferences)

Field Type Default Description
hasCompletedSwipeAction Boolean false Permanently dismisses swipe hint after first successful swipe action

Storage: DataStore UserPreferences proto or preferences file (existing infrastructure).

State Transitions:

false → true  (on first successful swipe-to-action completion)

One-way flag. Never resets to false (permanent dismissal).


SwipeHintSessionState (transient)

Location: In-memory, ViewModel-scoped

Field Type Default Description
hasShownHintThisSession Boolean false Prevents repeated hint animation within same process lifecycle

Lifecycle: Resets on process death. Within a session, hint shows once per list screen visit until hasCompletedSwipeAction becomes true.


Modified Entities

AppTypography (Type.kt)

Current State: val AppTypography = Typography() — empty default

Target State: Full expressive typescale definition:

Property Value Source
displayLarge Standard M3 default (auto-emphasized by expressive theme)
displayMedium Standard M3 default
displaySmall Standard M3 default
headlineLarge Standard M3 default
headlineMedium Standard M3 default
headlineSmall Standard M3 default
titleLarge Standard M3 default
titleMedium Standard M3 default
titleSmall Standard M3 default
bodyLarge fontSize = 16.sp minimum (design standards §5)
bodyMedium fontSize = 16.sp minimum (design standards §5)
bodySmall Standard M3 default
labelLarge Standard M3 default
labelMedium Standard M3 default
labelSmall Standard M3 default

Note: Emphasized variants (displayLargeEmphasized, titleMediumEmphasized, etc.) are auto-generated by MaterialExpressiveTheme based on the standard scale. No manual definition needed.


Component State Models

SwipeToRevealState

Location: core/ui/component/SwipeToRevealBox.kt

Field Type Description
anchoredDraggableState AnchoredDraggableState<SwipeAnchor> Manages drag position and anchoring
currentAnchor SwipeAnchor Current snapped position

SwipeAnchor Enum:

enum class SwipeAnchor {
    Start,       // Resting position (0 offset)
    RevealEnd,   // Left-swipe reveals end actions
    RevealStart, // Right-swipe reveals start actions
}

Relationships

UserPreferences (DataStore)
  └── hasCompletedSwipeAction: Boolean

NodeListScreen
  ├── uses SwipeToRevealBox (per item)
  │     └── owns AnchoredDraggableState
  └── reads hasCompletedSwipeAction (via ViewModel)

MessageListScreen
  ├── uses SwipeToRevealBox (per item)
  │     └── owns AnchoredDraggableState
  └── reads hasCompletedSwipeAction (via ViewModel)

Validation Rules

Rule Constraint
bodyLarge.fontSize >= 16.sp (design standards §5 minimum)
bodyMedium.fontSize >= 16.sp (design standards §5 minimum)
Touch target minimum 44.dp × 44.dp on all interactive elements (design standards accessibility)
Swipe threshold Action reveals at ≥ 56.dp horizontal drag (comfortable thumb distance)
Swipe velocity threshold Fling detected at ≥ 400.dp/s (standard Material swipe velocity)