Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions lib/providers/beer_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,12 @@ class BeerProvider extends ChangeNotifier {
_error = null;
notifyListeners();

// Log analytics event
await _analyticsService.logFestivalSelected(festival);

// Persist festival selection only if requested
if (persist) {
await _festivalRepository?.setSelectedFestivalId(festival.id);
}

// Load drinks for the new festival (loadDrinks will call notifyListeners when done)
await _loadDrinksInternal();
}

Expand Down
1 change: 0 additions & 1 deletion lib/services/beer_api_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class BeerApiService {
try {
return await fetchDrinks(festival, beverageType);
} catch (e) {
// Track the error for this beverage type
errors[beverageType] = e.toString();
return <Drink>[];
}
Expand Down
38 changes: 24 additions & 14 deletions lib/widgets/festival_menu_sheets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@ import '../utils/utils.dart';
/// Shows the festival browser/selector as a modal bottom sheet
void showFestivalBrowser(BuildContext context) {
final provider = context.read<BeerProvider>();
// 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 +11 to +16
// GoRouterState unavailable (e.g., in tests)
}
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => FestivalSelectorSheet(provider: provider),
builder: (context) => FestivalSelectorSheet(
provider: provider,
currentPath: currentPath,
),
);
}

Expand All @@ -27,8 +38,13 @@ void showSettingsSheet(BuildContext context) {
/// Festival selector sheet for browsing all festivals
class FestivalSelectorSheet extends StatelessWidget {
final BeerProvider provider;
final String? currentPath;

const FestivalSelectorSheet({required this.provider, super.key});
const FestivalSelectorSheet({
required this.provider,
this.currentPath,
super.key,
});

String _getStatusLabel(FestivalStatus status) {
switch (status) {
Expand Down Expand Up @@ -185,20 +201,14 @@ class FestivalSelectorSheet extends StatelessWidget {
sortedFestivals: festivals,
isSelected: isSelected,
onTap: () {
// Capture current path first, before any state changes
// Default to festival home; override if currently on favorites
// 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);
}
Comment on lines +204 to 211

final router = GoRouter.maybeOf(context);
provider.setFestival(festival);
Navigator.pop(context);
Expand Down
Loading