Skip to content

fix(connections): open the region picker directly from the region card - #6743

Merged
jamesarich merged 2 commits into
mainfrom
fix/6586-region-dialog-skip-progress
Aug 17, 2026
Merged

fix(connections): open the region picker directly from the region card#6743
jamesarich merged 2 commits into
mainfrom
fix/6586-region-dialog-skip-progress

Conversation

@jamesarich

@jamesarich jamesarich commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Fixes #6586

Tapping the "Set your region" card on Connections showed a brief spinner and then an empty dialog with only a Close button, instead of opening the region picker. Settings → LoRa → Region was unaffected, which is the workaround users found.

The card did not navigate. It called radioConfigViewModel.setResponseStateLoading(ConfigRoute.LORA) and put up a PacketResponseStateDialog, navigating to SettingsRoute.LoRa only from that dialog's onComplete. Two things made that unreliable:

  • LORA is a fan-out route (hasReadFanOut = true) — it issues getChannel(0) and getConfig(LORA_CONFIG) — but the generic is ConfigRoute -> branch leaves Loading.total at its default of 1, unlike CHANNELS and AdminRoute, which call setResponseStateTotal(...).
  • PacketResponseStateDialog fires onComplete() from inside composition (if (state.completed >= state.total) onComplete()), so it only navigates if a composition happens to observe the completed Loading state.

Once the last request id is removed, completePacketResponse calls clearPacketResponse(), which resets responseState to Empty. If both admin responses land before a composition observes the completed Loading state, the dialog composes straight to Empty — a blank body with a Close button, and onComplete can never fire again. That is the reported screenshot.

Note this is why simply adding the missing setResponseStateTotal(2) is not a fix: clearPacketResponse() is unconditional for non-Admin routes, so Empty is always the terminal state and the navigation would still be racing it, just at completed >= 2 instead of >= 1.

The dialog was never load-bearing here. configComposable already calls viewModel.loadConfigRoute(routeInfo) on entry, and LoRaConfigScreen/RadioConfigScreenList render from the connect-time snapshot while that refresh runs (the overlay is suppressed for local settings, and the dialog only appears for Success/Error). settingsRadioConfigSession() already names "Connections -> LoRa" as a supported direct entry. Worse, the Connections screen's RadioConfigViewModel was an unparameterised koinViewModel() — a different instance from the keyed one the Settings graph builds — so the fetch it was waiting on did not benefit the destination screen anyway.

Changes:

  • ConnectionsScreen: the "Set your region" card navigates directly with onConfigNavigate(SettingsRoute.LoRa).
  • Removed the now-dead isWaiting / PacketResponseStateDialog block, the radioConfigState collection, and the radioConfigViewModel parameter (plus the matching argument in ConnectionsNavigation).

On the happy path the user-visible result is identical to what the old onComplete did when it won the race — the same destination, minus the dialog.

Not covered by this PR

  • The second report on the thread (button missing entirely on a fresh 2.8.0 flash) is out of scope. This change touches only the card's onClick; its visibility gate — uiState == ConnectionUiState.CONNECTED_WITH_NODE && regionUnset && sessionAuthorized && isPhysicalDevice — is untouched, so that report is neither fixed nor made worse here. sessionAuthorized being false on a not-yet-authorised node is the likely cause and wants its own fix.
  • ChannelScreen's ModemPresetInfo tap has the same defect (setResponseStateLoading(ConfigRoute.LORA) behind the same dialog). Left alone deliberately: it shares onComplete/getNavRouteFrom with the channel-edit path, which has a legitimate multi-fetch progress at total = maxChannels + 1. Worth a follow-up.

Testing

No automated test added: this deletes a code path rather than adding logic, and the only assertion left to make (a click navigates) would need a runComposeUiTest over ConnectionsScreen with the full Koin graph and ~15 backing flows stubbed. Verified via the repo baseline (spotlessApply spotlessCheck detekt kmpSmokeCompile assembleDebug test allTests).

Summary by CodeRabbit

  • New Features

    • Region selection now opens LoRa settings directly for a faster configuration flow.
    • Modem preset selection now navigates directly to the LoRa settings screen.
  • Bug Fixes

    • Removed unnecessary loading and response dialogs during radio configuration navigation.
    • Simplified connections navigation to provide a more consistent experience.

The "Set your region" card did not navigate itself: it fired
setResponseStateLoading(ConfigRoute.LORA) and showed a
PacketResponseStateDialog, reaching SettingsRoute.LoRa only from that
dialog's onComplete. LORA is a fan-out route (getChannel + getConfig) but
the generic ConfigRoute branch leaves Loading.total at 1, and onComplete
fires from inside composition. Once the last request id is removed,
completePacketResponse calls clearPacketResponse() and resets the state to
Empty, so when both admin responses land before a composition observes the
completed Loading state the dialog composes straight to Empty - a blank
body with only a Close button, and onComplete can never fire again.

