@@ -3,9 +3,11 @@ import 'dart:async';
3
3
import 'package:bloc/bloc.dart' ;
4
4
import 'package:equatable/equatable.dart' ;
5
5
import 'package:ht_data_repository/ht_data_repository.dart' ;
6
- import 'package:ht_main/account/bloc/account_bloc.dart' ; // Corrected import
6
+ import 'package:ht_main/account/bloc/account_bloc.dart' ;
7
+ import 'package:ht_main/app/bloc/app_bloc.dart' ; // Added
7
8
import 'package:ht_main/entity_details/models/entity_type.dart' ;
8
- import 'package:ht_shared/ht_shared.dart' ;
9
+ import 'package:ht_main/shared/services/feed_injector_service.dart' ; // Added
10
+ import 'package:ht_shared/ht_shared.dart' ; // Ensures FeedItem, AppConfig, User are available
9
11
10
12
part 'entity_details_event.dart' ;
11
13
part 'entity_details_state.dart' ;
@@ -15,12 +17,16 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
15
17
required HtDataRepository <Headline > headlinesRepository,
16
18
required HtDataRepository <Category > categoryRepository,
17
19
required HtDataRepository <Source > sourceRepository,
18
- required AccountBloc accountBloc, // Changed to AccountBloc
19
- }) : _headlinesRepository = headlinesRepository,
20
- _categoryRepository = categoryRepository,
21
- _sourceRepository = sourceRepository,
22
- _accountBloc = accountBloc,
23
- super (const EntityDetailsState ()) {
20
+ required AccountBloc accountBloc,
21
+ required AppBloc appBloc, // Added
22
+ required FeedInjectorService feedInjectorService, // Added
23
+ }) : _headlinesRepository = headlinesRepository,
24
+ _categoryRepository = categoryRepository,
25
+ _sourceRepository = sourceRepository,
26
+ _accountBloc = accountBloc,
27
+ _appBloc = appBloc, // Added
28
+ _feedInjectorService = feedInjectorService, // Added
29
+ super (const EntityDetailsState ()) {
24
30
on < EntityDetailsLoadRequested > (_onEntityDetailsLoadRequested);
25
31
on < EntityDetailsToggleFollowRequested > (
26
32
_onEntityDetailsToggleFollowRequested,
@@ -43,10 +49,12 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
43
49
final HtDataRepository <Headline > _headlinesRepository;
44
50
final HtDataRepository <Category > _categoryRepository;
45
51
final HtDataRepository <Source > _sourceRepository;
46
- final AccountBloc _accountBloc; // Changed to AccountBloc
52
+ final AccountBloc _accountBloc;
53
+ final AppBloc _appBloc; // Added
54
+ final FeedInjectorService _feedInjectorService; // Added
47
55
late final StreamSubscription <AccountState > _accountBlocSubscription;
48
56
49
- static const _headlinesLimit = 10 ;
57
+ static const _headlinesLimit = 10 ; // For fetching original headlines
50
58
51
59
Future <void > _onEntityDetailsLoadRequested (
52
60
EntityDetailsLoadRequested event,
@@ -101,11 +109,33 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
101
109
queryParams['sources' ] = (entityToLoad as Source ).id;
102
110
}
103
111
104
- final headlinesResponse = await _headlinesRepository.readAllByQuery (
112
+ final headlineResponse = await _headlinesRepository.readAllByQuery (
105
113
queryParams,
106
114
limit: _headlinesLimit,
107
115
);
108
116
117
+ final currentUser = _appBloc.state.user;
118
+ final appConfig = _appBloc.state.appConfig;
119
+
120
+ if (appConfig == null ) {
121
+ emit (
122
+ state.copyWith (
123
+ status: EntityDetailsStatus .failure,
124
+ errorMessage: 'App configuration not available.' ,
125
+ entityType: entityTypeToLoad,
126
+ entity: entityToLoad,
127
+ ),
128
+ );
129
+ return ;
130
+ }
131
+
132
+ final processedFeedItems = _feedInjectorService.injectItems (
133
+ headlines: headlineResponse.items,
134
+ user: currentUser,
135
+ appConfig: appConfig,
136
+ currentFeedItemCount: 0 , // Initial load for this entity's feed
137
+ );
138
+
109
139
// 3. Determine isFollowing status
110
140
var isCurrentlyFollowing = false ;
111
141
final currentAccountState = _accountBloc.state;
@@ -131,13 +161,19 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
131
161
entityType: entityTypeToLoad,
132
162
entity: entityToLoad,
133
163
isFollowing: isCurrentlyFollowing,
134
- headlines : headlinesResponse.items,
164
+ feedItems : processedFeedItems, // Changed
135
165
headlinesStatus: EntityHeadlinesStatus .success,
136
- hasMoreHeadlines: headlinesResponse .hasMore,
137
- headlinesCursor: headlinesResponse .cursor,
166
+ hasMoreHeadlines: headlineResponse .hasMore, // Based on original headlines
167
+ headlinesCursor: headlineResponse .cursor,
138
168
clearErrorMessage: true ,
139
169
),
140
170
);
171
+
172
+ // Dispatch event if AccountAction was injected in the initial load
173
+ if (processedFeedItems.any ((item) => item is AccountAction ) &&
174
+ _appBloc.state.user? .id != null ) {
175
+ _appBloc.add (AppUserAccountActionShown (userId: _appBloc.state.user! .id));
176
+ }
141
177
} on HtHttpException catch (e) {
142
178
emit (
143
179
state.copyWith (
@@ -203,7 +239,7 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
203
239
EntityDetailsLoadMoreHeadlinesRequested event,
204
240
Emitter <EntityDetailsState > emit,
205
241
) async {
206
- if (! state.hasMoreHeadlines ||
242
+ if (! state.hasMoreHeadlines || // Still refers to original headlines pagination
207
243
state.headlinesStatus == EntityHeadlinesStatus .loadingMore) {
208
244
return ;
209
245
}
@@ -218,7 +254,6 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
218
254
} else if (state.entityType == EntityType .source) {
219
255
queryParams['sources' ] = (state.entity as Source ).id;
220
256
} else {
221
- // Should not happen
222
257
emit (
223
258
state.copyWith (
224
259
headlinesStatus: EntityHeadlinesStatus .failure,
@@ -228,21 +263,47 @@ class EntityDetailsBloc extends Bloc<EntityDetailsEvent, EntityDetailsState> {
228
263
return ;
229
264
}
230
265
231
- final headlinesResponse = await _headlinesRepository.readAllByQuery (
266
+ final headlineResponse = await _headlinesRepository.readAllByQuery (
232
267
queryParams,
233
268
limit: _headlinesLimit,
234
- startAfterId: state.headlinesCursor,
269
+ startAfterId: state.headlinesCursor, // Cursor for original headlines
270
+ );
271
+
272
+ final currentUser = _appBloc.state.user;
273
+ final appConfig = _appBloc.state.appConfig;
274
+
275
+ if (appConfig == null ) {
276
+ emit (
277
+ state.copyWith (
278
+ headlinesStatus: EntityHeadlinesStatus .failure,
279
+ errorMessage: 'App configuration not available for pagination.' ,
280
+ ),
281
+ );
282
+ return ;
283
+ }
284
+
285
+ final newProcessedFeedItems = _feedInjectorService.injectItems (
286
+ headlines: headlineResponse.items,
287
+ user: currentUser,
288
+ appConfig: appConfig,
289
+ currentFeedItemCount: state.feedItems.length, // Pass current total
235
290
);
236
291
237
292
emit (
238
293
state.copyWith (
239
- headlines : List .of (state.headlines )..addAll (headlinesResponse.items),
294
+ feedItems : List .of (state.feedItems )..addAll (newProcessedFeedItems), // Changed
240
295
headlinesStatus: EntityHeadlinesStatus .success,
241
- hasMoreHeadlines: headlinesResponse .hasMore,
242
- headlinesCursor: headlinesResponse .cursor,
243
- clearHeadlinesCursor: ! headlinesResponse .hasMore, // Clear if no more
296
+ hasMoreHeadlines: headlineResponse .hasMore, // Based on original headlines
297
+ headlinesCursor: headlineResponse .cursor,
298
+ clearHeadlinesCursor: ! headlineResponse .hasMore,
244
299
),
245
300
);
301
+
302
+ // Dispatch event if AccountAction was injected in the newly loaded items
303
+ if (newProcessedFeedItems.any ((item) => item is AccountAction ) &&
304
+ _appBloc.state.user? .id != null ) {
305
+ _appBloc.add (AppUserAccountActionShown (userId: _appBloc.state.user! .id));
306
+ }
246
307
} on HtHttpException catch (e) {
247
308
emit (
248
309
state.copyWith (
0 commit comments