1
1
import 'package:bloc/bloc.dart' ;
2
2
import 'package:bloc_concurrency/bloc_concurrency.dart' ;
3
3
import 'package:equatable/equatable.dart' ;
4
- import 'package:ht_data_repository/ht_data_repository.dart' ; // Generic Data Repository
5
- import 'package:ht_main/headlines-search/models/search_model_type.dart' ; // Import SearchModelType
6
- import 'package:ht_shared/ht_shared.dart' show Category, Headline, HtHttpException, PaginatedResponse, Source; // Shared models
4
+ import 'package:ht_data_repository/ht_data_repository.dart' ;
5
+ import 'package:ht_main/app/bloc/app_bloc.dart' ; // Added
6
+ import 'package:ht_main/headlines-search/models/search_model_type.dart' ;
7
+ import 'package:ht_main/shared/services/feed_injector_service.dart' ; // Added
8
+ import 'package:ht_shared/ht_shared.dart' ; // Updated for FeedItem, AppConfig, User etc.
7
9
8
10
part 'headlines_search_event.dart' ;
9
11
part 'headlines_search_state.dart' ;
@@ -14,12 +16,14 @@ class HeadlinesSearchBloc
14
16
required HtDataRepository <Headline > headlinesRepository,
15
17
required HtDataRepository <Category > categoryRepository,
16
18
required HtDataRepository <Source > sourceRepository,
17
- // required HtDataRepository<Country> countryRepository, // Removed
18
- }) : _headlinesRepository = headlinesRepository,
19
- _categoryRepository = categoryRepository,
20
- _sourceRepository = sourceRepository,
21
- // _countryRepository = countryRepository, // Removed
22
- super (const HeadlinesSearchInitial ()) {
19
+ required AppBloc appBloc, // Added
20
+ required FeedInjectorService feedInjectorService, // Added
21
+ }) : _headlinesRepository = headlinesRepository,
22
+ _categoryRepository = categoryRepository,
23
+ _sourceRepository = sourceRepository,
24
+ _appBloc = appBloc, // Added
25
+ _feedInjectorService = feedInjectorService, // Added
26
+ super (const HeadlinesSearchInitial ()) {
23
27
on < HeadlinesSearchModelTypeChanged > (_onHeadlinesSearchModelTypeChanged);
24
28
on < HeadlinesSearchFetchRequested > (
25
29
_onSearchFetchRequested,
@@ -30,7 +34,8 @@ class HeadlinesSearchBloc
30
34
final HtDataRepository <Headline > _headlinesRepository;
31
35
final HtDataRepository <Category > _categoryRepository;
32
36
final HtDataRepository <Source > _sourceRepository;
33
- // final HtDataRepository<Country> _countryRepository; // Removed
37
+ final AppBloc _appBloc; // Added
38
+ final FeedInjectorService _feedInjectorService; // Added
34
39
static const _limit = 10 ;
35
40
36
41
Future <void > _onHeadlinesSearchModelTypeChanged (
@@ -61,7 +66,7 @@ class HeadlinesSearchBloc
61
66
if (searchTerm.isEmpty) {
62
67
emit (
63
68
HeadlinesSearchSuccess (
64
- results : const [],
69
+ items : const [], // Changed
65
70
hasMore: false ,
66
71
lastSearchTerm: '' ,
67
72
selectedModelType: modelType,
@@ -86,32 +91,57 @@ class HeadlinesSearchBloc
86
91
limit: _limit,
87
92
startAfterId: successState.cursor,
88
93
);
94
+ // Cast to List<Headline> for the injector
95
+ final headlines = response.items.cast <Headline >();
96
+ final currentUser = _appBloc.state.user;
97
+ final appConfig = _appBloc.state.appConfig;
98
+ if (appConfig == null ) {
99
+ emit (successState.copyWith (errorMessage: 'App configuration not available for pagination.' ));
100
+ return ;
101
+ }
102
+ final injectedItems = _feedInjectorService.injectItems (
103
+ headlines: headlines,
104
+ user: currentUser,
105
+ appConfig: appConfig,
106
+ currentFeedItemCount: successState.items.length,
107
+ );
108
+ emit (
109
+ successState.copyWith (
110
+ items: List .of (successState.items)..addAll (injectedItems),
111
+ hasMore: response.hasMore, // hasMore from original headline fetch
112
+ cursor: response.cursor,
113
+ ),
114
+ );
115
+ break ; // Added break
89
116
case SearchModelType .category:
90
117
response = await _categoryRepository.readAllByQuery (
91
118
{'q' : searchTerm, 'model' : modelType.toJson ()},
92
119
limit: _limit,
93
120
startAfterId: successState.cursor,
94
121
);
122
+ emit (
123
+ successState.copyWith (
124
+ items: List .of (successState.items)..addAll (response.items.cast <FeedItem >()),
125
+ hasMore: response.hasMore,
126
+ cursor: response.cursor,
127
+ ),
128
+ );
129
+ break ; // Added break
95
130
case SearchModelType .source:
96
131
response = await _sourceRepository.readAllByQuery (
97
132
{'q' : searchTerm, 'model' : modelType.toJson ()},
98
133
limit: _limit,
99
134
startAfterId: successState.cursor,
100
135
);
101
- // case SearchModelType.country: // Removed
102
- // response = await _countryRepository.readAllByQuery(
103
- // {'q': searchTerm, 'model': modelType.toJson()},
104
- // limit: _limit,
105
- // startAfterId: successState.cursor,
106
- // );
136
+ emit (
137
+ successState.copyWith (
138
+ items: List .of (successState.items)..addAll (response.items.cast <FeedItem >()),
139
+ hasMore: response.hasMore,
140
+ cursor: response.cursor,
141
+ ),
142
+ );
143
+ break ; // Added break
107
144
}
108
- emit (
109
- successState.copyWith (
110
- results: List .of (successState.results)..addAll (response.items),
111
- hasMore: response.hasMore,
112
- cursor: response.cursor,
113
- ),
114
- );
115
145
} on HtHttpException catch (e) {
116
146
emit (successState.copyWith (errorMessage: e.message));
117
147
} catch (e, st) {
@@ -132,34 +162,55 @@ class HeadlinesSearchBloc
132
162
),
133
163
);
134
164
try {
135
- PaginatedResponse <dynamic > response;
165
+ PaginatedResponse <dynamic > rawResponse;
166
+ List <FeedItem > processedItems;
167
+
136
168
switch (modelType) {
137
169
case SearchModelType .headline:
138
- response = await _headlinesRepository.readAllByQuery ({
139
- 'q' : searchTerm,
140
- 'model' : modelType.toJson (),
141
- }, limit: _limit,);
170
+ rawResponse = await _headlinesRepository.readAllByQuery (
171
+ {'q' : searchTerm, 'model' : modelType.toJson ()},
172
+ limit: _limit,
173
+ );
174
+ final headlines = rawResponse.items.cast <Headline >();
175
+ final currentUser = _appBloc.state.user;
176
+ final appConfig = _appBloc.state.appConfig;
177
+ if (appConfig == null ) {
178
+ emit (
179
+ HeadlinesSearchFailure (
180
+ errorMessage: 'App configuration not available.' ,
181
+ lastSearchTerm: searchTerm,
182
+ selectedModelType: modelType,
183
+ ),
184
+ );
185
+ return ;
186
+ }
187
+ processedItems = _feedInjectorService.injectItems (
188
+ headlines: headlines,
189
+ user: currentUser,
190
+ appConfig: appConfig,
191
+ currentFeedItemCount: 0 ,
192
+ );
193
+ break ;
142
194
case SearchModelType .category:
143
- response = await _categoryRepository.readAllByQuery ({
144
- 'q' : searchTerm,
145
- 'model' : modelType.toJson (),
146
- }, limit: _limit,);
195
+ rawResponse = await _categoryRepository.readAllByQuery (
196
+ {'q' : searchTerm, 'model' : modelType.toJson ()},
197
+ limit: _limit,
198
+ );
199
+ processedItems = rawResponse.items.cast <FeedItem >();
200
+ break ;
147
201
case SearchModelType .source:
148
- response = await _sourceRepository.readAllByQuery ({
149
- 'q' : searchTerm,
150
- 'model' : modelType.toJson (),
151
- }, limit: _limit,);
152
- // case SearchModelType.country: // Removed
153
- // response = await _countryRepository.readAllByQuery({
154
- // 'q': searchTerm,
155
- // 'model': modelType.toJson(),
156
- // }, limit: _limit,);
202
+ rawResponse = await _sourceRepository.readAllByQuery (
203
+ {'q' : searchTerm, 'model' : modelType.toJson ()},
204
+ limit: _limit,
205
+ );
206
+ processedItems = rawResponse.items.cast <FeedItem >();
207
+ break ;
157
208
}
158
209
emit (
159
210
HeadlinesSearchSuccess (
160
- results : response.items,
161
- hasMore: response .hasMore,
162
- cursor: response .cursor,
211
+ items : processedItems, // Changed
212
+ hasMore: rawResponse .hasMore,
213
+ cursor: rawResponse .cursor,
163
214
lastSearchTerm: searchTerm,
164
215
selectedModelType: modelType,
165
216
),
0 commit comments