Skip to content

Commit d052799

Browse files
authored
Merge pull request #56 from flutter-news-app-full-source-code/54-feat-filter-bookmarked-entry-model
feat filter bookmarked entry model
2 parents 828b984 + 5f09f9e commit d052799

19 files changed

+325
-13
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 1.2.0 - 2024-05-21
2+
3+
- feat: add SavedFilter model for storing user-defined filter combinations.
4+
- **BREAKING** feat!: link SavedFilter to UserContentPreferences, making `savedFilters` a required field.
5+
- **BREAKING** feat!: add limits for saved filters to UserPreferenceConfig.
6+
- **BREAKING** refactor!: organize saved models into a new `user_presets` directory.
7+
- test: add unit tests for SavedFilter model.
8+
- test: update tests for UserContentPreferences to include saved filters.
9+
- docs: update README to reflect new User Presets section and model.
10+
- chore: add fixture data for SavedFilter.
11+
- chore: synchronize all related fixtures with recent model updates.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ This package provides the critical building blocks for a professional news appli
2727
- **`User`, `AppUserRole`, `DashboardUserRole`, `Permission`:** Robust models for user profiles, roles, and permissions, enabling secure and personalized experiences.
2828
- **`UserContentPreferences`, `UserAppSettings`:** Detailed models for storing user-specific content preferences (e.g., followed topics, saved headlines) and application settings (e.g., theme, language).
2929

30+
### 💾 User Presets
31+
- **`SavedFilter`:** A model for storing user-defined filter combinations.
32+
3033
### ⚙️ Application Configuration
3134
- **`RemoteConfig`:** A central container for all dynamic application settings, fetched from a remote source. This includes:
3235
- **`AdConfig`:** Master configuration for all advertising, now featuring **highly flexible, role-based control** over ad visibility and frequency for feed, article, and interstitial ads. This allows for granular control over monetization strategies per user segment.

lib/src/fixtures/fixture_ids.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,7 @@ const kLocalAd3Id = '3563c000a4a4e6e1a8e7f0f3';
530530
const kLocalAd4Id = '4563c000a4a4e6e1a8e7f0f4';
531531
const kLocalAd5Id = '5563c000a4a4e6e1a8e7f0f5';
532532
const kLocalAd6Id = '6563c000a4a4e6e1a8e7f0f6';
533+
534+
/// Saved filters Fixture IDs.
535+
const String kSavedFilterId1 = 'saved_search_1';
536+
const String kSavedFilterId2 = 'saved_search_2';

lib/src/fixtures/fixtures.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ export 'headlines.dart';
55
export 'languages.dart';
66
export 'local_ads.dart';
77
export 'remote_configs.dart';
8+
export 'saved_filter.dart';
89
export 'sources.dart';
910
export 'topics.dart';
10-
export 'user_app_settings_fixtures.dart';
11-
export 'user_content_preferences_fixtures.dart';
11+
export 'user_app_settings.dart';
12+
export 'user_content_preferences.dart';
1213
export 'users.dart';

lib/src/fixtures/remote_configs.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ final List<RemoteConfig> remoteConfigsFixturesData = [
3535
authenticatedSavedHeadlinesLimit: 30,
3636
premiumFollowedItemsLimit: 30,
3737
premiumSavedHeadlinesLimit: 100,
38+
guestSavedFiltersLimit: 3,
39+
authenticatedSavedFiltersLimit: 10,
40+
premiumSavedFiltersLimit: 25,
3841
),
3942
adConfig: const AdConfig(
4043
enabled: true,

lib/src/fixtures/saved_filter.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'package:core/src/fixtures/countries.dart';
2+
import 'package:core/src/fixtures/fixture_ids.dart';
3+
import 'package:core/src/fixtures/sources.dart';
4+
import 'package:core/src/fixtures/topics.dart';
5+
import 'package:core/src/models/user_presets/saved_filter.dart';
6+
7+
/// A list of predefined saved searches for fixture data.
8+
final savedFiltersFixturesData = <SavedFilter>[
9+
SavedFilter(
10+
id: kSavedFilterId1,
11+
name: 'UK Tech & Politics',
12+
topics: [
13+
topicsFixturesData.firstWhere((t) => t.name == 'Technology'),
14+
topicsFixturesData.firstWhere((t) => t.name == 'Politics'),
15+
],
16+
sources: [sourcesFixturesData.firstWhere((s) => s.name == 'BBC News')],
17+
countries: [
18+
countriesFixturesData.firstWhere((c) => c.name == 'United Kingdom'),
19+
],
20+
),
21+
SavedFilter(
22+
id: kSavedFilterId2,
23+
name: 'US Business News',
24+
topics: [topicsFixturesData.firstWhere((t) => t.name == 'Business')],
25+
sources: const [],
26+
countries: [
27+
countriesFixturesData.firstWhere((c) => c.name == 'United States'),
28+
],
29+
),
30+
];

lib/src/fixtures/user_content_preferences_fixtures.dart renamed to lib/src/fixtures/user_content_preferences.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ final List<UserContentPreferences> userContentPreferencesFixturesData = [
99
followedSources: [],
1010
followedTopics: [],
1111
savedHeadlines: [],
12+
savedFilters: [],
1213
),
1314
];

