fix(feedback): deliver toasts via the Navigator overlay so they show without a Scaffold - #106
Merged
Merged
Conversation
…hosts it MagicFeedback.showSnackbar called ScaffoldMessenger.of(context).showSnackBar directly. The whole magic UI layer is Wind-based (WDiv/WText), so a view registers no Material Scaffold; showSnackBar then trips its `_scaffolds.isNotEmpty` assertion and throws. Because Magic.error/success run that path, the throw escaped the caller's own try/catch: e.g. the monitor AI-analyze step called Magic.error on a failed probe, the toast threw before analyze could return null, and the create view span forever on "Analyzing..." with no way back. Route both snackbar call sites through _showSnackBarSafely, which degrades a Scaffold-less host to a Log.warning instead of throwing. A snackbar is best-effort and the condition it reports is already logged by the caller, so it must never crash the calling flow. Live-verified: with the relay down the AI-analyze step now falls back to the input step and logs the warning instead of stalling.
… without a Scaffold Follow-up to the crash guard: snackbars/toasts were routed through ScaffoldMessenger, which needs a Material Scaffold the Wind-based magic UI never registers, so every Magic.error/success/toast was invisible (and used to crash). Render them into the router's Navigator overlay instead (navigatorKey.currentState.overlay, read from the state rather than an ancestor lookup on the navigator context, which sits above that overlay). A single non-interactive (IgnorePointer) bottom toast fades in, auto-dismisses on a timer, and is replaced by the next one. Degrades to a logged warning when no overlay is available. The default snackbar content now carries its own chrome (padding/rounding/shadow) since the SnackBar wrapper is gone. Live-verified: Magic.error now shows a visible red bottom toast in a Scaffold-less Wind view; full magic suite 1252 green.
There was a problem hiding this comment.
Pull request overview
This PR updates Magic’s UI feedback delivery so toasts/snackbars can render in Wind-only (Scaffold-less) views by using the Navigator’s overlay instead of relying on ScaffoldMessenger, preventing _scaffolds.isNotEmpty assertion failures and making feedback visible across more UI surfaces.
Changes:
- Route
MagicFeedback.showSnackbar()andMagicFeedback.toast()through a new overlay-based toast renderer (navigatorKey.currentState?.overlay). - Add a single-active-toast mechanism with an auto-dismiss timer to mimic prior “replace current snackbar” behavior.
- Update
[Unreleased]changelog notes to document the feedback delivery change.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| lib/src/ui/magic_feedback.dart | Replaces SnackBar/ScaffoldMessenger delivery with an overlay-based, auto-dismissing toast entry. |
| CHANGELOG.md | Documents the Scaffold-less toast visibility fix under [Unreleased]. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Address PR review: guard _dismissToast on OverlayEntry.mounted so a late timer never calls remove() on a detached entry; add a widget test covering the Scaffold-less overlay render, replace-previous, and clean auto-dismiss; fix a docblock typo; correct the CHANGELOG to describe the final overlay-only path.
_dismissToast removed the entry but never disposed it, leaking the entry OverlayEntry state notifier. Dispose after our own remove (which clears the overlay link dispose asserts on); the already-detached branch is left to the overlay teardown that owns it.
…ay-toast # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Magic.error/Magic.success/MagicFeedback.inforouted throughScaffoldMessenger.of(context).showSnackBar, which asserts_scaffolds.isNotEmptywhen no MaterialScaffoldhosts the view. In a Wind-built screen (no Scaffold) that assertion escaped the caller's own try/catch and stalled the flow (e.g. a monitor create's error toast threw before the create could return).Fix (2 commits)
fix(feedback): the snackbar path degrades to a logged warning when no messenger is available, instead of throwing.feat(feedback): toast delivery moves offScaffoldMessengeronto the Navigator overlay, read fromnavigatorKey.currentState.overlay(NOTOverlay.maybeOf, which sits above that overlay), as a single non-interactive auto-dismissing bottom entry.The
Magic.error/success/toastAPI surface is unchanged; only the delivery path is. Toasts now show in Wind-only views where they were previously invisible.Notes
lib/src/ui/magic_feedback.dart.[Unreleased] > Fixed.