Adding the missing setResponseStateTotal(2) would not fix it, because
clearPacketResponse() is unconditional for non-Admin routes and Empty is
always the terminal state; the navigation would still be racing it.

The dialog bought nothing anyway: configComposable already calls
loadConfigRoute on entry and LoRaConfigScreen renders from the connect-time
snapshot while that refresh runs. The Connections screen also used an
unparameterised RadioConfigViewModel - a different instance from the keyed
one the Settings graph builds - so its fetch never reached the destination.

Navigate straight to SettingsRoute.LoRa and drop the dead dialog, its state
collection and the now-unused view model parameter.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the bugfix PR tag label Aug 16, 2026
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 509a191b-a23c-4006-862a-2f51416dbab9

📥 Commits

Reviewing files that changed from the base of the PR and between 07b5a8d and cd58910.

📒 Files selected for processing (5)
  • feature/connections/README.md
  • feature/connections/build.gradle.kts
  • feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt
  • feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
  • feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelScreen.kt
💤 Files with no reviewable changes (2)
  • feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt
  • feature/connections/build.gradle.kts

Included review availability: Your plan includes up to 4 reviews per rolling hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The connections feature removes its radio configuration dependency and view-model injection. Region setup and modem preset actions now navigate directly to SettingsRoute.LoRa, avoiding configuration requests and response dialogs.

Changes

Connections navigation cleanup

Layer / File(s) Summary
Connections route cleanup
feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt, feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt, feature/connections/build.gradle.kts, feature/connections/README.md
ConnectionsScreen no longer receives RadioConfigViewModel. Region setup navigates directly to SettingsRoute.LoRa. The unused settings dependency and related documentation are removed.
Channel preset navigation
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelScreen.kt
Modem preset selection navigates directly to SettingsRoute.LoRa without opening a loading dialog or requesting LoRa configuration.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to cd589

The region card now opens the LoRa region settings directly instead of relying on the unreliable intermediate dialog; no actionable merge-blocking risk remains after normal checks and review.

Possibly related PRs

Suggested reviewers: jeremiah-k, rcgv1

🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Regression Coverage For Changed Behavior ⚠️ Warning ConnectionsScreen’s region card and ChannelScreen’s ModemPresetInfo now navigate directly, but no UI test covers either click; existing tests cover only share state and navigation helpers. Add JVM Compose UI tests with connected/region-unset state and fake callbacks. Click each control and assert immediate SettingsRoute.LoRa navigation before any radio response; both must fail on the parent.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary fix: direct navigation from the Connections region card to the region picker.
Linked Issues check ✅ Passed The PR fixes issue [#6586] by replacing the blank-dialog flow with direct navigation to the LoRa region picker.
Out of Scope Changes check ✅ Passed The changes remain related to the navigation fix and its cleanup, including the identical ChannelScreen flow and dependency documentation.
Sibling Call Sites And Presence Semantics ✅ Passed The PR diff only changes navigation, dialog removal, and a module dependency; it does not alter nullable fields, zero-guards, or presence semantics.
Tests Prove The Path, Not The End State ✅ Passed The complete PR diff changes five non-test files and adds no test constructs, so no test can violate the path-versus-end-state criteria.
Moved Code Diffed Against Its Original ✅ Passed The PR does not move or extract a type/function; it removes dialog logic and changes two click callbacks. The only ConnectionsScreen caller removes the deleted parameter.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Same defect as the region card this PR already fixed: the progress
dialog can strand the user on an empty state when the admin read
completes before the dialog observes it. Also drops the now-unused
feature:settings dependency from feature:connections and regenerates
its README dependency graph.
@jamesarich

Copy link
Copy Markdown
Collaborator Author

Follow-up per adversarial review: the ModemPresetInfo tap in ChannelScreen had the identical #6586 bug (progress dialog + setResponseStateLoading(ConfigRoute.LORA)), and the fix was already available via the existing onNavigate callback — no reason to leave it out of scope. Applied the same direct-navigation fix there.

Also removed the now-dead feature:settings dependency from feature/connections/build.gradle.kts (no longer referenced anywhere in the module) and regenerated the module's README dependency graph, which was still documenting the removed RadioConfigViewModel injection.

Full baseline (spotlessApply/spotlessCheck/detekt/assembleDebug/test/allTests) green. No UI/rendering change (behavior-only onClick swap), so no screenshot goldens needed regeneration.

@jamesarich
jamesarich marked this pull request as ready for review August 17, 2026 13:57
@jamesarich

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@jamesarich

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor
❌ Action failed

Review failed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@jamesarich
jamesarich added this pull request to the merge queue Aug 17, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Aug 17, 2026
@jamesarich
jamesarich added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit b70f57b Aug 17, 2026
15 checks passed
@jamesarich
jamesarich deleted the fix/6586-region-dialog-skip-progress branch August 17, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix PR tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Blank dialog appears when tapping "Set your region" on the Connection screen

1 participant