Commit Graph

171 Commits

Author SHA1 Message Date
James Rich
94bcec85b3 refactor: Naming cleanup for clarity and Kotlin conventions
Audit-driven renames:
- DirectRadioControllerImpl -> RadioControllerImpl: the "Direct" prefix
  was vestigial (it once contrasted with the AIDL-routed
  AndroidRadioControllerImpl, now deleted); it is the sole impl and now
  matches its parts (AdminControllerImpl, etc.).
- RadioController.getPacketId() -> generatePacketId(): a `get`-prefixed
  function that generates a fresh id each call violates the
  getter-is-idempotent convention; also aligns with
  CommandSender.generatePacketId().
- RequestController -> QueryController (+ Impl, + the `requestController`
  params/mocks): clearer intent for the pull/query surface; "request" was
  generic.
- RequestTimer param `label` -> `logLabel`.
- AdminControllerImpl DEFAULT_REBOOT_DELAY -> DEFAULT_DELAY_SECONDS
  (shared by reboot + shutdown; conveys the unit).

Interface-consumer-safe; docs/READMEs/architecture guide updated to match.
Koin graph verifies on Android + desktop; affected test suites green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 14:37:54 -05:00
James Rich
dd6ca400c9 refactor: Decompose ServiceRepository into focused provider interfaces
Apply Interface Segregation Principle to ServiceRepository and
RadioController consumers:

New interfaces extracted from ServiceRepository:
- ConnectionStateProvider: read-only connectionState access
- TracerouteResponseProvider: traceroute response state + clear
- NeighborInfoResponseProvider: neighbor info response state + clear
- ServiceStateWriter: write-side for handlers (set*, emit*, clear*)

RadioController now extends ConnectionStateProvider, and sub-controller
interfaces (AdminController, MessagingController, NodeController,
RequestController) are bound in DI for fine-grained injection.

ViewModel narrowing:
- MessageViewModel: RadioController+ServiceRepository → MessagingController+ConnectionStateProvider
- NodeDetailViewModel: RadioController → RequestController
- NodeListViewModel: RadioController+ServiceRepository → AdminController+ConnectionStateProvider
- ContactsViewModel: ServiceRepository → ConnectionStateProvider
- MetricsViewModel: ServiceRepository → TracerouteResponseProvider

All tests updated to use narrowed interfaces. Koin DI bindings updated
for both Android (@Single binds) and Desktop (manual single<> declarations).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 12:50:28 -05:00
James Rich
b97ff4d712 refactor: Idempotent node ops (setFavorite/setIgnored) matching SDK
NodeController toggled favorite/ignore state by reading the current node
then flipping it (read-modify-write), which races concurrent callers and
forced a latent bug in SendMessageUseCase: it only ever wants to favorite
a node, but called a toggle, so a node that became favorite between the
guard and the call would have been un-favorited.

Replace with explicit-target idempotent operations mirroring the SDK's
AdminApi:

- favoriteNode(num) -> setFavorite(num, Boolean)
- ignoreNode(num)   -> setIgnored(num, Boolean)
- muteNode(num)     -> toggleMuted(num)   (mute is genuinely a firmware toggle)

Impls no-op when the node is already in the requested state. Callers
(NodeManagementActions confirm dialogs) pass !node.isFavorite from the
state the UI showed the user; SendMessageUseCase passes favorite = true.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 09:45:19 -05:00
James Rich
8ae937b063 refactor: Move RadioController interfaces to core:repository and split into focused sub-interfaces
Relocates RadioController, AdminController, MessagingController,
NodeController, and RequestController from core:model to core:repository
where they belong (alongside their consumers and the ServiceRepository
they mirror).

Splits the monolithic RadioController into 4 focused sub-interfaces
following the Interface Segregation Principle:
- AdminController: config, channels, device lifecycle
- MessagingController: send packets, reactions, contacts
- NodeController: favorite, ignore, mute, remove
- RequestController: traceroute, telemetry, position queries

RadioController remains as a composite extending all four for backward
compatibility. Feature modules can now inject the narrower interface
for better testability.

Also fixes ScannerViewModelTest by adding Dispatchers.setMain/resetMain
to match the pattern used by all other ViewModel tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 08:16:17 -05:00
James Rich
913c1a9810 fix: Address P1 code-review findings from AIDL-removal refactor
- NodeAddress.idToNum: reject >32-bit hex instead of silently truncating;
  use toLongOrNull rather than runCatching; drop redundant double prefix-strip.
- DirectRadioControllerImpl: compare destNum against the nullable
  myNodeNum.value (not the ?:0 getter) so local-side-effect branches
  don't fire spuriously for destNum=0 before connect.
- DirectRadioControllerImpl.setModuleConfig: move node_status optimistic
  write inside the local-node guard so we don't overwrite remote status.
- DirectRadioControllerImpl.sendReaction: use ContactKey wrapper instead
  of manual [0].digitToInt()/substring(1).
- DirectRadioControllerImpl.importContact: respect incoming
  manually_verified flag; early-return on node_num==0 or null user.
- DirectRadioControllerImpl.requestPosition: consolidate when-chain;
  document Position(0,0,0) as protocol "no position" sentinel.
- ContactKey: accessors safe against empty value; non-digit first char
  defaults channel to 0 rather than throwing.
- NodeDetailViewModel.openRemoteAdmin: atomic compareAndSet replaces
  check-then-act TOCTOU that allowed double-tap to queue two passkey
  exchanges + duplicate navigation events.
- MessageViewModel.frequentEmojis: toIntOrNull + mapNotNull so a
  corrupted pref entry no longer crashes every recomposition.
- AndroidMeshLocationManager.restart: log the silent-bail case
  (no-op until MeshConnectionManagerImpl wires us up).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 07:26:20 -05:00
James Rich
69883e9306 refactor: remove AIDL API and modernize radio architecture
Remove the deprecated AIDL/IPC API surface and perform deep architectural
modernization of the radio command pipeline, aligning with the meshtastic-sdk
AdminApiImpl pattern for future SDK migration.

Key changes:

1. AIDL Removal & Infrastructure Cleanup
   - Delete core:api module and all AIDL interfaces
   - Remove ServiceBroadcasts + CommonParcelable infrastructure
   - Remove core:api from CI workflow lint/publish steps

2. Model Modernization
   - Introduce NodeAddress sealed class with type-safe addressing
   - Remove deprecated DataPacket constants in favor of NodeAddress
   - Consolidate dual node maps into single source with getNodeById
   - Split large model files, deduplicate NodeEntity, flatten RadioController

3. Service Layer Refactoring (SDK-aligned)
   - Remove ServiceAction sealed class, use direct suspend calls
   - Convert CommandSender & MeshActionHandler to suspend APIs
   - Merge MeshActionHandler into DirectRadioControllerImpl
     (ViewModel → RadioController → CommandSender, no intermediate layer)
   - Build AdminMessage protos directly with typed protos end-to-end
   - Apply structured concurrency to NodeRequestActions/NodeManagementActions
   - Fix CancellationException handling throughout

Architecture (before → after):
  ViewModel → RadioController → Handler → CommandSender → PacketHandler
  ViewModel → RadioController → CommandSender → PacketHandler

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 06:37:32 -05:00
James Rich
5ec6d80f61 docs: comprehensive documentation audit and refresh (#5572)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 20:50:01 -05:00
James Rich
5d9e71da39 feat: node list density switching with compact layout and field toggles (#5444)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 17:44:48 -05:00
James Rich
a871dad7c1 chore(build): centralize feature CMP dependency wiring (#5567)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 19:02:07 +00:00
James Rich
9d5e20c742 feat: align node list context menu to canonical 6-item order (#5548)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-20 22:31:35 +00:00
James Rich
877909fa94 fix: prevent node details hang when device hardware API is unreachable (#5514)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 20:37:42 -05:00
James Rich
fc0df1a79a feat(docs): In-app documentation browser with Jekyll site and Docusaurus sync (#5445)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 04:00:22 +00:00
James Rich
f5128798a8 feat: adopt Material 3 Expressive design system (M3-native APIs only) (#5479)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 01:10:47 +00:00
James Rich
df4f10c4d6 fix(nav): remote admin nodenum + Nav3 consolidation and improvements (#5478)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 17:29:27 +00:00
James Rich
f4b6b02ace refactor(build): rename entry modules and remove DESKTOP_ONLY mode (#5476)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 12:44:12 +00:00
James Rich
dcb147163c fix: clarify position precision as ± radius (#5428) 2026-05-12 10:24:29 -05:00
James Rich
85c840de32 feat: add Compose Preview Screenshot Testing infrastructure (#5410)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 02:18:23 +00:00
James Rich
95c3bc0bce Brownfield gap remediation: 28 tasks + intro commonMain migration (#5401)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 20:10:23 +00:00
James Rich
82926fd734 feat: event firmware easter egg with ambient branding (#5354)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-04 19:37:47 +00:00
James Rich
2822290908 refactor(build): build-logic cleanup, CC safety, and detekt 2.0 upgrade (#5311) 2026-05-01 02:48:37 +00:00
James Rich
228d872f9d feat(connections): unified device list, ACCESS_LOCAL_NETWORK, transport filter chips (#5219)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-22 19:34:22 +00:00
James Rich
f14ae2643c feat(node): smoother remote-admin UX with per-node session tracking (#5217)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-22 14:21:04 -05:00
James Rich
38c2e9fb33 fix(compass): stop coarse network fixes from clobbering GPS fixes (#5200)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 14:06:19 +00:00
Copilot
7492a33cf8 Fix node-details remove action to preserve confirmation flow (#5192)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jamesarich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: James Rich <james.a.rich@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 15:59:20 +00:00
James Rich
b979663e24 refactor: consolidate metric formatting through MetricFormatter (#5169)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 17:13:01 +00:00
James Rich
90f6e21a9c fix(ui): stable LazyColumn keys, semantic roles, and content descriptions (#5168)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:24:18 +00:00
James Rich
df3b5365f9 fix(node): don't recreate Vico CartesianChartModelProducer on channel switch (#5160)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 02:40:17 +00:00
James Rich
a2763bdfeb fix(charts): apply Vico 3.1.0 best-practice audit fixes (#5138)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 02:20:33 +00:00
James Rich
72b981f73b chore: KMP audit — commonize code, centralize utilities, eliminate dead abstractions (#5133)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 02:17:50 +00:00
James Rich
bf0deef708 fix(icons): audit and correct icon migration regressions from #5030 #5040 #5056 (#5136)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 01:14:31 +00:00
James Rich
f48fc61729 feat(environment): add 1-Wire multi-thermometer (DS18B20) display support (#5130)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 00:03:24 +00:00
James Rich
3c7e1266f8 fix: truncate traceroute chart x-values to whole seconds to prevent Vico crash (#5122) 2026-04-14 11:01:03 +00:00
James Rich
e46a8296cb feat(core/ui): add safeLaunch, UiState, KMP permissions, and CMP lifecycle modernization (#5118) 2026-04-14 00:45:34 +00:00
James Rich
938a951737 refactor: leverage CMP 1.11 + Lifecycle 2.11 — v2 test API, Json privacy, dropUnlessResumed nav guards (#5112) 2026-04-13 20:02:31 +00:00
James Rich
76386e419c refactor: migrate remaining raw stateIn(WhileSubscribed) to stateInWhileSubscribed extension (#5113) 2026-04-13 20:02:06 +00:00
James Rich
39620d063b fix(nav): restore broken traceroute map navigation (#5104) 2026-04-13 12:25:21 +00:00
James Rich
a11dee42a7 test: migrate Compose UI tests from androidTest to commonTest (#5091) 2026-04-12 20:20:00 +00:00
James Rich
0441093ce8 refactor(node): move Position to last in telemetry list on node details (#5068) 2026-04-11 17:06:17 +00:00
James Rich
3794c79dae refactor: adopt M3 Expressive components from material3 1.11.0-alpha06 (#5063) 2026-04-11 02:10:03 +00:00
James Rich
a6423d0a0f feat(metrics): redesign position log with SelectableMetricCard and add CSV export to all metrics screens (#5062) 2026-04-11 01:26:26 +00:00
James Rich
37e9e2c8f0 fix(charts): hoist rememberVicoZoomState above vararg layers to prevent ClassCastException (#5060) 2026-04-11 00:05:56 +00:00
James Rich
ce32e640de fix(icons): replace outline (FILL=0) pathData with filled (FILL=1) from upstream Material Symbols (#5056) 2026-04-10 22:15:43 +00:00
James Rich
520fa717a9 refactor(metrics/map): DRY up charts, decompose MapView monoliths, add test coverage (#5049) 2026-04-10 20:54:09 +00:00
James Rich
02f6fd67b8 fix: clean up flaky, duplicated, and misplaced tests; remove redundant deps (#5048) 2026-04-10 19:46:45 +00:00
James Rich
1390a3cd4f ci: cache Robolectric SDK jars to prevent flaky SocketException failures (#5045) 2026-04-10 10:05:07 -05:00
James Rich
dba037466e refactor(icons): migrate to self-hosted VectorDrawable XMLs via MeshtasticIcons (#5030) 2026-04-10 01:35:52 +00:00
James Rich
9c0e9b82d6 feat(charts): adopt Vico best practices, add sensor data, and migrate TracerouteLog (#5026) 2026-04-09 23:44:59 +00:00
James Rich
1649e46dd5 chore(deps): remove 7 unused dependencies across modules (#5017) 2026-04-09 12:35:28 -05:00
James Rich
60cc2f4237 fix: resolve bugs across connection, PKI, admin, packet flow, and stability subsystems (#5011) 2026-04-09 13:20:06 +00:00
James Rich
51251ab16a feat(ci): shard test suite and enable JUnit 5 parallel execution (#4977) 2026-04-03 13:08:49 +00:00