Skip to content

Commit 87ee2bf

Browse files
open_wearable/lib/widgets/fota/fota_warning_page.dart: update some stylings
1 parent eb00a49 commit 87ee2bf

File tree

1 file changed

+149
-116
lines changed

1 file changed

+149
-116
lines changed

open_wearable/lib/widgets/fota/fota_warning_page.dart

Lines changed: 149 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ class FotaWarningPage extends StatelessWidget {
88
const FotaWarningPage({super.key});
99

1010
Future<void> _openGitHubLink() async {
11-
final uri = Uri.parse('https://github.com/OpenEarable/open-earable-2?tab=readme-ov-file#setup');
11+
final uri = Uri.parse(
12+
'https://github.com/OpenEarable/open-earable-2?tab=readme-ov-file#setup',
13+
);
1214
if (await canLaunchUrl(uri)) {
1315
await launchUrl(uri, mode: LaunchMode.platformDefault);
1416
} else {
@@ -20,6 +22,7 @@ class FotaWarningPage extends StatelessWidget {
2022
Widget build(BuildContext context) {
2123
final theme = Theme.of(context);
2224
final textTheme = theme.textTheme;
25+
final baseTextStyle = textTheme.bodyLarge; // one place to define size
2326

2427
return PlatformScaffold(
2528
appBar: PlatformAppBar(
@@ -31,130 +34,156 @@ class FotaWarningPage extends StatelessWidget {
3134
child: Center(
3235
child: ConstrainedBox(
3336
constraints: const BoxConstraints(maxWidth: 600),
34-
child: Column(
35-
crossAxisAlignment: CrossAxisAlignment.start,
36-
children: [
37-
// Header with warning icon
38-
Row(
39-
crossAxisAlignment: CrossAxisAlignment.center,
40-
children: [
41-
Icon(
42-
Icons.warning_amber_rounded,
43-
color: theme.colorScheme.error,
44-
size: 32,
45-
),
46-
const SizedBox(width: 12),
47-
Text(
48-
'Warning',
49-
style: textTheme.headlineSmall?.copyWith(
50-
fontWeight: FontWeight.bold,
51-
),
52-
),
53-
],
54-
),
55-
const SizedBox(height: 16),
56-
57-
// First paragraph with hyperlink
58-
Text.rich(
59-
TextSpan(
60-
style: textTheme.bodyMedium?.copyWith(fontSize: 16),
37+
child: DefaultTextStyle.merge( // <<– base style for everything
38+
style: baseTextStyle ?? const TextStyle(fontSize: 16),
39+
child: Column(
40+
crossAxisAlignment: CrossAxisAlignment.start,
41+
children: [
42+
// Header with warning icon
43+
Row(
44+
crossAxisAlignment: CrossAxisAlignment.center,
6145
children: [
62-
const TextSpan(
63-
text:
64-
'Sometimes, updating OpenEarable over Bluetooth might not complete successfully. '
65-
'If that happens, you can easily perform a manual update with the help of a J-Link debugger (see ',
46+
Icon(
47+
Icons.warning_amber_rounded,
48+
color: theme.colorScheme.error,
49+
size: 32,
6650
),
67-
TextSpan(
68-
text: 'GitHub instructions',
69-
style: const TextStyle(
70-
color: Colors.blue,
71-
decoration: TextDecoration.underline,
72-
),
73-
recognizer: TapGestureRecognizer()
74-
..onTap = _openGitHubLink,
51+
const SizedBox(width: 12),
52+
Text(
53+
'Warning',
54+
style: (baseTextStyle ?? const TextStyle())
55+
.copyWith(
56+
fontWeight: FontWeight.bold,
57+
fontSize: (baseTextStyle?.fontSize ?? 16) + 2,
58+
),
7559
),
76-
const TextSpan(text: ').'),
7760
],
7861
),
79-
),
80-
const SizedBox(height: 16),
81-
82-
Text(
83-
'To help ensure a smooth update, please:',
84-
style: textTheme.bodyMedium?.copyWith(
85-
fontSize: 16,
86-
fontWeight: FontWeight.w600,
87-
),
88-
),
89-
const SizedBox(height: 12),
62+
const SizedBox(height: 16),
9063

91-
// Steps in a Card
92-
Card(
93-
elevation: 2,
94-
margin: EdgeInsets.zero,
95-
child: Padding(
96-
padding: const EdgeInsets.symmetric(
97-
horizontal: 16,
98-
vertical: 12,
99-
),
100-
child: Column(
101-
crossAxisAlignment: CrossAxisAlignment.start,
102-
children: const [
103-
_NumberedStep(
104-
number: '1.',
105-
text:
106-
'Power cycle your OpenEarable once before you update.',
107-
),
108-
SizedBox(height: 8),
109-
_NumberedStep(
110-
number: '2.',
111-
text:
112-
'Keep the app open in the foreground and make sure your phone doesn’t enter power-saving mode.',
113-
),
114-
SizedBox(height: 8),
115-
_NumberedStep(
116-
number: '3.',
117-
text:
118-
'Charge your OpenEarable fully before starting.',
119-
),
120-
SizedBox(height: 8),
121-
_NumberedStep(
122-
number: '4.',
64+
// First paragraph with hyperlink
65+
Text.rich(
66+
TextSpan(
67+
style: baseTextStyle,
68+
children: [
69+
const TextSpan(
12370
text:
124-
'If you have two devices, power off the one that’s not being updated.',
71+
'Updating OpenEarable via Bluetooth is currently an experimental feature. '
72+
'Hence, updating OpenEarable over Bluetooth might sometimes not complete successfully. '
73+
'If that happens, you can easily perform a manual update with the help of a J-Link debugger (see ',
12574
),
126-
SizedBox(height: 8),
127-
_NumberedStep(
128-
number: '5.',
129-
text:
130-
'After the firmware is uploaded, OpenEarable will automatically verify it. '
131-
'During this step, the device might seem unresponsive for up to 3 minutes. '
132-
'Don’t worry, this is normal. It will start blinking again once the process is complete. '
133-
'Don‘t reset the device via the button while the firmware is verified by OpenEarable.',
75+
TextSpan(
76+
text: 'GitHub instructions',
77+
style: const TextStyle(
78+
color: Colors.blue,
79+
decoration: TextDecoration.underline,
80+
fontWeight: FontWeight.w600,
81+
),
82+
recognizer: TapGestureRecognizer()
83+
..onTap = _openGitHubLink,
13484
),
85+
const TextSpan(text: ').'),
13586
],
13687
),
13788
),
138-
),
89+
const SizedBox(height: 16),
13990

140-
const SizedBox(height: 24),
91+
Text(
92+
'To help ensure a smooth update, please:',
93+
style: baseTextStyle?.copyWith(
94+
fontWeight: FontWeight.w600,
95+
),
96+
),
97+
const SizedBox(height: 12),
14198

142-
// Proceed button
143-
SizedBox(
144-
width: double.infinity,
145-
child: PlatformElevatedButton(
146-
onPressed: () {
147-
Navigator.of(context).push(
148-
platformPageRoute(
149-
context: context,
150-
builder: (_) => const FirmwareUpdateWidget(),
151-
),
152-
);
153-
},
154-
child: const Text('Accept Risks and Proceed'),
99+
// Steps in a Card
100+
Card(
101+
elevation: 2,
102+
margin: EdgeInsets.zero,
103+
child: Padding(
104+
padding: const EdgeInsets.symmetric(
105+
horizontal: 16,
106+
vertical: 12,
107+
),
108+
child: Column(
109+
crossAxisAlignment: CrossAxisAlignment.start,
110+
children: const [
111+
_NumberedStep(
112+
number: '1.',
113+
text: TextSpan(
114+
text:
115+
'Power cycle your OpenEarable once before you update.',
116+
),
117+
),
118+
SizedBox(height: 8),
119+
_NumberedStep(
120+
number: '2.',
121+
text: TextSpan(
122+
text:
123+
'Keep the app open in the foreground and make sure your phone doesn’t enter power-saving mode.',
124+
),
125+
),
126+
SizedBox(height: 8),
127+
_NumberedStep(
128+
number: '3.',
129+
text: TextSpan(
130+
text:
131+
'Charge your OpenEarable fully before starting.',
132+
),
133+
),
134+
SizedBox(height: 8),
135+
_NumberedStep(
136+
number: '4.',
137+
text: TextSpan(
138+
text:
139+
'If you have two devices, power off the one that’s not being updated.',
140+
),
141+
),
142+
SizedBox(height: 8),
143+
_NumberedStep(
144+
number: '5.',
145+
text: TextSpan(
146+
children: [
147+
TextSpan(
148+
text:
149+
'After the firmware is uploaded, OpenEarable will automatically verify it. '
150+
'During this step, the device might seem unresponsive for up to 3 minutes. '
151+
'Don’t worry, this is normal. It will start blinking again once the process is complete.\n',
152+
),
153+
TextSpan(
154+
text:
155+
'Don‘t reset the device via the button while the firmware is verified by OpenEarable.',
156+
style: TextStyle(
157+
fontWeight: FontWeight.bold,
158+
),
159+
),
160+
],
161+
),
162+
),
163+
],
164+
),
165+
),
155166
),
156-
),
157-
],
167+
168+
const SizedBox(height: 24),
169+
170+
// Proceed button
171+
SizedBox(
172+
width: double.infinity,
173+
child: PlatformElevatedButton(
174+
onPressed: () {
175+
Navigator.of(context).push(
176+
platformPageRoute(
177+
context: context,
178+
builder: (_) => const FirmwareUpdateWidget(),
179+
),
180+
);
181+
},
182+
child: const Text('Acknowledge and Proceed'),
183+
),
184+
),
185+
],
186+
),
158187
),
159188
),
160189
),
@@ -167,7 +196,7 @@ class FotaWarningPage extends StatelessWidget {
167196
/// Helper widget for cleanly aligned numbered steps
168197
class _NumberedStep extends StatelessWidget {
169198
final String number;
170-
final String text;
199+
final InlineSpan text; // now accepts TextSpan / InlineSpan
171200

172201
const _NumberedStep({
173202
required this.number,
@@ -176,19 +205,23 @@ class _NumberedStep extends StatelessWidget {
176205

177206
@override
178207
Widget build(BuildContext context) {
179-
final textStyle = Theme.of(context).textTheme.bodyMedium?.copyWith(fontSize: 16);
208+
final baseStyle = Theme.of(context).textTheme.bodyLarge ??
209+
const TextStyle(fontSize: 16);
210+
180211
return Row(
181212
crossAxisAlignment: CrossAxisAlignment.start,
182213
children: [
183214
Text(
184215
number,
185-
style: textStyle?.copyWith(fontWeight: FontWeight.bold),
216+
style: baseStyle.copyWith(fontWeight: FontWeight.bold),
186217
),
187218
const SizedBox(width: 8),
188219
Expanded(
189-
child: Text(
190-
text,
191-
style: textStyle,
220+
child: RichText(
221+
text: TextSpan(
222+
style: baseStyle,
223+
children: [text],
224+
),
192225
),
193226
),
194227
],

0 commit comments

Comments
 (0)