fix(node): scroll traceroute/log history detail popups - #6708
Conversation
showTracerouteDetail and showLogDetail passed MeshtasticDialog a bare
SelectionContainer { Text(...) } as composableMessage. MeshtasticDialog
only adds verticalScroll to its own wrapping column when the dialog
has choices (a button list) - a plain text dialog's scrolling is the
caller's responsibility. The live traceroute view already gets this
right; the history detail popup (and the identical showLogDetail
pattern used for e.g. neighbor-info logs) did not, so a long route
just got cut off with no way to see the rest. Fixes meshtastic#6701.
A screenshot test can't catch this: a single frame of "scrolled to
top, more below" looks identical whether scrolling actually works.
Added a behavioral test using performScrollTo(), which throws when
the target has no scrollable ancestor - confirmed it genuinely fails
against the pre-fix shape and passes against the fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
Fix itself looks right, and matching One thing on the test, and I think it's worth sorting before this comes out of draft.
I think that's also what the manual check was telling you: reverting the test to the unwrapped shape and watching it fail confirms the test notices its own copy of the shape, not that the app has it. The good news is val alertManager = AlertManager()
// ...construct the VM with it, then:
viewModel.showLogDetail(titleRes = Res.string.traceroute, annotatedMessage = longRoute)
val message = alertManager.currentAlert.value?.composableMessage
assertNotNull(message)
setContent { AppTheme { MeshtasticDialog(title = "Traceroute", text = message, onDismiss = {}) } }
onNodeWithText(LAST_HOP_MARKER, substring = true).performScrollTo().assertIsDisplayed()
No urgency on the hardware check. Holding in draft until a real multi-hop route comes back is exactly right, and worth noting the test shards have not run yet either since draft PRs skip them. |
Fixes #6701.
Why
A traceroute with many hops scrolls fine in the live/real-time result view, but the same route reopened from history is cut off with no way to see the rest.
Root cause: the shared popup component
MeshtasticDialog(core/ui/.../AlertDialogs.kt) only wraps its content in a scrollable column when the dialog haschoices(a button list). For a plain text/composableMessagedialog, scrolling is the caller's own responsibility.TracerouteAlertHandler.kt) already does this correctly - wraps itsTextinColumn(Modifier.verticalScroll(rememberScrollState())).MetricsViewModel.showTracerouteDetail(the history case) did not - just a bareSelectionContainer { Text(...) }- so long content clips inside the dialog's bounded height with no way to reach the rest.MetricsViewModel.showLogDetail(used for other detail popups, e.g. neighbor-info logs) had the exact same missing-modifier pattern, one-for-one. Not reported in the issue, but it's the identical mistake in the same file, so it's fixed in the same PR rather than left for someone to report separately.What changed
showLogDetailandshowTracerouteDetail(feature/node/.../MetricsViewModel.kt) now wrap their content inColumn(Modifier.verticalScroll(rememberScrollState())), matching the workingTracerouteAlertHandler.ktpattern exactly.MeshtasticDialog/AlertDialogs.ktitself - a shared-component-level fix (always-scrollable text content regardless ofchoices) was considered but deliberately left out of scope here, since it touches a component used by every dialog in the app and deserves its own separately-reviewed PR.Test plan
feature/node/src/jvmTest/.../DetailDialogScrollTest.kt. A static screenshot can't catch this regression - a single frame of "scrolled to top, more content below" looks identical whether or not scrolling actually works. Used a behavioral test instead:performScrollTo()throws when the target node has no scrollable ancestor, so it fails exactly when theverticalScrollwrapper is missing. Confirmed by hand: temporarily reverted the test to the pre-fix (unwrapped) shape and watched it fail with the expectedAssertionError, then restored it.spotlessApply spotlessCheck detekt assembleDebug test allTestsandkmpSmokeCompile.Not yet verified on real hardware. I have the fdroid debug build with this fix installed on a Samsung Galaxy S24+, but no nearby node has responded to a traceroute request yet to produce a fresh multi-hop result to test against. Will update here once verified against an actual long route on-device; happy to hold this in draft until then.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com