Skip to content

Commit 01e8eb8

Browse files
authored
Merge pull request #159 from flutter-news-app-full-source-code/158-feat-enforce-following-limit-constrains-on-the-account-content-preferences
158 feat enforce following limit constrains on the account content preferences
2 parents 6be2c3e + c157e11 commit 01e8eb8

File tree

3 files changed

+133
-33
lines changed

3 files changed

+133
-33
lines changed

lib/account/view/manage_followed_items/countries/add_country_to_follow_page.dart

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
55
import 'package:flutter_news_app_mobile_client_full_source_code/account/bloc/available_countries_bloc.dart';
66
import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart';
77
import 'package:flutter_news_app_mobile_client_full_source_code/l10n/l10n.dart';
8+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/services/content_limitation_service.dart';
9+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/widgets/content_limitation_bottom_sheet.dart';
810
import 'package:ui_kit/ui_kit.dart';
911

1012
/// {@template add_country_to_follow_page}
@@ -150,29 +152,61 @@ class AddCountryToFollowPage extends StatelessWidget {
150152
? l10n.unfollowCountryTooltip(country.name)
151153
: l10n.followCountryTooltip(country.name),
152154
onPressed: () {
155+
// Ensure user preferences are available before
156+
// proceeding.
153157
if (userContentPreferences == null) return;
154158

159+
// Create a mutable copy of the followed countries list.
155160
final updatedFollowedCountries = List<Country>.from(
156161
followedCountries,
157162
);
163+
164+
// If the user is unfollowing, always allow it.
158165
if (isFollowed) {
159166
updatedFollowedCountries.removeWhere(
160167
(c) => c.id == country.id,
161168
);
169+
final updatedPreferences = userContentPreferences
170+
.copyWith(
171+
followedCountries: updatedFollowedCountries,
172+
);
173+
174+
context.read<AppBloc>().add(
175+
AppUserContentPreferencesChanged(
176+
preferences: updatedPreferences,
177+
),
178+
);
162179
} else {
163-
updatedFollowedCountries.add(country);
164-
}
180+
// If the user is following, check the limit first.
181+
final limitationService = context
182+
.read<ContentLimitationService>();
183+
final status = limitationService.checkAction(
184+
ContentAction.followCountry,
185+
);
165186

166-
final updatedPreferences = userContentPreferences
167-
.copyWith(
168-
followedCountries: updatedFollowedCountries,
169-
);
187+
if (status == LimitationStatus.allowed) {
188+
updatedFollowedCountries.add(country);
189+
final updatedPreferences =
190+
userContentPreferences.copyWith(
191+
followedCountries:
192+
updatedFollowedCountries,
193+
);
170194

171-
context.read<AppBloc>().add(
172-
AppUserContentPreferencesChanged(
173-
preferences: updatedPreferences,
174-
),
175-
);
195+
context.read<AppBloc>().add(
196+
AppUserContentPreferencesChanged(
197+
preferences: updatedPreferences,
198+
),
199+
);
200+
} else {
201+
// If the limit is reached, show the bottom sheet.
202+
showModalBottomSheet<void>(
203+
context: context,
204+
builder: (_) => ContentLimitationBottomSheet(
205+
status: status,
206+
),
207+
);
208+
}
209+
}
176210
},
177211
),
178212
contentPadding: const EdgeInsets.symmetric(

lib/account/view/manage_followed_items/sources/add_source_to_follow_page.dart

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
55
import 'package:flutter_news_app_mobile_client_full_source_code/account/bloc/available_sources_bloc.dart';
66
import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart';
77
import 'package:flutter_news_app_mobile_client_full_source_code/l10n/l10n.dart';
8+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/services/content_limitation_service.dart';
9+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/widgets/content_limitation_bottom_sheet.dart';
810
import 'package:ui_kit/ui_kit.dart';
911

1012
/// {@template add_source_to_follow_page}
@@ -80,29 +82,60 @@ class AddSourceToFollowPage extends StatelessWidget {
8082
? l10n.unfollowSourceTooltip(source.name)
8183
: l10n.followSourceTooltip(source.name),
8284
onPressed: () {
85+
// Ensure user preferences are available before
86+
// proceeding.
8387
if (userContentPreferences == null) return;
8488

89+
// Create a mutable copy of the followed sources list.
8590
final updatedFollowedSources = List<Source>.from(
8691
followedSources,
8792
);
93+
94+
// If the user is unfollowing, always allow it.
8895
if (isFollowed) {
8996
updatedFollowedSources.removeWhere(
9097
(s) => s.id == source.id,
9198
);
99+
final updatedPreferences = userContentPreferences
100+
.copyWith(
101+
followedSources: updatedFollowedSources,
102+
);
103+
104+
context.read<AppBloc>().add(
105+
AppUserContentPreferencesChanged(
106+
preferences: updatedPreferences,
107+
),
108+
);
92109
} else {
93-
updatedFollowedSources.add(source);
94-
}
110+
// If the user is following, check the limit first.
111+
final limitationService = context
112+
.read<ContentLimitationService>();
113+
final status = limitationService.checkAction(
114+
ContentAction.followSource,
115+
);
95116

96-
final updatedPreferences = userContentPreferences
97-
.copyWith(
98-
followedSources: updatedFollowedSources,
99-
);
117+
if (status == LimitationStatus.allowed) {
118+
updatedFollowedSources.add(source);
119+
final updatedPreferences =
120+
userContentPreferences.copyWith(
121+
followedSources: updatedFollowedSources,
122+
);
100123

101-
context.read<AppBloc>().add(
102-
AppUserContentPreferencesChanged(
103-
preferences: updatedPreferences,
104-
),
105-
);
124+
context.read<AppBloc>().add(
125+
AppUserContentPreferencesChanged(
126+
preferences: updatedPreferences,
127+
),
128+
);
129+
} else {
130+
// If the limit is reached, show the bottom sheet.
131+
showModalBottomSheet<void>(
132+
context: context,
133+
builder: (_) => ContentLimitationBottomSheet(
134+
status: status,
135+
),
136+
);
137+
}
138+
}
106139
},
107140
),
108141
),

