Skip to content

Commit b135b61

Browse files
committed
refactor(headlines-feed): remove engagementsMap from CachedFeed and update state management
- Remove engagementsMap from CachedFeed model - Update HeadlinesFeedBloc to manage engagementsMap in state instead of CachedFeed - Optimize AppBloc subscription for user content preferences changes - Adjust feed update logic to use state-engagementsMap instead of CachedFeed's
1 parent 54c4dff commit b135b61

File tree

2 files changed

+25
-71
lines changed

2 files changed

+25
-71
lines changed

lib/headlines-feed/bloc/headlines_feed_bloc.dart

Lines changed: 25 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -94,23 +94,18 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
9494
// Subscribe to AppBloc to react to global state changes, primarily for
9595
// keeping the feed's list of saved filters synchronized with the global
9696
// app state.
97-
_appBlocSubscription = _appBloc.stream.listen((appState) {
98-
// This subscription is now responsible for handling *updates* to the
99-
// user's preferences while the bloc is active. The initial state is
100-
// handled by the constructor.
101-
// This subscription's responsibility is to listen for changes in user
102-
// preferences (like adding/removing a saved filter) from other parts
103-
// of the app and update this BLoC's state accordingly.
104-
if (appState.userContentPreferences?.savedHeadlineFilters != null &&
105-
state.savedHeadlineFilters !=
106-
appState.userContentPreferences!.savedHeadlineFilters) {
107-
add(
108-
_AppContentPreferencesChanged(
109-
preferences: appState.userContentPreferences!,
110-
),
111-
);
112-
}
113-
});
97+
_appBlocSubscription = _appBloc.stream
98+
.map((appState) => appState.userContentPreferences)
99+
.distinct()
100+
.listen((preferences) {
101+
// This subscription's responsibility is to listen for changes in
102+
// user preferences (like adding/removing a saved filter) from other
103+
// parts of the app and update this BLoC's state accordingly.
104+
if (preferences != null &&
105+
state.savedHeadlineFilters != preferences.savedHeadlineFilters) {
106+
add(_AppContentPreferencesChanged(preferences: preferences));
107+
}
108+
});
114109

115110
on<HeadlinesFeedStarted>(
116111
_onHeadlinesFeedStarted,
@@ -173,7 +168,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
173168
final Logger _logger;
174169

175170
/// Subscription to the AppBloc's state stream.
176-
late final StreamSubscription<AppState> _appBlocSubscription;
171+
late final StreamSubscription<UserContentPreferences?> _appBlocSubscription;
177172

178173
static const _allFilterId = 'all';
179174

@@ -308,7 +303,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
308303
headlineResponse.items.map((h) => h.id).toList(),
309304
);
310305
final updatedEngagementsMap = Map<String, List<Engagement>>.from(
311-
cachedFeed.engagementsMap,
306+
state.engagementsMap,
312307
)..addAll(newEngagements);
313308

314309
// For pagination, only inject ad placeholders.
@@ -335,7 +330,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
335330
feedItems: updatedFeedItems,
336331
hasMore: headlineResponse.hasMore,
337332
cursor: headlineResponse.cursor,
338-
engagementsMap: updatedEngagementsMap,
339333
);
340334

341335
_feedCacheService.updateFeed(filterKey, updatedCachedFeed);
@@ -407,7 +401,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
407401
headlineResponse.items.map((h) => h.id).toList(),
408402
);
409403
final updatedEngagementsMap = Map<String, List<Engagement>>.from(
410-
cachedFeed?.engagementsMap ?? {},
404+
state.engagementsMap,
411405
)..addAll(newEngagements);
412406

413407
_logger.info(
@@ -443,12 +437,12 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
443437
final updatedCachedFeed = cachedFeed.copyWith(
444438
feedItems: updatedFeedItems,
445439
lastRefreshedAt: DateTime.now(),
446-
engagementsMap: updatedEngagementsMap,
447440
);
448441
_feedCacheService.updateFeed(filterKey, updatedCachedFeed);
449442
emit(
450443
state.copyWith(
451444
status: HeadlinesFeedStatus.success,
445+
engagementsMap: updatedEngagementsMap,
452446
feedItems: updatedFeedItems,
453447
),
454448
);
@@ -464,7 +458,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
464458
state.copyWith(
465459
status: HeadlinesFeedStatus.success,
466460
feedItems: cachedFeed.feedItems,
467-
engagementsMap: updatedEngagementsMap,
468461
),
469462
);
470463
// This early return is critical. It prevents the BLoC from
@@ -506,7 +499,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
506499
feedItems: fullyDecoratedFeed,
507500
hasMore: headlineResponse.hasMore,
508501
cursor: headlineResponse.cursor,
509-
engagementsMap: newEngagements,
510502
lastRefreshedAt: DateTime.now(),
511503
);
512504

