Skip to content

Commit 2cdfe82

Browse files
committed
refactor(app_configuration): replace SegmentedButton with TabBar for user role selection
- Add TabController and TabBar to replace SegmentedButton for selecting user roles - Adjust layout and padding for better hierarchy visualization - Update ExpansionTile children to use CrossAxisAlignment.start for alignment - Modify interstitial role frequency fields to use TabBarView within a fixed-height container
1 parent efb1b86 commit 2cdfe82

File tree

1 file changed

+73
-54
lines changed

1 file changed

+73
-54
lines changed

lib/app_configuration/widgets/article_ad_settings_form.dart

Lines changed: 73 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ class ArticleAdSettingsForm extends StatefulWidget {
2727
State<ArticleAdSettingsForm> createState() => _ArticleAdSettingsFormState();
2828
}
2929

30-
class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
31-
AppUserRole _selectedUserRole = AppUserRole.guestUser;
30+
class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm>
31+
with SingleTickerProviderStateMixin {
32+
late TabController _tabController;
3233
late final Map<AppUserRole, TextEditingController>
33-
_articlesToReadBeforeShowingInterstitialAdsControllers;
34+
_articlesToReadBeforeShowingInterstitialAdsControllers;
3435

3536
@override
3637
void initState() {
3738
super.initState();
39+
_tabController = TabController(length: AppUserRole.values.length, vsync: this);
3840
_initializeControllers();
3941
}
4042

@@ -52,19 +54,17 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
5254
final interstitialConfig = articleAdConfig.interstitialAdConfiguration;
5355
_articlesToReadBeforeShowingInterstitialAdsControllers = {
5456
for (final role in AppUserRole.values)
55-
role:
56-
TextEditingController(
57-
text: _getArticlesBeforeInterstitial(
58-
interstitialConfig,
59-
role,
60-
).toString(),
61-
)
62-
..selection = TextSelection.collapsed(
63-
offset: _getArticlesBeforeInterstitial(
64-
interstitialConfig,
65-
role,
66-
).toString().length,
67-
),
57+
role: TextEditingController(
58+
text: _getArticlesBeforeInterstitial(
59+
interstitialConfig,
60+
role,
61+
).toString(),
62+
)..selection = TextSelection.collapsed(
63+
offset: _getArticlesBeforeInterstitial(
64+
interstitialConfig,
65+
role,
66+
).toString().length,
67+
),
6868
};
6969
}
7070

@@ -79,15 +79,15 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
7979
_articlesToReadBeforeShowingInterstitialAdsControllers[role]?.text =
8080
newInterstitialValue;
8181
_articlesToReadBeforeShowingInterstitialAdsControllers[role]
82-
?.selection = TextSelection.collapsed(
83-
offset: newInterstitialValue.length,
84-
);
82+
?.selection =
83+
TextSelection.collapsed(offset: newInterstitialValue.length);
8584
}
8685
}
8786
}
8887