lib/account/view/manage_followed_items/topics/add_topic_to_follow_page.dart

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
55
import 'package:flutter_news_app_mobile_client_full_source_code/account/bloc/available_topics_bloc.dart';
66
import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart';
77
import 'package:flutter_news_app_mobile_client_full_source_code/l10n/l10n.dart';
8+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/services/content_limitation_service.dart';
9+
import 'package:flutter_news_app_mobile_client_full_source_code/shared/widgets/content_limitation_bottom_sheet.dart';
810
import 'package:ui_kit/ui_kit.dart';
911

1012
/// {@template add_topic_to_follow_page}
@@ -149,29 +151,60 @@ class AddTopicToFollowPage extends StatelessWidget {
149151
? l10n.unfollowTopicTooltip(topic.name)
150152
: l10n.followTopicTooltip(topic.name),
151153
onPressed: () {
154+
// Ensure user preferences are available before
155+
// proceeding.
152156
if (userContentPreferences == null) return;
153157

158+
// Create a mutable copy of the followed topics list.
154159
final updatedFollowedTopics = List<Topic>.from(
155160
followedTopics,
156161
);
162+
163+
// If the user is unfollowing, always allow it.
157164
if (isFollowed) {
158165
updatedFollowedTopics.removeWhere(
159166
(t) => t.id == topic.id,
160167
);
168+
final updatedPreferences = userContentPreferences
169+
.copyWith(
170+
followedTopics: updatedFollowedTopics,
171+
);
172+
173+
context.read<AppBloc>().add(
174+
AppUserContentPreferencesChanged(
175+
preferences: updatedPreferences,
176+
),
177+
);
161178
} else {
162-
updatedFollowedTopics.add(topic);
163-
}
179+
// If the user is following, check the limit first.
180+
final limitationService = context
181+
.read<ContentLimitationService>();
182+
final status = limitationService.checkAction(
183+
ContentAction.followTopic,
184+
);
164185

165-
final updatedPreferences = userContentPreferences
166-
.copyWith(
167-
followedTopics: updatedFollowedTopics,
168-
);
186+
if (status == LimitationStatus.allowed) {
187+
updatedFollowedTopics.add(topic);
188+
final updatedPreferences =
189+
userContentPreferences.copyWith(
190+
followedTopics: updatedFollowedTopics,
191+
);
169192

170-
context.read<AppBloc>().add(
171-
AppUserContentPreferencesChanged(
172-
preferences: updatedPreferences,
173-
),
174-
);
193+
context.read<AppBloc>().add(
194+
AppUserContentPreferencesChanged(
195+
preferences: updatedPreferences,
196+
),
197+
);
198+
} else {
199+
// If the limit is reached, show the bottom sheet.
200+
showModalBottomSheet<void>(
201+
context: context,
202+
builder: (_) => ContentLimitationBottomSheet(
203+
status: status,
204+
),
205+
);
206+
}
207+
}
175208
},
176209
),
177210
contentPadding: const EdgeInsets.symmetric(

0 commit comments

Comments
 (0)