@@ -519,7 +511,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
519511
hasMore: newCachedFeed.hasMore,
520512
cursor: newCachedFeed.cursor,
521513
filter: state.filter,
522-
engagementsMap: newCachedFeed.engagementsMap,
514+
engagementsMap: updatedEngagementsMap,
523515
),
524516
);
525517
} on HttpException catch (e) {
@@ -590,7 +582,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
590582
feedItems: cachedFeed.feedItems,
591583
hasMore: cachedFeed.hasMore,
592584
cursor: cachedFeed.cursor,
593-
engagementsMap: cachedFeed.engagementsMap,
594585
filter: event.filter,
595586
activeFilterId: newActiveFilterId,
596587
),
@@ -636,6 +627,9 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
636627
final newEngagements = await _fetchEngagementsForHeadlines(
637628
headlineResponse.items.map((h) => h.id).toList(),
638629
);
630+
final updatedEngagementsMap = Map<String, List<Engagement>>.from(
631+
state.engagementsMap,
632+
)..addAll(newEngagements);
639633

640634
final settings = _appBloc.state.settings;
641635

@@ -658,7 +652,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
658652
feedItems: fullyDecoratedFeed,
659653
hasMore: headlineResponse.hasMore,
660654
cursor: headlineResponse.cursor,
661-
engagementsMap: newEngagements,
662655
lastRefreshedAt: DateTime.now(),
663656
);
664657

@@ -670,7 +663,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
670663
feedItems: newCachedFeed.feedItems,
671664
hasMore: newCachedFeed.hasMore,
672665
cursor: newCachedFeed.cursor,
673-
engagementsMap: newCachedFeed.engagementsMap,
666+
engagementsMap: updatedEngagementsMap,
674667
),
675668
);
676669
} on HttpException catch (e) {
@@ -695,7 +688,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
695688
feedItems: cachedFeed.feedItems,
696689
hasMore: cachedFeed.hasMore,
697690
cursor: cachedFeed.cursor,
698-
engagementsMap: cachedFeed.engagementsMap,
699691
filter: const HeadlineFilterCriteria(
700692
topics: [],
701693
sources: [],
@@ -748,6 +740,9 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
748740
final newEngagements = await _fetchEngagementsForHeadlines(
749741
headlineResponse.items.map((h) => h.id).toList(),
750742
);
743+
final updatedEngagementsMap = Map<String, List<Engagement>>.from(
744+
state.engagementsMap,
745+
)..addAll(newEngagements);
751746

752747
final settings = _appBloc.state.settings;
753748

@@ -770,7 +765,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
770765
feedItems: fullyDecoratedFeed,
771766
hasMore: headlineResponse.hasMore,
772767
cursor: headlineResponse.cursor,
773-
engagementsMap: newEngagements,
774768
lastRefreshedAt: DateTime.now(),
775769
);
776770

@@ -782,7 +776,7 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
782776
feedItems: newCachedFeed.feedItems,
783777
hasMore: newCachedFeed.hasMore,
784778
cursor: newCachedFeed.cursor,
785-
engagementsMap: newCachedFeed.engagementsMap,
779+
engagementsMap: updatedEngagementsMap,
786780
),
787781
);
788782
} on HttpException catch (e) {
@@ -838,7 +832,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
838832
feedItems: cachedFeed.feedItems,
839833
hasMore: cachedFeed.hasMore,
840834
cursor: cachedFeed.cursor,
841-
engagementsMap: cachedFeed.engagementsMap,
842835
activeFilterId: filterKey,
843836
filter: newFilter,
844837
),
@@ -883,7 +876,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
883876
feedItems: cachedFeed.feedItems,
884877
hasMore: cachedFeed.hasMore,
885878
cursor: cachedFeed.cursor,
886-
engagementsMap: cachedFeed.engagementsMap,
887879
activeFilterId: 'all',
888880
filter: const HeadlineFilterCriteria(
889881
topics: [],
@@ -939,7 +931,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
939931
feedItems: cachedFeed.feedItems,
940932
hasMore: cachedFeed.hasMore,
941933
cursor: cachedFeed.cursor,
942-
engagementsMap: cachedFeed.engagementsMap,
943934
activeFilterId: 'followed',
944935
filter: newFilter,
945936
),
@@ -1066,16 +1057,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
10661057
state.engagementsMap,
10671058
)..[event.headlineId] = newEngagementsForHeadline;
10681059