8988
@override
9089
void dispose() {
90+
_tabController.dispose();
9191
for (final controller
9292
in _articlesToReadBeforeShowingInterstitialAdsControllers.values) {
9393
controller.dispose();
@@ -122,20 +122,29 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
122122
const SizedBox(height: AppSpacing.lg),
123123
ExpansionTile(
124124
title: Text(l10n.defaultInArticleAdTypeSelectionTitle),
125-
childrenPadding: const EdgeInsets.symmetric(
126-
horizontal: AppSpacing.xxl,
127-
vertical: AppSpacing.md,
125+
childrenPadding: const EdgeInsetsDirectional.only(
126+
start: AppSpacing.lg, // Adjusted padding for hierarchy
127+
top: AppSpacing.md,
128+
bottom: AppSpacing.md,
128129
),
130+
expandedCrossAxisAlignment: CrossAxisAlignment.start, // Align content to start
129131
children: [
130132
Text(
131133
l10n.defaultInArticleAdTypeSelectionDescription,
132134
style: Theme.of(context).textTheme.bodySmall?.copyWith(
133135
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
134136
),
137+
textAlign: TextAlign.start, // Ensure text aligns to start
135138
),
136139
const SizedBox(height: AppSpacing.lg),
137-
Center(
140+
Align(
141+
alignment: AlignmentDirectional.centerStart,
138142
child: SegmentedButton<AdType>(
143+
style: SegmentedButton.styleFrom(
144+
shape: const RoundedRectangleBorder(
145+
borderRadius: BorderRadius.zero,
146+
),
147+
),
139148
segments: AdType.values
140149
.where(
141150
(type) => type == AdType.native || type == AdType.banner,
@@ -166,10 +175,12 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
166175
const SizedBox(height: AppSpacing.lg),
167176
ExpansionTile(
168177
title: Text(l10n.interstitialAdSettingsTitle),
169-
childrenPadding: const EdgeInsets.symmetric(
170-
horizontal: AppSpacing.xxl,
171-
vertical: AppSpacing.md,
178+
childrenPadding: const EdgeInsetsDirectional.only(
179+
start: AppSpacing.lg, // Adjusted padding for hierarchy
180+
top: AppSpacing.md,
181+
bottom: AppSpacing.md,
172182
),
183+
expandedCrossAxisAlignment: CrossAxisAlignment.start, // Align content to start
173184
children: [
174185
SwitchListTile(
175186
title: Text(l10n.enableInterstitialAdsLabel),
@@ -190,10 +201,12 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
190201
),
191202
ExpansionTile(
192203
title: Text(l10n.userRoleInterstitialFrequencyTitle),
193-
childrenPadding: const EdgeInsets.symmetric(
194-
horizontal: AppSpacing.xxl,
195-
vertical: AppSpacing.md,
204+
childrenPadding: const EdgeInsetsDirectional.only(
205+
start: AppSpacing.xl, // Further adjusted padding for nested hierarchy
206+
top: AppSpacing.md,
207+
bottom: AppSpacing.md,
196208
),
209+
expandedCrossAxisAlignment: CrossAxisAlignment.start, // Align content to start
197210
children: [
198211
Text(
199212
l10n.userRoleInterstitialFrequencyDescription,
@@ -202,56 +215,62 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm> {
202215
context,
203216
).colorScheme.onSurface.withOpacity(0.7),
204217
),
218+
textAlign: TextAlign.start, // Ensure text aligns to start
205219
),
206220
const SizedBox(height: AppSpacing.lg),
221+
// Replaced SegmentedButton with TabBar for role selection
207222
Align(
208223
alignment: AlignmentDirectional.centerStart,
209-
child: SegmentedButton<AppUserRole>(
210-
style: SegmentedButton.styleFrom(
211-
shape: const RoundedRectangleBorder(
212-
borderRadius: BorderRadius.zero,
213-
),
224+
child: SizedBox(
225+
height: kTextTabBarHeight,
226+
child: TabBar(
227+
controller: _tabController,
228+
tabAlignment: TabAlignment.start,
229+
isScrollable: true,
230+
tabs: AppUserRole.values
231+
.map((role) => Tab(text: role.l10n(context)))
232+
.toList(),
214233
),
215-
segments: AppUserRole.values
234+
),
235+
),
236+
const SizedBox(height: AppSpacing.lg),
237+
// TabBarView to display role-specific fields
238+
SizedBox(
239+
height: 250, // Fixed height for TabBarView within a ListView
240+
child: TabBarView(
241+
controller: _tabController,
242+
children: AppUserRole.values
216243
.map(
217-
(role) => ButtonSegment<AppUserRole>(
218-
value: role,
219-
label: Text(role.l10n(context)),
244+
(role) => _buildInterstitialRoleSpecificFields(
245+
context,
246+
l10n,
247+
role,
248+
articleAdConfig.interstitialAdConfiguration,
220249
),
221250
)
222251
.toList(),
223-
selected: {_selectedUserRole},
224-
onSelectionChanged: (newSelection) {
225-
setState(() {
226-
_selectedUserRole = newSelection.first;
227-
});
228-
},
229252
),
230253
),
231-
const SizedBox(height: AppSpacing.lg),
232-
_buildInterstitialRoleSpecificFields(
233-
context,
234-
l10n,
235-
_selectedUserRole,
236-
articleAdConfig.interstitialAdConfiguration,
237-
),
238254
],
239255
),
240256
],
241257
),
242258
const SizedBox(height: AppSpacing.lg),
243259
ExpansionTile(
244260
title: Text(l10n.inArticleAdSlotPlacementsTitle),
245-
childrenPadding: const EdgeInsets.symmetric(
246-
horizontal: AppSpacing.xxl,
247-
vertical: AppSpacing.md,
261+
childrenPadding: const EdgeInsetsDirectional.only(
262+
start: AppSpacing.lg, // Adjusted padding for hierarchy
263+
top: AppSpacing.md,
264+
bottom: AppSpacing.md,
248265
),
266+
expandedCrossAxisAlignment: CrossAxisAlignment.start, // Align content to start
249267
children: [
250268
Text(
251269
l10n.inArticleAdSlotPlacementsDescription,
252270
style: Theme.of(context).textTheme.bodySmall?.copyWith(
253271
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
254272
),
273+
textAlign: TextAlign.start, // Ensure text aligns to start
255274
),
256275
const SizedBox(height: AppSpacing.lg),
257276
...articleAdConfig.inArticleAdSlotConfigurations.map(

0 commit comments

Comments
 (0)