Meshtastic-Android/core/ui
James Rich 092238cb55 refactor: use injected ioDispatcher and ApplicationCoroutineScope
Replaces two coroutine anti-patterns flagged by the architecture audit:

* FirmwareUpdateViewModel.onCleared() was using GlobalScope.launch to
  run cleanup work that must outlive the ViewModel scope. Introduce a
  new ApplicationCoroutineScope marker interface + Koin @Single binding
  in core/common, backed by SupervisorJob() + ioDispatcher, and inject
  it into the VM. NonCancellable is preserved so shutdown work still
  cannot be interrupted. Verified end-to-end by the KoinVerificationTest
  full-graph check.
* Six sites in feature/settings (android+jvm LogExporter/PrefExporter)
  and core/ui (android+jvm PlatformUtils) were hardcoding Dispatchers.IO.
  Switch to the project's injectable ioDispatcher property so tests
  can substitute a test dispatcher without reflection.

Dispatchers.Main sites in LogExporter are intentionally left alone —
they are fully test-swappable via Dispatchers.setMain() and there is
no existing mainDispatcher property to inject.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 10:53:08 -05:00
..
src refactor: use injected ioDispatcher and ApplicationCoroutineScope 2026-04-17 10:53:08 -05:00
build.gradle.kts refactor: modern APIs — Koin 4.2, CMP 1.11, Ktor resilience, Room @Upsert, injected dispatchers (#5119) 2026-04-14 11:41:01 +00:00
detekt-baseline.xml refactor: migrate core UI and features to KMP, adopt Navigation 3 (#4750) 2026-03-10 17:29:47 +00:00
README.md refactor: BLE transport and UI for Kotlin Multiplatform unification (#4911) 2026-03-25 02:15:51 +00:00

:core:ui

Overview

The :core:ui module contains shared Jetpack Compose components, themes, and utility functions used across the entire Meshtastic Android application. It ensures a consistent look and feel following Material 3 guidelines.

Key Components

1. Alert Dialogs (org.meshtastic.core.ui.component.AlertDialogs.kt)

  • MeshtasticDialog: The base dialog component for all alerts.
  • MeshtasticResourceDialog: Optimized for dialogs with resource-only content.
  • MeshtasticTextDialog: Optimized for dialogs with mixed resource and raw text content.

2. Common UI Elements

  • LastHeardInfo: Displays when a node was last seen.
  • TelemetryInfo: Displays battery, voltage, and other telemetry data.
  • TransportIcon: Shows the connection type (BLE, USB, TCP).
  • MainAppBar: The standard top app bar used in the app.

3. Preferences

Standardized Material 3 preference components for settings screens:

  • RegularPreference
  • SwitchPreference
  • DropDownPreference
  • SliderPreference
  • EditTextPreference

4. Utilities

  • ModifierExtensions.kt: Useful Compose Modifiers (e.g., conditional modifiers).
  • ProtoExtensions.kt: Extensions for mapping Protobuf models to UI-friendly strings or icons.

Usage

Most components are designed to be used with the Compose Multiplatform Resource library for strings.

import org.meshtastic.core.ui.component.MeshtasticResourceDialog
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.ok

MeshtasticResourceDialog(
    title = Res.string.your_title,
    message = Res.string.your_message,
    onDismissRequest = { /* ... */ },
    confirmButtonText = Res.string.ok
)

Module dependency graph

graph TB
  :core:ui[ui]:::kmp-library-compose

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;