@@ -3,9 +3,15 @@ import 'dart:async';
3
3
import 'package:bloc/bloc.dart' ;
4
4
import 'package:bloc_concurrency/bloc_concurrency.dart' ;
5
5
import 'package:equatable/equatable.dart' ;
6
- import 'package:ht_headlines_client/ht_headlines_client.dart' ; // Import for Headline and Exceptions
7
- import 'package:ht_headlines_repository/ht_headlines_repository.dart' ;
6
+ import 'package:ht_data_repository/ht_data_repository.dart' ; // Generic Data Repository
8
7
import 'package:ht_main/headlines-feed/models/headline_filter.dart' ;
8
+ import 'package:ht_shared/ht_shared.dart'
9
+ show
10
+ Category,
11
+ Country,
12
+ Headline,
13
+ HtHttpException,
14
+ Source; // Shared models and standardized exceptions
9
15
10
16
part 'headlines_feed_event.dart' ;
11
17
part 'headlines_feed_state.dart' ;
@@ -14,13 +20,13 @@ part 'headlines_feed_state.dart';
14
20
/// Manages the state for the headlines feed feature.
15
21
///
16
22
/// Handles fetching headlines, applying filters, pagination, and refreshing
17
- /// the feed using the provided [HtHeadlinesRepository ] .
23
+ /// the feed using the provided [HtDataRepository ] .
18
24
/// {@endtemplate}
19
25
class HeadlinesFeedBloc extends Bloc <HeadlinesFeedEvent , HeadlinesFeedState > {
20
26
/// {@macro headlines_feed_bloc}
21
27
///
22
- /// Requires a [HtHeadlinesRepository ] to interact with the data layer.
23
- HeadlinesFeedBloc ({required HtHeadlinesRepository headlinesRepository})
28
+ /// Requires a [HtDataRepository<Headline> ] to interact with the data layer.
29
+ HeadlinesFeedBloc ({required HtDataRepository < Headline > headlinesRepository})
24
30
: _headlinesRepository = headlinesRepository,
25
31
super (HeadlinesFeedLoading ()) {
26
32
on < HeadlinesFeedFetchRequested > (
@@ -37,7 +43,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
37
43
on < HeadlinesFeedFiltersCleared > (_onHeadlinesFeedFiltersCleared);
38
44
}
39
45
40
- final HtHeadlinesRepository _headlinesRepository;
46
+ final HtDataRepository < Headline > _headlinesRepository;
41
47
42
48
/// The number of headlines to fetch per page during pagination or initial load.
43
49
static const _headlinesFetchLimit = 10 ;
@@ -54,12 +60,26 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
54
60
) async {
55
61
emit (HeadlinesFeedLoading ()); // Show loading for filter application
56
62
try {
57
- final response = await _headlinesRepository.getHeadlines (
58
- limit: _headlinesFetchLimit,
59
- categories: event.filter.categories,
60
- sources: event.filter.sources,
61
- eventCountries: event.filter.eventCountries,
62
- );
63
+ final response = await _headlinesRepository.readAllByQuery ({
64
+ if (event.filter.categories? .isNotEmpty ?? false )
65
+ 'categories' :
66
+ event.filter.categories!
67
+ .whereType <Category >()
68
+ .map ((c) => c.id)
69
+ .toList (),
70
+ if (event.filter.sources? .isNotEmpty ?? false )
71
+ 'sources' :
72
+ event.filter.sources!
73
+ .whereType <Source >()
74
+ .map ((s) => s.id)
75
+ .toList (),
76
+ if (event.filter.eventCountries? .isNotEmpty ?? false )
77
+ 'eventCountries' :
78
+ event.filter.eventCountries!
79
+ .whereType <Country >()
80
+ .map ((c) => c.isoCode)
81
+ .toList (),
82
+ }, limit: _headlinesFetchLimit,);
63
83
emit (
64
84
HeadlinesFeedLoaded (
65
85
headlines: response.items,
@@ -68,7 +88,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
68
88
filter: event.filter, // Store the applied filter
69
89
),
70
90
);
71
- } on HeadlinesFetchException catch (e) {
91
+ } on HtHttpException catch (e) {
72
92
emit (HeadlinesFeedError (message: e.message));
73
93
} catch (e, st) {
74
94
// Log the error and stack trace for unexpected errors
@@ -88,7 +108,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
88
108
emit (HeadlinesFeedLoading ()); // Show loading indicator
89
109
try {
90
110
// Fetch the first page with no filters
91
- final response = await _headlinesRepository.getHeadlines (
111
+ final response = await _headlinesRepository.readAll (
92
112
limit: _headlinesFetchLimit,
93
113
);
94
114
emit (
@@ -98,7 +118,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
98
118
cursor: response.cursor,
99
119
),
100
120
);
101
- } on HeadlinesFetchException catch (e) {
121
+ } on HtHttpException catch (e) {
102
122
emit (HeadlinesFeedError (message: e.message));
103
123
} catch (e, st) {
104
124
// Log the error and stack trace for unexpected errors
@@ -155,12 +175,29 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
155
175
}
156
176
157
177
try {
158
- final response = await _headlinesRepository.getHeadlines (
178
+ final response = await _headlinesRepository.readAllByQuery (
179
+ {
180
+ if (currentFilter.categories? .isNotEmpty ?? false )
181
+ 'categories' :
182
+ currentFilter.categories!
183
+ .whereType <Category >()
184
+ .map ((c) => c.id)
185
+ .toList (),
186
+ if (currentFilter.sources? .isNotEmpty ?? false )
187
+ 'sources' :
188
+ currentFilter.sources!
189
+ .whereType <Source >()
190
+ .map ((s) => s.id)
191
+ .toList (),
192
+ if (currentFilter.eventCountries? .isNotEmpty ?? false )
193
+ 'eventCountries' :
194
+ currentFilter.eventCountries!
195
+ .whereType <Country >()
196
+ .map ((c) => c.isoCode)
197
+ .toList (),
198
+ },
159
199
limit: _headlinesFetchLimit,
160
200
startAfterId: currentCursor, // Use determined cursor
161
- categories: currentFilter.categories,
162
- sources: currentFilter.sources,
163
- eventCountries: currentFilter.eventCountries,
164
201
);
165
202
emit (
166
203
HeadlinesFeedLoaded (
@@ -172,7 +209,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
172
209
filter: currentFilter, // Preserve the filter
173
210
),
174
211
);
175
- } on HeadlinesFetchException catch (e) {
212
+ } on HtHttpException catch (e) {
176
213
emit (HeadlinesFeedError (message: e.message));
177
214
} catch (e, st) {
178
215
print ('Unexpected error in _onHeadlinesFeedFetchRequested: $e \n $st ' );
@@ -198,12 +235,26 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
198
235
199
236
try {
200
237
// Fetch the first page using the current filter
201
- final response = await _headlinesRepository.getHeadlines (
202
- limit: _headlinesFetchLimit,
203
- categories: currentFilter.categories,
204
- sources: currentFilter.sources,
205
- eventCountries: currentFilter.eventCountries,
206
- );
238
+ final response = await _headlinesRepository.readAllByQuery ({
239
+ if (currentFilter.categories? .isNotEmpty ?? false )
240
+ 'categories' :
241
+ currentFilter.categories!
242
+ .whereType <Category >()
243
+ .map ((c) => c.id)
244
+ .toList (),
245
+ if (currentFilter.sources? .isNotEmpty ?? false )
246
+ 'sources' :
247
+ currentFilter.sources!
248
+ .whereType <Source >()
249
+ .map ((s) => s.id)
250
+ .toList (),
251
+ if (currentFilter.eventCountries? .isNotEmpty ?? false )
252
+ 'eventCountries' :
253
+ currentFilter.eventCountries!
254
+ .whereType <Country >()
255
+ .map ((c) => c.isoCode)
256
+ .toList (),
257
+ }, limit: _headlinesFetchLimit,);
207
258
emit (
208
259
HeadlinesFeedLoaded (
209
260
headlines: response.items, // Replace headlines on refresh
@@ -212,7 +263,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
212
263
filter: currentFilter, // Preserve the filter
213
264
),
214
265
);
215
- } on HeadlinesFetchException catch (e) {
266
+ } on HtHttpException catch (e) {
216
267
emit (HeadlinesFeedError (message: e.message));
217
268
} catch (e, st) {
218
269
print ('Unexpected error in _onHeadlinesFeedRefreshRequested: $e \n $st ' );
0 commit comments