lib/src/models/config/user_preference_config.dart

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:core/src/models/config/remote_config.dart';
22
import 'package:core/src/models/user_preferences/user_content_preferences.dart';
3+
import 'package:core/src/models/user_presets/saved_filter.dart';
34
import 'package:equatable/equatable.dart';
45
import 'package:json_annotation/json_annotation.dart';
56
import 'package:meta/meta.dart';
@@ -22,17 +23,8 @@ part 'user_preference_config.g.dart';
2223
/// Countries, up to 5 Sources, and up to 5 Categories).
2324
/// - Saved Headlines: The limit applies to the total number of headlines
2425
/// a user can save.
25-
///
26-
/// **Tiered Limits defaults:**
27-
/// - **Guest User:**
28-
/// - Followed Items (Countries, Sources, Categories): 5 each
29-
/// - Saved Headlines: 10
30-
/// - **Authenticated User:**
31-
/// - Followed Items (Countries, Sources, Categories): 15 each
32-
/// - Saved Headlines: 30
33-
/// - **Premium User:**
34-
/// - Followed Items (Countries, Sources, Categories): 30 each
35-
/// - Saved Headlines: 100
26+
/// - Saved Filters: The limit applies to the total number of [SavedFilter]
27+
/// a user can save.
3628
///
3729
/// These limits are configurable to balance performance (allowing fetching
3830
/// full objects within these limits) and feature differentiation across tiers.
@@ -49,6 +41,9 @@ class UserPreferenceConfig extends Equatable {
4941
required this.authenticatedSavedHeadlinesLimit,
5042
required this.premiumFollowedItemsLimit,
5143
required this.premiumSavedHeadlinesLimit,
44+
required this.guestSavedFiltersLimit,
45+
required this.authenticatedSavedFiltersLimit,
46+
required this.premiumSavedFiltersLimit,
5247
});
5348

5449
/// Factory method to create a [UserPreferenceConfig] instance from a JSON map.
@@ -76,6 +71,15 @@ class UserPreferenceConfig extends Equatable {
7671
/// Maximum number of headlines a Premium user can save.
7772
final int premiumSavedHeadlinesLimit;
7873

74+
/// Maximum number of filters a Guest user can save.
75+
final int guestSavedFiltersLimit;
76+
77+
/// Maximum number of filters an Authenticated user can save.
78+
final int authenticatedSavedFiltersLimit;
79+
80+
/// Maximum number of filters a Premium user can save.
81+
final int premiumSavedFiltersLimit;
82+
7983
/// Converts this [UserPreferenceConfig] instance to a JSON map.
8084
Map<String, dynamic> toJson() => _$UserPreferenceConfigToJson(this);
8185

@@ -88,6 +92,9 @@ class UserPreferenceConfig extends Equatable {
8892
int? authenticatedSavedHeadlinesLimit,
8993
int? premiumFollowedItemsLimit,
9094
int? premiumSavedHeadlinesLimit,
95+
int? guestSavedFiltersLimit,
96+
int? authenticatedSavedFiltersLimit,
97+
int? premiumSavedFiltersLimit,
9198
}) {
9299
return UserPreferenceConfig(
93100
guestFollowedItemsLimit:
@@ -104,6 +111,12 @@ class UserPreferenceConfig extends Equatable {
104111
premiumFollowedItemsLimit ?? this.premiumFollowedItemsLimit,
105112
premiumSavedHeadlinesLimit:
106113
premiumSavedHeadlinesLimit ?? this.premiumSavedHeadlinesLimit,
114+
guestSavedFiltersLimit:
115+
guestSavedFiltersLimit ?? this.guestSavedFiltersLimit,
116+
authenticatedSavedFiltersLimit:
117+
authenticatedSavedFiltersLimit ?? this.authenticatedSavedFiltersLimit,
118+
premiumSavedFiltersLimit:
119+
premiumSavedFiltersLimit ?? this.premiumSavedFiltersLimit,
107120
);
108121
}
109122

@@ -115,6 +128,9 @@ class UserPreferenceConfig extends Equatable {
115128
authenticatedSavedHeadlinesLimit,
116129
premiumFollowedItemsLimit,
117130
premiumSavedHeadlinesLimit,
131+
guestSavedFiltersLimit,
132+
authenticatedSavedFiltersLimit,
133+
premiumSavedFiltersLimit,
118134
];
119135

120136
@override

lib/src/models/config/user_preference_config.g.dart

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)