Skip to content

Commit 5ca48a8

Browse files
committed
refactor(shared): improve ad injection logic and naming
- Rename `currentFeedItemCount` to `processedContentItemCount` for clarity - Refactor ad placement logic to focus on content items only - Add detailed comments explaining the ad injection process - Update method signature and documentation
1 parent 6d0073e commit 5ca48a8

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

lib/shared/services/feed_decorator_service.dart

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,13 @@ class FeedDecoratorService {
165165
required List<FeedItem> feedItems,
166166
required User? user,
167167
required AdConfig adConfig,
168-
int currentFeedItemCount = 0,
168+
int processedContentItemCount = 0,
169169
}) {
170170
return _injectAds(
171171
feedItems: feedItems,
172172
user: user,
173173
adConfig: adConfig,
174-
currentFeedItemCount: currentFeedItemCount,
174+
processedContentItemCount: processedContentItemCount,
175175
);
176176
}
177177

@@ -343,12 +343,26 @@ class FeedDecoratorService {
343343
}
344344
}
345345

346-
/// Injects ads into a list of feed items based on frequency rules.
346+
/// Injects ads into a list of [FeedItem]s based on frequency rules.
347+
///
348+
/// This method ensures that ads are placed according to the `adPlacementInterval`
349+
/// (initial buffer before the first ad) and `adFrequency` (subsequent ad spacing).
350+
/// It correctly accounts for content items only, ignoring previously injected ads
351+
/// when calculating placement.
352+
///
353+
/// [feedItems]: The list of feed items (headlines, decorators) to inject ads into.
354+
/// [user]: The current authenticated user, used to determine ad configuration.
355+
/// [adConfig]: The remote configuration for ad display rules.
356+
/// [processedContentItemCount]: The count of *content items* (non-ad, non-decorator)
357+
/// that have already been processed in previous feed loads/pages. This is
358+
/// crucial for maintaining correct ad placement across pagination.
359+
///
360+
/// Returns a new list of [FeedItem] objects, interspersed with ads.
347361
List<FeedItem> _injectAds({
348362
required List<FeedItem> feedItems,
349363
required User? user,
350364
required AdConfig adConfig,
351-
int currentFeedItemCount = 0,
365+
int processedContentItemCount = 0,
352366
}) {
353367
final userRole = user?.appRole ?? AppUserRole.guestUser;
354368

@@ -374,21 +388,31 @@ class FeedDecoratorService {
374388
}
375389

376390
final result = <FeedItem>[];
377-
var headlinesInBatch = 0;
391+
// This counter tracks the absolute number of *content items* (headlines,
392+
// topics, sources, countries) processed so far, including those from
393+
// previous pages. This is key for accurate ad placement.
394+
var currentContentItemCount = processedContentItemCount;
378395

379396
for (final item in feedItems) {
380397
result.add(item);
381-
headlinesInBatch++;
382398

383-
// Calculate the total number of items processed so far, including
384-
// those from previous pages.
385-
final totalItemsSoFar = currentFeedItemCount + result.length;
399+
// Only increment the content item counter if the current item is
400+
// a primary content type (not an ad or a decorator).
401+
// This ensures ad placement is based purely on content density.
402+
if (item is Headline ||
403+
item is Topic ||
404+
item is Source ||
405+
item is Country) {
406+
currentContentItemCount++;
407+
}
386408

387-
// Check if an ad should be injected.
388-
// The total number of items must be past the initial placement interval,
389-
// AND the number of content items in this batch must meet the frequency.
390-
if (totalItemsSoFar >= adPlacementInterval &&
391-
headlinesInBatch % adFrequency == 0) {
409+
// Check if an ad should be injected at the current position.
410+
// An ad is injected if:
411+
// 1. We have passed the initial placement interval.
412+
// 2. The number of content items *after* the initial interval is a
413+
// multiple of the ad frequency.
414+
if (currentContentItemCount > adPlacementInterval &&
415+
(currentContentItemCount - adPlacementInterval) % adFrequency == 0) {
392416
final adToInject = _getAdToInject();
393417
if (adToInject != null) {
394418
result.add(adToInject);

0 commit comments

Comments
 (0)