Skip to content

Commit 1d2f007

Browse files
committed
feat(app_configuration): enhance app review settings
- Rename positiveInteractionThreshold to interactionCycleThreshold - Add localization support for interaction cycle threshold label and description - Implement switchable list for eligible positive interactions - Update UI to display new interaction types and their descriptions
1 parent 0e750c5 commit 1d2f007

File tree

1 file changed

+83
-12
lines changed

1 file changed

+83
-12
lines changed

lib/app_configuration/widgets/app_review_settings_form.dart

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:core/core.dart';
22
import 'package:flutter/material.dart';
33
import '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';
45
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart';
56
import 'package:ui_kit/ui_kit.dart';
67

@@ -26,7 +27,7 @@ class AppReviewSettingsForm extends StatefulWidget {
2627
}
2728

2829
class _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

Comments
 (0)