@@ -135,36 +135,56 @@ class _HeadlinesFilterViewState extends State<_HeadlinesFilterView> {
135135
136136 /// Initiates the process of saving a filter by showing the naming dialog,
137137 /// and then applies it.
138- void _saveAndApplyFilter () {
138+ ///
139+ /// This function `await` s the result of the `SaveFilterDialog` . This is
140+ /// crucial to prevent a race condition where the `HeadlinesFilterPage` might
141+ /// be popped before the dialog is fully dismissed, which was causing a
142+ /// navigation stack error and a black screen.
143+ Future <void > _saveAndApplyFilter () async {
139144 final filterState = context.read <HeadlinesFilterBloc >().state;
140- showDialog <void >(
145+
146+ // `showDialog` returns a Future that completes when the dialog is popped.
147+ // We await its result (`true` on successful save) to synchronize navigation.
148+ final didSave = await showDialog <bool >(
141149 context: context,
142150 builder: (_) {
143151 return SaveFilterDialog (
144152 onSave: (name) {
153+ // This callback is executed when the user submits the save dialog.
145154 final newFilter = SavedFilter (
146155 id: const Uuid ().v4 (),
147156 name: name,
148157 topics: filterState.selectedTopics.toList (),
149158 sources: filterState.selectedSources.toList (),
150159 countries: filterState.selectedCountries.toList (),
151160 );
152- // Add the filter to the global state.
161+ // Add the new filter to the global AppBloc state.
153162 context.read <AppBloc >().add (SavedFilterAdded (filter: newFilter));
154- // Apply the newly saved filter and exit the page.
155- _applyAndExit (newFilter);
163+
164+ // Apply the filter to the HeadlinesFeedBloc. The page is not
165+ // popped here; that action is deferred until after the dialog
166+ // has been successfully dismissed.
167+ _applyFilter (newFilter);
156168 },
157169 );
158170 },
159171 );
172+
173+ // After the dialog is popped and we have the result, check if the save
174+ // was successful and if the widget is still in the tree.
175+ // This check prevents the "Don't use 'BuildContext's across async gaps"
176+ // lint warning and ensures we don't try to pop a disposed context.
177+ if (didSave == true && mounted) {
178+ context.pop ();
179+ }
160180 }
161181
162182 /// Applies the current filter selections to the feed and pops the page.
163183 ///
164184 /// If a [savedFilter] is provided, it's passed to the event to ensure
165185 /// its chip is correctly selected on the feed. Otherwise, the filter is
166186 /// treated as a "custom" one.
167- void _applyAndExit (SavedFilter ? savedFilter) {
187+ void _applyFilter (SavedFilter ? savedFilter) {
168188 final filterState = context.read <HeadlinesFilterBloc >().state;
169189 final newFilter = HeadlineFilter (
170190 topics: filterState.selectedTopics.toList (),
@@ -179,6 +199,12 @@ class _HeadlinesFilterViewState extends State<_HeadlinesFilterView> {
179199 adThemeStyle: AdThemeStyle .fromTheme (Theme .of (context)),
180200 ),
181201 );
202+ }
203+
204+ void _applyAndExit (SavedFilter ? savedFilter) {
205+ // This helper method now separates applying the filter from exiting.
206+ // It's called for the "Apply Only" flow.
207+ _applyFilter (savedFilter);
182208 context.pop ();
183209 }
184210
0 commit comments