Skip to content

Commit 605a9f9

Browse files
committed
feat: add font settings page
- Implemented font size setting - Implemented font family setting - Implemented font weight setting - Refreshes app settings on change
1 parent ee1756e commit 605a9f9

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:ht_main/app/bloc/app_bloc.dart'; // Import AppBloc and events
4+
import 'package:ht_main/l10n/l10n.dart';
5+
import 'package:ht_main/settings/bloc/settings_bloc.dart';
6+
import 'package:ht_main/shared/constants/app_spacing.dart';
7+
import 'package:ht_shared/ht_shared.dart'
8+
show AppTextScaleFactor, AppFontWeight;
9+
10+
/// {@template font_settings_page}
11+
/// A page for configuring font-related settings like size, family, and weight.
12+
/// {@endtemplate}
13+
class FontSettingsPage extends StatelessWidget {
14+
/// {@macro font_settings_page}
15+
const FontSettingsPage({super.key});
16+
17+
// Helper to map AppTextScaleFactor enum to user-friendly strings
18+
String _textScaleFactorToString(
19+
AppTextScaleFactor size,
20+
AppLocalizations l10n,
21+
) {
22+
switch (size) {
23+
case AppTextScaleFactor.small:
24+
return l10n.settingsAppearanceFontSizeSmall;
25+
case AppTextScaleFactor.large:
26+
return l10n.settingsAppearanceFontSizeLarge;
27+
case AppTextScaleFactor.medium:
28+
return l10n.settingsAppearanceFontSizeMedium;
29+
case AppTextScaleFactor.extraLarge:
30+
return l10n.settingsAppearanceFontSizeExtraLarge;
31+
}
32+
}
33+
34+
// Helper to map font family string to user-friendly strings
35+
String _fontFamilyToString(String fontFamily, AppLocalizations l10n) {
36+
return fontFamily == 'SystemDefault'
37+
? l10n.settingsAppearanceFontFamilySystemDefault
38+
: fontFamily;
39+
}
40+
41+
// Helper to map AppFontWeight enum to user-friendly strings
42+
String _fontWeightToString(AppFontWeight weight, AppLocalizations l10n) {
43+
// Using direct strings as placeholders until specific l10n keys are confirmed
44+
switch (weight) {
45+
case AppFontWeight.light:
46+
return 'Light'; // Placeholder
47+
case AppFontWeight.regular:
48+
return 'Regular'; // Placeholder
49+
case AppFontWeight.bold:
50+
return 'Bold'; // Placeholder
51+
}
52+
}
53+
54+
@override
55+
Widget build(BuildContext context) {
56+
final l10n = context.l10n;
57+
final settingsBloc = context.watch<SettingsBloc>();
58+
final state = settingsBloc.state;
59+
60+
if (state.status != SettingsStatus.success ||
61+
state.userAppSettings == null) {
62+
return Scaffold(
63+
appBar: AppBar(title: Text(l10n.settingsAppearanceTitle)), // Use existing key
64+
body: const Center(child: CircularProgressIndicator()),
65+
);
66+
}
67+
68+
return BlocListener<SettingsBloc, SettingsState>(
69+
listener: (context, settingsState) { // Renamed state to avoid conflict
70+
if (settingsState.status == SettingsStatus.success) {
71+
context.read<AppBloc>().add(const AppSettingsRefreshed());
72+
}
73+
},
74+
child: Scaffold(
75+
appBar: AppBar(title: Text(l10n.settingsAppearanceTitle)), // Use existing key
76+
body: ListView(
77+
padding: const EdgeInsets.all(AppSpacing.lg),
78+
children: [
79+
// --- Text Scale Factor ---
80+
_buildDropdownSetting<AppTextScaleFactor>(
81+
context: context,
82+
title: l10n.settingsAppearanceAppFontSizeLabel,
83+
currentValue:
84+
state.userAppSettings!.displaySettings.textScaleFactor,
85+
items: AppTextScaleFactor.values,
86+
itemToString: (size) => _textScaleFactorToString(size, l10n),
87+
onChanged: (value) {
88+
if (value != null) {
89+
settingsBloc.add(SettingsAppFontSizeChanged(value));
90+
}
91+
},
92+
),
93+
const SizedBox(height: AppSpacing.lg),
94+
95+
// --- Font Family ---
96+
_buildDropdownSetting<String>(
97+
context: context,
98+
title: l10n.settingsAppearanceAppFontTypeLabel,
99+
currentValue: state.userAppSettings!.displaySettings.fontFamily,
100+
items: const ['SystemDefault'], // Currently only SystemDefault
101+
itemToString: (fontFamily) => _fontFamilyToString(fontFamily, l10n),
102+
onChanged: (value) {
103+
if (value != null) {
104+
settingsBloc.add(SettingsAppFontTypeChanged(value));
105+
}
106+
},
107+
),
108+
const SizedBox(height: AppSpacing.lg),
109+
110+
// --- Font Weight ---
111+
_buildDropdownSetting<AppFontWeight>(
112+
context: context,
113+
title: l10n.settingsAppearanceFontWeightLabel,
114+
currentValue: state.userAppSettings!.displaySettings.fontWeight,
115+
items: AppFontWeight.values,
116+
itemToString: (weight) => _fontWeightToString(weight, l10n),
117+
onChanged: (value) {
118+
if (value != null) {
119+
settingsBloc.add(SettingsAppFontWeightChanged(value));
120+
}
121+
},
122+
),
123+
],
124+
),
125+
), // Correctly close BlocListener's child Scaffold
126+
);
127+
}
128+
129+
Widget _buildDropdownSetting<T>({
130+
required BuildContext context,
131+
required String title,
132+
required T currentValue,
133+
required List<T> items,
134+
required String Function(T) itemToString,
135+
required ValueChanged<T?> onChanged,
136+
}) {
137+
final textTheme = Theme.of(context).textTheme;
138+
return Column(
139+
crossAxisAlignment: CrossAxisAlignment.start,
140+
children: [
141+
Text(title, style: textTheme.titleMedium),
142+
const SizedBox(height: AppSpacing.sm),
143+
DropdownButtonFormField<T>(
144+
value: currentValue,
145+
items: items.map((T value) {
146+
return DropdownMenuItem<T>(
147+
value: value,
148+
child: Text(itemToString(value)),
149+
);
150+
}).toList(),
151+
onChanged: onChanged,
152+
decoration: const InputDecoration(
153+
border: OutlineInputBorder(),
154+
contentPadding: EdgeInsets.symmetric(
155+
horizontal: AppSpacing.md,
156+
vertical: AppSpacing.sm,
157+
),
158+
),
159+
),
160+
],
161+
);
162+
}
163+
}

0 commit comments

Comments
 (0)