11import 'package:core/core.dart' ;
22import 'package:flutter/material.dart' ;
33import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/app_config_form_fields.dart' ;
4+ import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart' ;
45import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart' ;
56import 'package:ui_kit/ui_kit.dart' ;
67
@@ -26,7 +27,7 @@ class AppReviewSettingsForm extends StatefulWidget {
2627}
2728
2829class _AppReviewSettingsFormState extends State <AppReviewSettingsForm > {
29- late final TextEditingController _positiveInteractionThresholdController ;
30+ late final TextEditingController _interactionCycleThresholdController ;
3031 late final TextEditingController _initialPromptCooldownController;
3132
3233 @override
@@ -46,8 +47,8 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
4647
4748 void _initializeControllers () {
4849 final appReviewConfig = widget.remoteConfig.features.community.appReview;
49- _positiveInteractionThresholdController = TextEditingController (
50- text: appReviewConfig.positiveInteractionThreshold .toString (),
50+ _interactionCycleThresholdController = TextEditingController (
51+ text: appReviewConfig.interactionCycleThreshold .toString (),
5152 );
5253 _initialPromptCooldownController = TextEditingController (
5354 text: appReviewConfig.initialPromptCooldownDays.toString (),
@@ -56,17 +57,16 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
5657
5758 void _updateControllers () {
5859 final appReviewConfig = widget.remoteConfig.features.community.appReview;
59- _positiveInteractionThresholdController.text = appReviewConfig
60- .positiveInteractionThreshold
61- .toString ();
60+ _interactionCycleThresholdController.text =
61+ appReviewConfig.interactionCycleThreshold.toString ();
6262 _initialPromptCooldownController.text = appReviewConfig
6363 .initialPromptCooldownDays
6464 .toString ();
6565 }
6666
6767 @override
6868 void dispose () {
69- _positiveInteractionThresholdController .dispose ();
69+ _interactionCycleThresholdController .dispose ();
7070 _initialPromptCooldownController.dispose ();
7171 super .dispose ();
7272 }
@@ -121,14 +121,14 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
121121 expandedCrossAxisAlignment: CrossAxisAlignment .start,
122122 children: [
123123 AppConfigIntField (
124- label: l10n.positiveInteractionThresholdLabel ,
124+ label: l10n.interactionCycleThresholdLabel ,
125125 description:
126- l10n.positiveInteractionThresholdDescription ,
127- value: appReviewConfig.positiveInteractionThreshold ,
126+ l10n.interactionCycleThresholdDescription ,
127+ value: appReviewConfig.interactionCycleThreshold ,
128128 onChanged: (value) {
129129 final newConfig = communityConfig.copyWith (
130130 appReview: appReviewConfig.copyWith (
131- positiveInteractionThreshold : value,
131+ interactionCycleThreshold : value,
132132 ),
133133 );
134134 widget.onConfigChanged (
@@ -140,7 +140,7 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
140140 ),
141141 );
142142 },
143- controller: _positiveInteractionThresholdController ,
143+ controller: _interactionCycleThresholdController ,
144144 ),
145145 AppConfigIntField (
146146 label: l10n.initialPromptCooldownLabel,
@@ -168,6 +168,61 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
168168 },
169169 ),
170170 ),
171+ Padding (
172+ padding: const EdgeInsetsDirectional .only (
173+ start: AppSpacing .lg,
174+ ),
175+ child: LayoutBuilder (
176+ builder: (context, constraints) {
177+ final isMobile = constraints.maxWidth < 600 ;
178+ return ExpansionTile (
179+ title: Text (l10n.eligiblePositiveInteractionsTitle),
180+ initiallyExpanded: ! isMobile,
181+ childrenPadding: const EdgeInsetsDirectional .only (
182+ start: AppSpacing .lg,
183+ top: AppSpacing .md,
184+ bottom: AppSpacing .md,
185+ ),
186+ expandedCrossAxisAlignment: CrossAxisAlignment .start,
187+ children: [
188+ ...PositiveInteractionType .values.map (
189+ (interactionType) => SwitchListTile (
190+ title: Text (interactionType.l10n (context)),
191+ value: appReviewConfig
192+ .eligiblePositiveInteractions
193+ .contains (interactionType),
194+ onChanged: (value) {
195+ final currentInteractions = List <
196+ PositiveInteractionType >.from (
197+ appReviewConfig.eligiblePositiveInteractions,
198+ );
199+ if (value) {
200+ currentInteractions.add (interactionType);
201+ } else {
202+ currentInteractions.remove (interactionType);
203+ }
204+ final newAppReviewConfig =
205+ appReviewConfig.copyWith (
206+ eligiblePositiveInteractions:
207+ currentInteractions,
208+ );
209+ widget.onConfigChanged (
210+ widget.remoteConfig.copyWith (
211+ features: widget.remoteConfig.features
212+ .copyWith (
213+ community: communityConfig.copyWith (
214+ appReview: newAppReviewConfig),
215+ ),
216+ ),
217+ );
218+ },
219+ ),
220+ ),
221+ ],
222+ );
223+ },
224+ ),
225+ ),
171226 Padding (
172227 padding: const EdgeInsetsDirectional .only (
173228 start: AppSpacing .lg,
@@ -244,3 +299,19 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
244299 );
245300 }
246301}
302+
303+ extension on PositiveInteractionType {
304+ String l10n (BuildContext context) {
305+ final l10n = AppLocalizationsX (context).l10n;
306+ switch (this ) {
307+ case PositiveInteractionType .saveItem:
308+ return l10n.positiveInteractionTypeSaveItem;
309+ case PositiveInteractionType .followItem:
310+ return l10n.positiveInteractionTypeFollowItem;
311+ case PositiveInteractionType .shareContent:
312+ return l10n.positiveInteractionTypeShareContent;
313+ case PositiveInteractionType .saveFilter:
314+ return l10n.positiveInteractionTypeSaveFilter;
315+ }
316+ }
317+ }
0 commit comments