Skip to content

fix(festival-selector): avoid GoRouterState.of() inside gesture callback - #241

Merged
richardthe3rd merged 1 commit into
mainfrom
fix/festival-switch-freeze
May 10, 2026
Merged

fix(festival-selector): avoid GoRouterState.of() inside gesture callback#241
richardthe3rd merged 1 commit into
mainfrom
fix/festival-switch-freeze

Conversation

@richardthe3rd

Copy link
Copy Markdown
Owner

Calling GoRouterState.of(context) from an onTap handler causes a complete app freeze when a notifyListeners() continuation is pending on the Dart microtask queue at tap time — reproduces reliably when switching festivals immediately after data finishes loading.

Fix: capture the current path in showFestivalBrowser() before the modal opens, where it is safe to call InheritedWidget lookups, and pass it as a constructor parameter to FestivalSelectorSheet.

Calling GoRouterState.of(context) from an onTap handler causes a
complete app freeze when a notifyListeners() continuation is pending
on the Dart microtask queue at tap time — reproduces reliably when
switching festivals immediately after data finishes loading.

Fix: capture the current path in showFestivalBrowser() before the
modal opens, where it is safe to call InheritedWidget lookups, and
pass it as a constructor parameter to FestivalSelectorSheet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@richardthe3rd
richardthe3rd marked this pull request as ready for review May 10, 2026 07:58
Copilot AI review requested due to automatic review settings May 10, 2026 07:58
@github-actions

Copy link
Copy Markdown
Contributor

LCOV of commit c2a4bd6 during CI #108

Summary coverage rate:
  lines......: 78.3% (2321 of 2966 lines)
  functions..: no data found
  branches...: no data found

Files changed coverage rate:
                                                      |Lines       |Functions  |Branches    
  Filename                                            |Rate     Num|Rate    Num|Rate     Num
  ==========================================================================================
  lib/providers/beer_provider.dart                    | 0.0%    222|    -     0|    -      0
  lib/services/beer_api_service.dart                  | 0.0%     43|    -     0|    -      0
  lib/widgets/festival_menu_sheets.dart               | 0.0%    176|    -     0|    -      0

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an app freeze triggered by calling GoRouterState.of(context) inside the festival selection tap handler by capturing the current route before opening the festival selector modal and passing it into the sheet.

Changes:

  • Capture the current route path in showFestivalBrowser() and pass it into FestivalSelectorSheet to avoid GoRouterState.of() during the festival card onTap.
  • Update festival selection routing logic to preserve the user’s current tab (favorites vs home) based on the captured path.
  • Minor comment-only cleanup in BeerApiService and BeerProvider.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/widgets/festival_menu_sheets.dart Captures current route before modal opens and uses it to decide whether to navigate to /favorites on festival switch, avoiding GoRouterState.of() during tap.
lib/services/beer_api_service.dart Comment-only cleanup in error tracking logic.
lib/providers/beer_provider.dart Comment-only cleanup in setFestival.

Comment on lines +11 to +16
// Capture current route before opening modal — GoRouterState must not be
// accessed inside an onTap handler (gesture callbacks are not build phase).
String? currentPath;
try {
currentPath = GoRouterState.of(context).uri.path;
} catch (_) {
Comment on lines +204 to 211
// Preserve user's tab: if on favorites, stay on favorites.
// currentPath was captured before the modal opened to avoid
// calling GoRouterState.of() inside a gesture callback,
// which can cause a freeze during active widget rebuilds.
String targetPath = buildFestivalHome(festival.id);
try {
final currentPath = GoRouterState.of(context).uri.path;
// Preserve user's tab: if on favorites, stay on favorites
if (currentPath.endsWith('/favorites')) {
targetPath = buildFavoritesPath(festival.id);
}
} catch (e) {
// GoRouterState unavailable (e.g., in tests), keep default path
debugPrint('Festival selector: Unable to get current route, using default: $e');
if (currentPath?.endsWith('/favorites') == true) {
targetPath = buildFavoritesPath(festival.id);
}
@codecov

codecov Bot commented May 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 40.00000% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lib/widgets/festival_menu_sheets.dart 40.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Cloudflare Pages Preview

Your preview deployment is ready!

Preview URL: https://fix-festival-switch-freeze.staging-cambeerfestival.pages.dev

This preview will be automatically updated when you push new commits to this PR.

@richardthe3rd
richardthe3rd merged commit b20dbcf into main May 10, 2026
14 of 15 checks passed
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.

2 participants