@@ -18,11 +18,11 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
18
18
super (const SourcesFilterState ()) {
19
19
on < LoadSourceFilterData > (_onLoadSourceFilterData);
20
20
on < CountryCapsuleToggled > (_onCountryCapsuleToggled);
21
- on < AllSourceTypesCapsuleToggled > (_onAllSourceTypesCapsuleToggled); // Added
21
+ on < AllSourceTypesCapsuleToggled > (_onAllSourceTypesCapsuleToggled);
22
22
on < SourceTypeCapsuleToggled > (_onSourceTypeCapsuleToggled);
23
23
on < SourceCheckboxToggled > (_onSourceCheckboxToggled);
24
24
on < ClearSourceFiltersRequested > (_onClearSourceFiltersRequested);
25
- on < _FetchFilteredSourcesRequested > (_onFetchFilteredSourcesRequested);
25
+ // Removed _FetchFilteredSourcesRequested event listener
26
26
}
27
27
28
28
final HtDataRepository <Source > _sourcesRepository;
@@ -40,32 +40,37 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
40
40
final initialSelectedSourceIds =
41
41
event.initialSelectedSources.map ((s) => s.id).toSet ();
42
42
43
- // Initialize selected capsules based on initialSelectedSources
44
- final initialSelectedCountryIsoCodes = < String > {};
45
- final initialSelectedSourceTypes = < SourceType > {};
46
-
47
- if (event.initialSelectedSources.isNotEmpty) {
48
- for (final source in event.initialSelectedSources) {
49
- if (source.headquarters? .isoCode != null ) {
50
- initialSelectedCountryIsoCodes.add (source.headquarters! .isoCode);
51
- }
52
- if (source.sourceType != null ) {
53
- initialSelectedSourceTypes.add (source.sourceType! );
54
- }
55
- }
56
- }
43
+ // Use the passed-in initial capsule selections directly
44
+ final initialSelectedCountryIsoCodes =
45
+ event.initialSelectedCountryIsoCodes;
46
+ final initialSelectedSourceTypes = event.initialSelectedSourceTypes;
47
+
48
+ final allSourcesResponse = await _sourcesRepository.readAll ();
49
+ final allAvailableSources = allSourcesResponse.items;
50
+
51
+ // Initially, display all sources. Capsules are visually set but don't filter the list yet.
52
+ // Filtering will occur if a capsule is manually toggled.
53
+ // However, if initial capsule filters ARE provided, we should respect them for the initial display.
54
+ final displayableSources = _getFilteredSources (
55
+ allSources: allAvailableSources,
56
+ selectedCountries: initialSelectedCountryIsoCodes, // Use event's data
57
+ selectedTypes: initialSelectedSourceTypes, // Use event's data
58
+ );
57
59
58
60
emit (
59
61
state.copyWith (
60
62
availableCountries: availableCountries.items,
63
+ allAvailableSources: allAvailableSources,
64
+ displayableSources:
65
+ displayableSources, // Now correctly filtered if initial capsules were set
61
66
finallySelectedSourceIds: initialSelectedSourceIds,
62
- selectedCountryIsoCodes: initialSelectedCountryIsoCodes,
63
- selectedSourceTypes: initialSelectedSourceTypes,
64
- // Keep loading status until sources are fetched
67
+ selectedCountryIsoCodes:
68
+ initialSelectedCountryIsoCodes, // Use event's data
69
+ selectedSourceTypes: initialSelectedSourceTypes, // Use event's data
70
+ dataLoadingStatus: SourceFilterDataLoadingStatus .success,
71
+ clearErrorMessage: true ,
65
72
),
66
73
);
67
- // Trigger initial fetch of displayable sources
68
- add (const _FetchFilteredSourcesRequested ());
69
74
} catch (e) {
70
75
emit (
71
76
state.copyWith (
@@ -95,34 +100,57 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
95
100
currentSelected.add (event.countryIsoCode);
96
101
}
97
102
}
98
- emit (state.copyWith (selectedCountryIsoCodes: currentSelected));
99
- add (const _FetchFilteredSourcesRequested ());
103
+ final newDisplayableSources = _getFilteredSources (
104
+ allSources: state.allAvailableSources,
105
+ selectedCountries: currentSelected,
106
+ selectedTypes: state.selectedSourceTypes,
107
+ );
108
+ emit (
109
+ state.copyWith (
110
+ selectedCountryIsoCodes: currentSelected,
111
+ displayableSources: newDisplayableSources,
112
+ ),
113
+ );
100
114
}
101
115
102
- Future < void > _onAllSourceTypesCapsuleToggled (
116
+ void _onAllSourceTypesCapsuleToggled (
103
117
AllSourceTypesCapsuleToggled event,
104
118
Emitter <SourcesFilterState > emit,
105
- ) async {
106
- // Toggling "All" for source types means clearing any specific selections.
107
- // If already clear, it remains clear.
108
- emit (state.copyWith (selectedSourceTypes: {}));
109
- add (const _FetchFilteredSourcesRequested ());
119
+ ) {
120
+ final newDisplayableSources = _getFilteredSources (
121
+ allSources: state.allAvailableSources,
122
+ selectedCountries: state.selectedCountryIsoCodes,
123
+ selectedTypes: {}, // Cleared source types
124
+ );
125
+ emit (
126
+ state.copyWith (
127
+ selectedSourceTypes: {},
128
+ displayableSources: newDisplayableSources,
129
+ ),
130
+ );
110
131
}
111
132
112
- Future < void > _onSourceTypeCapsuleToggled (
133
+ void _onSourceTypeCapsuleToggled (
113
134
SourceTypeCapsuleToggled event,
114
135
Emitter <SourcesFilterState > emit,
115
- ) async {
136
+ ) {
116
137
final currentSelected = Set <SourceType >.from (state.selectedSourceTypes);
117
138
if (currentSelected.contains (event.sourceType)) {
118
139
currentSelected.remove (event.sourceType);
119
140
} else {
120
141
currentSelected.add (event.sourceType);
121
142
}
122
- // If specific types are selected, "All" is no longer true.
123
- // The UI will derive "All" state from selectedSourceTypes.isEmpty
124
- emit (state.copyWith (selectedSourceTypes: currentSelected));
125
- add (const _FetchFilteredSourcesRequested ());
143
+ final newDisplayableSources = _getFilteredSources (
144
+ allSources: state.allAvailableSources,
145
+ selectedCountries: state.selectedCountryIsoCodes,
146
+ selectedTypes: currentSelected,
147
+ );
148
+ emit (
149
+ state.copyWith (
150
+ selectedSourceTypes: currentSelected,
151
+ displayableSources: newDisplayableSources,
152
+ ),
153
+ );
126
154
}
127
155
128
156
void _onSourceCheckboxToggled (
@@ -147,55 +175,33 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
147
175
selectedCountryIsoCodes: {},
148
176
selectedSourceTypes: {},
149
177
finallySelectedSourceIds: {},
150
- // Keep availableCountries and availableSourceTypes
151
- ),
152
- );
153
- add (const _FetchFilteredSourcesRequested ());
154
- }
155
-
156
- Future <void > _onFetchFilteredSourcesRequested (
157
- _FetchFilteredSourcesRequested event,
158
- Emitter <SourcesFilterState > emit,
159
- ) async {
160
- emit (
161
- state.copyWith (
162
- dataLoadingStatus: SourceFilterDataLoadingStatus .loading,
163
- displayableSources: [], // Clear previous sources
178
+ displayableSources: List .from (state.allAvailableSources), // Reset
179
+ dataLoadingStatus: SourceFilterDataLoadingStatus .success,
164
180
clearErrorMessage: true ,
165
181
),
166
182
);
167
- try {
168
- final queryParameters = < String , dynamic > {};
169
- if (state.selectedCountryIsoCodes.isNotEmpty) {
170
- queryParameters['countries' ] = state.selectedCountryIsoCodes.join (',' );
171
- }
172
- if (state.selectedSourceTypes.isNotEmpty) {
173
- queryParameters['sourceTypes' ] = state.selectedSourceTypes
174
- .map ((st) => st.name)
175
- .join (',' );
176
- }
183
+ }
177
184
178
- final response = await _sourcesRepository.readAllByQuery (queryParameters);
179
- emit (
180
- state.copyWith (
181
- displayableSources: response.items,
182
- dataLoadingStatus: SourceFilterDataLoadingStatus .success,
183
- ),
184
- );
185
- } on HtHttpException catch (e) {
186
- emit (
187
- state.copyWith (
188
- dataLoadingStatus: SourceFilterDataLoadingStatus .failure,
189
- errorMessage: e.message,
190
- ),
191
- );
192
- } catch (e) {
193
- emit (
194
- state.copyWith (
195
- dataLoadingStatus: SourceFilterDataLoadingStatus .failure,
196
- errorMessage: 'An unexpected error occurred while fetching sources.' ,
197
- ),
198
- );
185
+ // Helper method to filter sources based on selected countries and types
186
+ List <Source > _getFilteredSources ({
187
+ required List <Source > allSources,
188
+ required Set <String > selectedCountries,
189
+ required Set <SourceType > selectedTypes,
190
+ }) {
191
+ if (selectedCountries.isEmpty && selectedTypes.isEmpty) {
192
+ return List .from (allSources); // Return all if no filters
199
193
}
194
+
195
+ return allSources.where ((source) {
196
+ final matchesCountry =
197
+ selectedCountries.isEmpty ||
198
+ (source.headquarters != null &&
199
+ selectedCountries.contains (source.headquarters! .isoCode));
200
+ final matchesType =
201
+ selectedTypes.isEmpty ||
202
+ (source.sourceType != null &&
203
+ selectedTypes.contains (source.sourceType));
204
+ return matchesCountry && matchesType;
205
+ }).toList ();
200
206
}
201
207
}
0 commit comments