@@ -21,14 +21,20 @@ class CountryInMemoryClient implements DataClient<Country> {
2121 required DataClient <Country > decoratedClient,
2222 required List <Source > allSources,
2323 required List <Headline > allHeadlines,
24- }) : _decoratedClient = decoratedClient,
25- _allSources = allSources,
26- _allHeadlines = allHeadlines;
24+ }) : _decoratedClient = decoratedClient,
25+ _allSources = allSources,
26+ _allHeadlines = allHeadlines;
2727
2828 final DataClient <Country > _decoratedClient;
2929 final List <Source > _allSources;
3030 final List <Headline > _allHeadlines;
3131
32+ /// Filter key for checking if a country has active sources.
33+ static const String hasActiveSourcesFilter = 'hasActiveSources' ;
34+
35+ /// Filter key for checking if a country has active headlines.
36+ static const String hasActiveHeadlinesFilter = 'hasActiveHeadlines' ;
37+
3238 @override
3339 Future <SuccessApiResponse <List <Map <String , dynamic >>>> aggregate ({
3440 required List <Map <String , dynamic >> pipeline,
@@ -73,32 +79,33 @@ class CountryInMemoryClient implements DataClient<Country> {
7379 PaginationOptions ? pagination,
7480 List <SortOption >? sort,
7581 }) async {
76- // First, get the initial list of countries from the decorated client.
77- // This handles generic filters, sorting, and pagination.
78- final response = await _decoratedClient.readAll (
82+ // Fetch ALL items from the decorated client first,
83+ // then apply custom filters, and finally apply pagination.
84+ // This ensures correct pagination behavior with custom filters.
85+ final allItemsResponse = await _decoratedClient.readAll (
7986 userId: userId,
8087 filter: filter,
81- pagination: pagination,
88+ // Pass null for pagination to get all items, as custom filters
89+ // need to operate on the complete dataset before pagination.
90+ pagination: null ,
8291 sort: sort,
8392 );
8493
85- var filteredCountries = response .data.items;
94+ Iterable < Country > filteredCountriesIterable = allItemsResponse .data.items;
8695
8796 // Apply custom filters if present
88- final hasActiveSources = filter? ['hasActiveSources' ] == true ;
89- final hasActiveHeadlines = filter? ['hasActiveHeadlines' ] == true ;
97+ final hasActiveSources = filter? [hasActiveSourcesFilter ] == true ;
98+ final hasActiveHeadlines = filter? [hasActiveHeadlinesFilter ] == true ;
9099
91100 if (hasActiveSources) {
92101 final countriesWithActiveSources = _allSources
93102 .where ((source) => source.status == ContentStatus .active)
94103 .map ((source) => source.headquarters.id)
95104 .toSet ();
96105
97- filteredCountries = filteredCountries
98- .where (
99- (country) => countriesWithActiveSources.contains (country.id),
100- )
101- .toList ();
106+ filteredCountriesIterable = filteredCountriesIterable.where (
107+ (country) => countriesWithActiveSources.contains (country.id),
108+ );
102109 }
103110
104111 if (hasActiveHeadlines) {
@@ -107,19 +114,33 @@ class CountryInMemoryClient implements DataClient<Country> {
107114 .map ((headline) => headline.eventCountry.id)
108115 .toSet ();
109116
110- filteredCountries = filteredCountries
111- .where (
112- (country) => countriesWithActiveHeadlines.contains (country.id),
113- )
114- .toList ();
117+ filteredCountriesIterable = filteredCountriesIterable.where (
118+ (country) => countriesWithActiveHeadlines.contains (country.id),
119+ );
115120 }
116121
117- // Return a new PaginatedResponse with the potentially further filtered items.
118- // The cursor and hasMore logic from the original response are preserved,
119- // but the items list is updated.
122+ // Manually apply pagination to the filtered list.
123+ final offset = pagination? .cursor != null
124+ ? int .tryParse (pagination! .cursor! ) ?? 0
125+ : 0 ;
126+ final limit = pagination? .limit ?? filteredCountriesIterable.length;
127+
128+ final paginatedItems = filteredCountriesIterable
129+ .skip (offset)
130+ .take (limit)
131+ .toList ();
132+
133+ final hasMore = (offset + limit) < filteredCountriesIterable.length;
134+ final nextCursor = hasMore ? (offset + limit).toString () : null ;
135+
136+ // Return a new PaginatedResponse with the correctly filtered and paginated items.
120137 return SuccessApiResponse (
121- data: response.data.copyWith (items: filteredCountries),
122- metadata: response.metadata,
138+ data: PaginatedResponse (
139+ items: paginatedItems,
140+ cursor: nextCursor,
141+ hasMore: hasMore,
142+ ),
143+ metadata: allItemsResponse.metadata,
123144 );
124145 }
125146
0 commit comments