Skip to content

Commit 3c9d079

Browse files
committed
docs: clarify filter page state management
- Explain temporary state usage - Describe data passing to sub-pages - Clarify state update on apply
1 parent ed01ef4 commit 3c9d079

File tree

1 file changed

+49
-28
lines changed

1 file changed

+49
-28
lines changed

lib/headlines-feed/view/headlines_filter_page.dart

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,32 @@ class HeadlinesFilterPage extends StatefulWidget {
2929
}
3030

3131
class _HeadlinesFilterPageState extends State<HeadlinesFilterPage> {
32-
// Temporary state for filter selections within this modal flow
32+
/// Temporary state for filter selections within this modal flow.
33+
/// These hold the selections made by the user *while* this filter page
34+
/// and its sub-pages (Category, Source, Country) are open.
35+
/// They are initialized from the main [HeadlinesFeedBloc]'s current filter
36+
/// and are only applied back to the BLoC when the user taps 'Apply'.
3337
late List<Category> _tempSelectedCategories;
3438
late List<Source> _tempSelectedSources;
3539
late List<Country> _tempSelectedCountries;
3640

3741
@override
3842
void initState() {
3943
super.initState();
40-
// Initialize temporary state from the currently active filters in the BLoC
44+
// Initialize the temporary selection state based on the currently
45+
// active filters held within the HeadlinesFeedBloc. This ensures that
46+
// when the filter page opens, it reflects the filters already applied.
4147
final currentState = BlocProvider.of<HeadlinesFeedBloc>(context).state;
4248
if (currentState is HeadlinesFeedLoaded) {
49+
// Create copies of the lists to avoid modifying the BLoC state directly.
4350
_tempSelectedCategories = List.from(currentState.filter.categories ?? []);
4451
_tempSelectedSources = List.from(currentState.filter.sources ?? []);
4552
_tempSelectedCountries = List.from(
4653
currentState.filter.eventCountries ?? [],
4754
);
4855
} else {
49-
// Default to empty lists if the feed isn't loaded yet (should be rare)
56+
// Default to empty lists if the feed isn't loaded yet. This might happen
57+
// if the filter page is accessed before the initial feed load completes.
5058
_tempSelectedCategories = [];
5159
_tempSelectedSources = [];
5260
_tempSelectedCountries = [];
@@ -59,9 +67,11 @@ class _HeadlinesFilterPageState extends State<HeadlinesFilterPage> {
5967
/// ([selectedCount]), and navigates to the corresponding selection page
6068
/// specified by [routeName] when tapped.
6169
///
62-
/// Uses [currentSelection] to pass the temporary selection state to the
63-
/// criterion page and updates the state via the [onResult] callback when
64-
/// the criterion page pops with a result.
70+
/// Uses [currentSelection] to pass the current temporary selection state
71+
/// (e.g., `_tempSelectedSources`) to the corresponding criterion selection page
72+
/// (e.g., `SourceFilterPage`) via the `extra` parameter of `context.pushNamed`.
73+
/// Updates the temporary state via the [onResult] callback when the
74+
/// criterion page pops with a result (the user tapped 'Apply' on that page).
6575
Widget _buildFilterTile({
6676
required BuildContext context,
6777
required String title,
@@ -83,14 +93,21 @@ class _HeadlinesFilterPageState extends State<HeadlinesFilterPage> {
8393
subtitle: Text(subtitle),
8494
trailing: const Icon(Icons.chevron_right),
8595
onTap: () async {
86-
// Use pushNamed to navigate and wait for a result
96+
// Navigate to the specific filter selection page (e.g., SourceFilterPage).
97+
// Use pushNamed to wait for a result when the page is popped.
8798
final result = await context.pushNamed<List<dynamic>>(
88-
routeName,
89-
extra: currentSelection, // Pass current temp selection
99+
routeName, // The route name for the specific filter page.
100+
// Pass the current temporary selection for this filter type
101+
// (e.g., _tempSelectedSources) to the next page. This allows
102+
// the next page to initialize its UI reflecting the current state.
103+
extra: currentSelection,
90104
);
91-
// Update temp state if result is not null (user applied changes)
105+
// When the filter selection page pops (usually via its 'Apply' button),
106+
// it returns the potentially modified list of selected items.
107+
// If the result is not null (meaning the user didn't just cancel/go back),
108+
// update the corresponding temporary state list on *this* page.
92109
if (result != null) {
93-
onResult(result);
110+
onResult(result); // Calls setState to update the UI here.
94111
}
95112
},
96113
);
@@ -127,24 +144,28 @@ class _HeadlinesFilterPageState extends State<HeadlinesFilterPage> {
127144
icon: const Icon(Icons.check),
128145
tooltip: l10n.headlinesFeedFilterApplyButton,
129146
onPressed: () {
130-
// Apply the temporary filters to the BLoC
147+
// When the user confirms their filter choices on this page,
148+
// create a new HeadlineFilter object using the final temporary
149+
// selections gathered from the sub-pages.
150+
final newFilter = HeadlineFilter(
151+
categories:
152+
_tempSelectedCategories.isNotEmpty
153+
? _tempSelectedCategories
154+
: null, // Use null if empty
155+
sources:
156+
_tempSelectedSources.isNotEmpty
157+
? _tempSelectedSources
158+
: null, // Use null if empty
159+
eventCountries:
160+
_tempSelectedCountries.isNotEmpty
161+
? _tempSelectedCountries
162+
: null, // Use null if empty
163+
);
164+
165+
// Add an event to the main HeadlinesFeedBloc to apply the
166+
// newly constructed filter and trigger a data refresh.
131167
context.read<HeadlinesFeedBloc>().add(
132-
HeadlinesFeedFiltersApplied(
133-
filter: HeadlineFilter(
134-
categories:
135-
_tempSelectedCategories.isNotEmpty
136-
? _tempSelectedCategories
137-
: null,
138-
sources:
139-
_tempSelectedSources.isNotEmpty
140-
? _tempSelectedSources
141-
: null,
142-
eventCountries:
143-
_tempSelectedCountries.isNotEmpty
144-
? _tempSelectedCountries
145-
: null,
146-
),
147-
),
168+
HeadlinesFeedFiltersApplied(filter: newFilter),
148169
);
149170
context.pop(); // Close the filter page
150171
},

0 commit comments

Comments
 (0)