Skip to content

fix(InterfaceManagementViewModel): default add-dialog AutoInterface to wifi_only#904

Draft
torlando-agent[bot] wants to merge 1 commit into
mainfrom
columba-suite/issue-899-autointerface-defaults-any-not-wifi
Draft

fix(InterfaceManagementViewModel): default add-dialog AutoInterface to wifi_only#904
torlando-agent[bot] wants to merge 1 commit into
mainfrom
columba-suite/issue-899-autointerface-defaults-any-not-wifi

Conversation

@torlando-agent

@torlando-agent torlando-agent Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Implements the approved plan for #899.

Summary

When the user taps the FAB to add a new interface and saves without touching the network restriction selector, the persisted InterfaceConfig.AutoInterface ended up with networkRestriction = ANY instead of WIFI_ONLY. The 894 design intent ("AutoInterface defaults to Wi-Fi only — UDP multicast on cellular is meaningless and noisy") and the data class default (AutoInterface.networkRestriction = NetworkRestriction.WIFI_ONLY) were bypassed because InterfaceConfigState defaulted its string field to NetworkRestriction.ANY.value regardless of type, so the per-type fallback in configStateToInterfaceConfig never fired.

The seeded "Auto Discovery" row and the v1→v2 JSON-omission path both correctly inherit WIFI_ONLY. Only the showAddDialog() → save-without-touching-selector path was broken.

Switches InterfaceConfigState.networkRestriction to a nullable String? with sentinel-as-null. Save resolves null to the per-type default (AutoInterface → WIFI_ONLY, others → ANY); editing existing rows still seeds a non-null string from the entity, so user-picked values survive round-trips. The dialog renders via a new effectiveNetworkRestriction computed property so the segmented selector highlights the per-type default when the user hasn't picked anything.

Changes

  • app/src/main/java/network/columba/app/viewmodel/InterfaceManagementViewModel.ktInterfaceConfigState.networkRestriction: String? = null; new effectiveNetworkRestriction computed property mirroring the per-type fallback in configStateToInterfaceConfig; configStateToInterfaceConfig reads via state.networkRestriction?.let { NetworkRestriction.fromValue(it) } ?: defaultRestriction.
  • app/src/main/java/network/columba/app/ui/components/InterfaceConfigDialog.ktNetworkRestrictionSelector is fed configState.effectiveNetworkRestriction so a freshly-opened AutoInterface dialog renders "Wi-Fi only" highlighted.
  • app/src/test/java/network/columba/app/viewmodel/InterfaceManagementViewModelStatusEventTest.kt — adds the tight-assertion repro test for the showAddDialog→save path (AutoInterface saves as WIFI_ONLY) plus a paired test confirming explicit "Any" selection still persists ANY so the sentinel doesn't swallow user choices.

Test plan

  • ./gradlew :app:testNoSentryDebugUnitTest --tests "network.columba.app.viewmodel.InterfaceManagementViewModelStatusEventTest" — 29 PASSED, including the two new tests
  • ./gradlew :app:testNoSentryDebugUnitTest — full app unit suite green
  • ./gradlew ktlintCheck detekt cpdCheck --continue — BUILD SUCCESSFUL
  • ./gradlew :app:assembleNoSentryDebug — debug APK builds clean

Implementer notes

Wizards (TcpClientWizardViewModel, RNodeWizardViewModel) carry their own networkRestriction: String state independent of InterfaceConfigState; the change here does not touch them, and per the plan they were not buggy (their per-type default is ANY, which matches the wizard string default).

The plan flagged a "hotspot" pattern around 894-derived plumbing — long-term, dropping the string-typed networkRestriction on InterfaceConfigState in favor of a NetworkRestriction? would be cleaner. Out of scope here.

🤖 Generated with Claude Code

…o wifi_only

InterfaceConfigState.networkRestriction was a non-null String defaulting to
NetworkRestriction.ANY.value, regardless of the active interface type. The
per-type fallback in configStateToInterfaceConfig only fires when
NetworkRestriction.fromValue returns null, so "any" parsed cleanly and the
AutoInterface row was persisted with networkRestriction=ANY instead of the
intended WIFI_ONLY (894 design intent: UDP multicast on cellular is noise).

Switch the field to nullable with sentinel-as-null. Save resolves null to
the per-type default (AutoInterface -> WIFI_ONLY, others -> ANY); editing
existing rows still seeds a non-null string from the entity, so user-picked
values survive round-trips. Dialog renders via a new effectiveNetworkRestriction
computed property so the segmented selector highlights the per-type default
when the user hasn't picked anything.

Tests: tight-assertion repro for the showAddDialog->save path (AutoInterface
saves as WIFI_ONLY); paired test confirming explicit "Any" selection still
persists ANY so the sentinel doesn't swallow user choices.

Closes #899

Co-Authored-By: Claude claude-opus-4-7 <noreply@anthropic.com>
@sentry

sentry Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants