Skip to content

Commit 8d6b826

Browse files
committed
style: format
1 parent 6f52ab1 commit 8d6b826

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

lib/discover/bloc/discover_bloc.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ class DiscoverBloc extends Bloc<DiscoverEvent, DiscoverState> {
6868
emit(
6969
state.copyWith(
7070
status: DiscoverStatus.failure,
71-
error: UnknownException(
72-
'An unexpected error occurred: $e',
73-
),
71+
error: UnknownException('An unexpected error occurred: $e'),
7472
),
7573
);
7674
}

lib/discover/bloc/source_list_bloc.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,9 @@ class SourceListBloc extends Bloc<SourceListEvent, SourceListState> {
298298
Emitter<SourceListState> emit,
299299
) async {
300300
if (!state.countriesHasMore ||
301-
state.status == SourceListStatus.loadingMoreCountries)
301+
state.status == SourceListStatus.loadingMoreCountries) {
302302
return;
303+
}
303304

304305
_logger.fine('Load more countries for source list filter requested.');
305306
emit(state.copyWith(status: SourceListStatus.loadingMoreCountries));

lib/discover/view/source_list_filter_page.dart

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:collection/collection.dart';
12
import 'package:core/core.dart';
23
import 'package:flutter/material.dart';
34
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -33,14 +34,26 @@ class _SourceListFilterView extends StatefulWidget {
3334
}
3435

3536
class _SourceListFilterViewState extends State<_SourceListFilterView> {
37+
late final Set<Country> _initialSelection;
38+
late Set<Country> _currentSelection;
3639
final _scrollController = ScrollController();
3740

3841
@override
3942
void initState() {
4043
super.initState();
44+
// Store the initial and current selections locally to track changes.
45+
_initialSelection = context.read<SourceListBloc>().state.selectedCountries;
46+
_currentSelection = Set.from(_initialSelection);
4147
_scrollController.addListener(_onScroll);
4248
}
4349

50+
bool get _hasChanges {
51+
return !const SetEquality<Country>().equals(
52+
_initialSelection,
53+
_currentSelection,
54+
);
55+
}
56+
4457
@override
4558
void dispose() {
4659
_scrollController
@@ -79,7 +92,20 @@ class _SourceListFilterViewState extends State<_SourceListFilterView> {
7992
IconButton(
8093
icon: const Icon(Icons.check),
8194
tooltip: l10n.headlinesFeedFilterApplyButton,
82-
onPressed: () => Navigator.of(context).pop(),
95+
// The button is enabled only if the selection has changed.
96+
onPressed: _hasChanges
97+
? () {
98+
// When applying, dispatch a single event with the final
99+
// selection and then pop the page.
100+
context.read<SourceListBloc>().add(
101+
SourceListCountryFilterChanged(
102+
selectedCountries: _currentSelection,
103+
),
104+
);
105+
Navigator.of(context).pop();
106+
}
107+
// If there are no changes, the button is disabled.
108+
: null,
83109
),
84110
],
85111
),
@@ -115,7 +141,7 @@ class _SourceListFilterViewState extends State<_SourceListFilterView> {
115141
: const SizedBox.shrink();
116142
}
117143
final country = state.countries[index];
118-
final isSelected = state.selectedCountries.contains(country);
144+
final isSelected = _currentSelection.contains(country);
119145

120146
return CheckboxListTile(
121147
title: Text(country.name, style: textTheme.titleMedium),
@@ -138,19 +164,15 @@ class _SourceListFilterViewState extends State<_SourceListFilterView> {
138164
value: isSelected,
139165
onChanged: (bool? value) {
140166
if (value == null) return;
141-
final newSelection = Set<Country>.from(
142-
state.selectedCountries,
143-
);
144-
if (value) {
145-
newSelection.add(country);
146-
} else {
147-
newSelection.remove(country);
148-
}
149-
context.read<SourceListBloc>().add(
150-
SourceListCountryFilterChanged(
151-
selectedCountries: newSelection,
152-
),
153-
);
167+
// Update the local selection state, which will trigger a
168+
// rebuild and enable/disable the apply button.
169+
setState(() {
170+
if (value) {
171+
_currentSelection.add(country);
172+
} else {
173+
_currentSelection.remove(country);
174+
}
175+
});
154176
},
155177
controlAffinity: ListTileControlAffinity.leading,
156178
);

lib/headlines-feed/view/source_list_filter_page.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import 'package:core/core.dart';
44
import 'package:flutter/material.dart';
55
import 'package:flutter_news_app_mobile_client_full_source_code/l10n/l10n.dart';
66
import 'package:flutter_news_app_mobile_client_full_source_code/router/routes.dart';
7-
import 'package:go_router/go_router.dart';
87
import 'package:flutter_news_app_mobile_client_full_source_code/shared/extensions/extensions.dart';
8+
import 'package:go_router/go_router.dart';
99
import 'package:ui_kit/ui_kit.dart';
1010

1111
/// {@template source_list_filter_page}

0 commit comments

Comments
 (0)