Skip to content

Commit b045ff8

Browse files
committed
fix(feed_core): improve loading dialog resilience in HeadlineTapHandler
- Make the loading dialog resilient to context changes - Use unawaited to show the dialog without waiting for it to complete - Refactor dialog logic to use a single try-finally block - Ensure the dialog is dismissed properly even if the context changes
1 parent f63c06f commit b045ff8

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

lib/shared/widgets/feed_core/headline_tap_handler.dart

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:core/core.dart';
24
import 'package:data_repository/data_repository.dart';
35
import 'package:flutter/material.dart';
@@ -68,23 +70,25 @@ abstract final class HeadlineTapHandler {
6870
BuildContext context,
6971
String headlineId,
7072
) async {
71-
// Show a loading dialog as fetching the headline may take time.
72-
if (context.mounted) {
73-
await showDialog<void>(
73+
// Show a loading dialog that is resilient to context changes.
74+
final navigator = Navigator.of(context);
75+
unawaited(
76+
showDialog<void>(
7477
context: context,
7578
barrierDismissible: false,
76-
builder: (BuildContext context) =>
77-
const Center(child: CircularProgressIndicator()),
78-
);
79-
}
80-
81-
final headline = await context.read<DataRepository<Headline>>().read(
82-
id: headlineId,
79+
builder: (_) => const Center(child: CircularProgressIndicator()),
80+
),
8381
);
8482

85-
if (!context.mounted) return;
86-
Navigator.of(context).pop(); // Dismiss the loading dialog.
87-
await handleHeadlineTap(context, headline);
83+
try {
84+
final headline = await context.read<DataRepository<Headline>>().read(
85+
id: headlineId,
86+
);
87+
if (!context.mounted) return;
88+
await handleHeadlineTap(context, headline);
89+
} finally {
90+
if (navigator.canPop()) navigator.pop();
91+
}
8892
}
8993

9094
/// Handles a tap on a headline from a system notification.
@@ -109,24 +113,25 @@ abstract final class HeadlineTapHandler {
109113
context.read<AppBloc>().add(AppNotificationTapped(notificationId));
110114
}
111115

112-
if (context.mounted) {
113-
await showDialog<void>(
116+
// Show a loading dialog that is resilient to context changes.
117+
final navigator = Navigator.of(context);
118+
unawaited(
119+
showDialog<void>(
114120
context: context,
115121
barrierDismissible: false,
116-
builder: (BuildContext context) =>
117-
const Center(child: CircularProgressIndicator()),
118-
);
119-
}
120-
121-
final headline = await context.read<DataRepository<Headline>>().read(
122-
id: headlineId,
122+
builder: (_) => const Center(child: CircularProgressIndicator()),
123+
),
123124
);
124125

125-
if (!context.mounted) return;
126-
Navigator.of(context).pop(); // Dismiss the loading dialog.
127-
128-
if (await canLaunchUrlString(headline.url)) {
129-
await launchUrlString(headline.url, mode: LaunchMode.inAppWebView);
126+
try {
127+
final headline = await context.read<DataRepository<Headline>>().read(
128+
id: headlineId,
129+
);
130+
if (context.mounted && await canLaunchUrlString(headline.url)) {
131+
await launchUrlString(headline.url, mode: LaunchMode.inAppWebView);
132+
}
133+
} finally {
134+
if (navigator.canPop()) navigator.pop();
130135
}
131136
}
132137
}

0 commit comments

Comments
 (0)