1069-
// Update the cache with the new engagement map.
1070-
final filterKey = _generateFilterKey(state.activeFilterId!, state.filter);
1071-
final cachedFeed = _feedCacheService.getFeed(filterKey);
1072-
if (cachedFeed != null) {
1073-
_feedCacheService.updateFeed(
1074-
filterKey,
1075-
cachedFeed.copyWith(engagementsMap: newEngagementsMap),
1076-
);
1077-
}
1078-
10791060
emit(state.copyWith(engagementsMap: newEngagementsMap));
10801061
_appBloc.add(AppPositiveInteractionOcurred(context: event.context));
10811062
} catch (e, s) {
@@ -1133,15 +1114,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
11331114
state.engagementsMap,
11341115
)..[event.headlineId] = newEngagementsForHeadline;
11351116

1136-
final filterKey = _generateFilterKey(state.activeFilterId!, state.filter);
1137-
final cachedFeed = _feedCacheService.getFeed(filterKey);
1138-
if (cachedFeed != null) {
1139-
_feedCacheService.updateFeed(
1140-
filterKey,
1141-
cachedFeed.copyWith(engagementsMap: newEngagementsMap),
1142-
);
1143-
}
1144-
11451117
emit(state.copyWith(engagementsMap: newEngagementsMap));
11461118

11471119
try {
@@ -1203,15 +1175,6 @@ class HeadlinesFeedBloc extends Bloc<HeadlinesFeedEvent, HeadlinesFeedState> {
12031175
state.engagementsMap,
12041176
)..[event.headlineId] = newEngagementsForHeadline;
12051177

1206-
final filterKey = _generateFilterKey(state.activeFilterId!, state.filter);
1207-
final cachedFeed = _feedCacheService.getFeed(filterKey);
1208-
if (cachedFeed != null) {
1209-
_feedCacheService.updateFeed(
1210-
filterKey,
1211-
cachedFeed.copyWith(engagementsMap: newEngagementsMap),
1212-
);
1213-
}
1214-
12151178
emit(state.copyWith(engagementsMap: newEngagementsMap));
12161179

12171180
try {

lib/headlines-feed/models/cached_feed.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class CachedFeed extends Equatable {
1616
required this.hasMore,
1717
required this.lastRefreshedAt,
1818
this.cursor,
19-
this.engagementsMap = const {},
2019
});
2120

2221
/// The cached list of fully decorated feed items.
@@ -31,26 +30,20 @@ class CachedFeed extends Equatable {
3130
/// A timestamp to track the last successful refresh for throttling.
3231
final DateTime lastRefreshedAt;
3332

34-
/// A map of engagements, where the key is the entity ID (e.g., headline ID)
35-
/// and the value is the list of engagements for that entity.
36-
final Map<String, List<Engagement>> engagementsMap;
37-
3833
/// Creates a copy of this [CachedFeed] but with the given fields replaced
3934
/// with the new values.
4035
CachedFeed copyWith({
4136
List<FeedItem>? feedItems,
4237
bool? hasMore,
4338
String? cursor,
4439
DateTime? lastRefreshedAt,
45-
Map<String, List<Engagement>>? engagementsMap,
4640
bool clearCursor = false,
4741
}) {
4842
return CachedFeed(
4943
feedItems: feedItems ?? this.feedItems,
5044
hasMore: hasMore ?? this.hasMore,
5145
cursor: clearCursor ? null : cursor ?? this.cursor,
5246
lastRefreshedAt: lastRefreshedAt ?? this.lastRefreshedAt,
53-
engagementsMap: engagementsMap ?? this.engagementsMap,
5447
);
5548
}
5649

@@ -60,7 +53,6 @@ class CachedFeed extends Equatable {
6053
hasMore,
6154
cursor,
6255
lastRefreshedAt,
63-
engagementsMap,
6456
];
6557

6658
@override
@@ -70,7 +62,6 @@ class CachedFeed extends Equatable {
7062
'hasMore: $hasMore, '
7163
'cursor: $cursor, '
7264
'lastRefreshedAt: $lastRefreshedAt, '
73-
'engagementsMap: ${engagementsMap.length} entries '
7465
')';
7566
}
7667
}

0 commit comments

Comments
 (0)